Background to Foreground Image Solution for Responsive Web Development

Proper design plays a key role when it comes to the topic of responsive web design (RWD). But sometimes we don’t have the luxury of a flushed out design to begin with. We often have to manage and make practical use of the assets in hand, and in some cases, background images can become a problem for smaller screens.

I’m typically tasked with turning a fixed-pixel site into a fully responsive site, which often involves lots of thought and understanding of what should/can be accomplished. Add a CMS with big muscles to the equation and it gets complicated very quickly.

 

Problem with text over background images

There is a problem we face with background images that have text layered on top of them. They typically work fine for desktop/laptop screens, but can often become illegible on smaller mobile screens. Here’s an example on a desktop screen:

screenshot-desktop

It looks good…but then there’s the mobile screen:

screenshot-mobile

Ain’t nobody got time for that!

 

The overlay effect

So, what if we were to create some kind of overlay effect over the entire image which would make the text legible? Something like this (mobile screen):
screenshot-mobile-overlay

It’s looking much better. But…what if the brand you’re working on has bright, vivid imagery that is compromised with dark overlays in order to contrast the text?

 

Practical solution

I’ve recently found a decent solution for this issue. Using media queries, let’s just switch out the background image with a foreground image. Here’s the desktop screen with background image:

 

screenshot-desktop

 

And, voilà! Here’s a mobile screen with foreground image implemented — 100% responsive — and both text and the image now have great visual clarity:

 

screenshot-final

 

Nothing ground breaking here, but it serves its purpose well. Let me explain first, and then I will demonstrate.

You may know that BrainJocks is a team of Sitecore specialists. You also may be familiar with or even be using BrainJocks SCORE, our modular development framework. SCORE includes a library comprised of reusable components, most of which are based on Twitter Bootstrap’s framework (as a default starting point). I’ve used one of our content components here, called a SCORE Hero, but this implementation isn’t tied to any one component (in this case).

Whether you’re combining SCORE components to form the necessary markup for this procedure or simply writing plain HTML outside of our realm, this little technique may benefit your cause.

 

How to do it

Step 1: You need a wrapper with a background image (desktop-version.jpg) in place. In this example I am using a “score-hero” component with a class of “cover” that positions the background image size to cover in CSS. This will serve as our desktop implementation. (Note: we place background images in an inline style so that content administrators have the ability to switch out images within the DOM.)

Step 2: You need an img tag in the foreground (mobile-version.jpg). This will serve as our mobile version.

Step 3: Your text and link, of course…

Given the content component we’ve decided to use for this example, our admin selects a Hero component in the Experience Editor and populates the content with both background image (on the wrapper) and foreground image, as well as text and link.

So, what we need here are two images and one component. This is the HTML that is generated from SCORE:



<div class="score-hero cover" style="background-image: url('../img/desktop-version.jpg');">
  <div class="score-hero-image">
    <img src="../img/mobile-version.jpg" alt="#">
  </div>
  <h1>Hero Header</h1>
  <div class="score-hero-body">
    Hero body text. Lorem ipsum dolor sit amet. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </div>
  <div class="score-call-to-action">
    <a href="/" class="score-button">Button</a>
  </div>
</div>


 

So, visually, we now have something that looks like this for mobile:

 

screenshot-mobile-incomplete

 

And it looks this for desktop:

 

screenshot-desktop-incomplete

Time to style it.

Step 4: You need to replace the background image with a background color for mobile screens only. Now, remember, we’re using an inline style for the background image, which means we need to use the ugly “!important” for the proper override in this case. If you’re not concerned with the need for an inline style here, then you can simply cascade your overriding media query style for the image to color replacement. (Note: we are using Bootstrap’s default variable “$screen-xs-max” for the pixel size since our platform is based on Bootstrap.)

SCSS:

 

.score-hero {
    @media only screen and (max-width: $screen-xs-max) {
        background: rgba(0, 0, 0, 0.8) !important;
    }
}

 

Compile…and now mobile screens up to 767px wide now look like this:

 

screenshot-final

 

Step 5: Next, you need to set the foreground image to “display: none;” to hide it on desktop. In this case, I’m setting it to “display: block;” only for extra small screens. So easy!

SCSS:

 

.score-hero {
    @media only screen and (max-width: $screen-xs-max) {
        background: rgba(0, 0, 0, 0.8) !important;
    }
    .score-hero-image {
        display: none;
        img {
            width: 100%;
        }
        @media only screen and (max-width: $screen-xs-max) {
            display: block;
        }
    }
}

 

Compile…and now screens above 768px wide look like this:

(768px – Bootstrap default for $screen-sm)

 

screenshot-768

 

(992px – Bootstrap default for $screen-md)

 

screenshot-992

(1200px – Bootstrap default for $screen-lg)

screenshot-desktop

Final code used in styling this demo

SCSS (for score-hero):
_site-heroes.scss (SCORE users)

.score-hero {
    @extend .jumbotron; //inherit bootstrap
    @include vertical-space($vertical-spacing);
    overflow: hidden; //to crop foreground image for border-radius
    @media only screen and (max-width: $screen-xs-max) {
        background: rgba(0, 0, 0, 0.8) !important;
        padding-top: 0;
    }
    @media only screen and (min-width: $screen-sm-min) {
        text-align: right;
    }
    .score-hero-image {
        display: none;
        img {
            width: 100%;
        }
        @media only screen and (max-width: $screen-xs-max) {
            display: block;
            margin-left: -15px;
            margin-right: -15px;
        }
    }
    h1 {
        color: #fff;
    }
    .score-hero-body {
        color: #aaa;
        margin-bottom: 30px;
        p {
            @media only screen and (min-width: $screen-sm-min) {
                width: 50%;
                float: right;
            }
        }
    }
    .score-call-to-action {
        clear: both;
        a {
            font-size: 10px;
            font-weight: bold;
            text-transform: uppercase;
        }
    }
}

 

SCSS (for “.cover” class with all components that accept background images):
_site-background.scss (SCORE users)

 

.score-stripe, .score-style-box, .score-carousel-pane, .score-full-width-hero, .score-hero, .score-section-header, .score-well {
    &.cover {
        background-position:center center;
        background-repeat:no-repeat;
        background-size:cover;
    }
    &.contain {
        background-repeat:no-repeat;
        background-size:contain;
    }
    &.repeat {
        background-repeat:repeat;
    }
    &.repeat-x {
        background-repeat:repeat-x;
    }
    &.repeat-y {
        background-repeat:repeat-y;
    }
}

 

There’s one more step when we’re using SCORE. In “experience editor” mode we’ll need to override our “display: none;” for the “.score-hero-image” to “display: block;” at all times in page_editor.scss. Why? Your content admins need to be able to see the foreground image that will be used in Experience Editor. Without this overriding page editor style, they will lack the capability to insert or even switch out the image.

SCSS (for experience editor/page editor override):
page_editor.scss (SCORE users)

 

.score-hero {
    .score-hero-image {
        display: block;
    }
}

 

Compile, and now page-editor.css cascades after main.css to override the “display: none;” on the hero image. Here’s a demo.

Super easy, right?

 

Ben Cato

These days, I love the people I work with and I love what I do. I specialize in front-end development (HTML5, CSS3, LESS, SASS, JS, GSAP and Photoshop / Illustrator / Sketch App). Learn more about Ben.

Add a Comment

Your email address will not be published. Required fields are marked *

Or request call back