Background Image

Written by Fuxing Loh - Dec 2020

Web development is hard, the complexity of dealing with image is especially challenging. Background image how do you do them properly?

As the guiding question, you should ask yourself:

Is the image the content or just for aesthetic purpose?

Below are just a few examples of how to "do image" properly.

Image is the content

Nothing really special here, the image is the content hence we use the <img> tag. The image height will adjust accordingly to the given width. As image is the content, the entirety of the image will be shown.

import=image-is-the-content.vue
<template>
  <img src="/joe-green-jewel.jpg">
</template>

Image as background

The image is just the background and something as is the content. In this case, the text is the content. As text is the content, it will resize based on the height of the content. You can try resizing the browser, and the height of the content will change and therefore the image.

Text is the content

Due to the nature of images, this is very hard to see clearly.
import=image-as-background.vue
<template>
  <div class="content">
    <h2>Text is the content</h2>
    <small>Due to the nature of images, this is very hard to see clearly.</small>
  </div>
</template>

<style scoped lang="less">
.content {
  background: url('/joe-green-jewel.jpg') no-repeat center;
  background-size: cover;
  padding: 24px;

  * {
    color: white;
  }
}
</style>

Image as background with layer

As you have observed by now, image as background makes it in incredibly difficult to see the text. To make it easier to see, you can add a layer between the text, and the image. Depending on the image, either black on white or white on black.

Translucent black layer.

Black background layer with white text.

Translucent white layer and blur.

White background layer with black text.

import=image-as-background-layer.vue
<template>
  <div class="content">
    <div class="black-on-white">
      <h3>Translucent black layer.</h3>
      <p>Black background layer with white text.</p>
    </div>
    <div class="white-on-black">
      <h3>Translucent white layer and blur.</h3>
      <p>White background layer with black text.</p>
    </div>
  </div>
</template>

<style scoped lang="less">
.content {
  background: url('/joe-green-jewel.jpg') no-repeat center;
  background-size: cover;
}

.black-on-white {
  background: #00000050;
  padding: 24px;

  * {
    color: white
  }
}

.white-on-black {
  background: #ffffff66;
  padding: 24px;

  * {
    color: black
  }
}
</style>

Aspect ratio on images

You want the image to have a certain aspect ratio? For example, when width is 100px height is 50px, a 2:1 aspect ratio. You can do this.

import=aspect-ratio.vue
<template>
  <div>
    <div class="image"></div>
  </div>
</template>

<style scoped>
.image {
  background: url('/joe-green-jewel.jpg') no-repeat center;
  background-size: cover;
  padding-bottom: 50%;
}
</style>

Fixed height image

You want the image to have a fixed height regardless of the width of the image? (E.g. Your landing page banner design?) This is pretty basic, you can just set the height accordingly. Additionally, you can set the height to be a certain percentage of the viewport. In this example, it is 25% of the browser height.

Image with fixed height

Height fixed the 25% of browser viewport.

import=fixed-height.vue
<template>
  <div>
    <div class="image">
      <section>
        <div>
          <h2>Image with fixed height</h2>
          <p>Height fixed the 25% of browser viewport.</p>
        </div>
      </section>
    </div>
  </div>
</template>

<style scoped lang="less">
.image {
  background: url('/joe-green-jewel.jpg') no-repeat center;
  background-size: cover;
  height: 25vw;
}

section {
  padding: 24px 48px;
  text-align: center;
  background: #00000033;
  height: 100%;

  display: flex;
  align-items: center;
  justify-content: center;

  * {
    color: white;
  }
}
</style>

Full height image

Image control the height of the image regardless of the content in the image. In other words, image must be full height, text is just accompanying the image and must not influence height of image. You can resize your browser and see the text get clipped.

Image + Text

Image must be full height, text is just accompanying the image and must not influence height of image.

Image + Text

Image must be full height, text is just accompanying the image and must not influence height of image.

import=image-text-content.vue
<template>
  <div class="root">
    <div v-for="title in ['Image + Text', 'Image + Text']" :key="title">
      <img src="/joe-green-jewel.jpg">
      <section>
        <div>
          <h2>{{ title }}</h2>
          <p>Image must be full height, text is just accompanying the image and must not influence height of image.</p>
        </div>
      </section>
    </div>
  </div>
</template>

<style scoped lang="less">
.root {
  display: flex;
  align-items: center;
  justify-content: center;
}

.root > div {
  position: relative;
}

section {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;

  padding: 32px;
  text-align: center;
  background: #00000066;
  height: 100%;

  * {
    color: white;
  }

  display: flex;
  align-items: center;
  justify-content: center;
}
</style>

Bonus: Image on a horizontal scroll

Vue Horizontal is an ultra simple pure vue horizontal layout for modern responsive web with zero dependencies.

0

Image in Horizontal Scroll

1

Image in Horizontal Scroll

2

Image in Horizontal Scroll

3

Image in Horizontal Scroll

4

Image in Horizontal Scroll

5

Image in Horizontal Scroll

6

Image in Horizontal Scroll

7

Image in Horizontal Scroll

8

Image in Horizontal Scroll

9

Image in Horizontal Scroll
import=horizontal.vue
<template>
  <section>
    <vue-horizontal>
      <div class="item" v-for="i in [0,1,2,3,4,5,6,7,8,9]" :key="i">
        <img src="/joe-green-jewel.jpg">
        <div class="overlay">
          <div>
            <h2>{{ i }}</h2>
            <h5>Image in Horizontal Scroll</h5>
          </div>
        </div>
      </div>
    </vue-horizontal>
  </section>
</template>

<script>
import VueHorizontal from 'vue-horizontal';

export default {
  name: "horizontal.vue",
  components: {VueHorizontal}
}
</script>

<style scoped lang="less">
section {
  margin: 32px;
}

.item {
  width: calc((100% - 36px) / 3);
  margin-right: 18px;
  position: relative;
  overflow: hidden;
  border-radius: 4px;
}

.overlay {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;

  padding: 32px;
  text-align: center;
  background: #00000066;
  height: 100%;

  * {
    color: white;
  }

  display: flex;
  align-items: center;
  justify-content: center;
}
</style>