I Serve Different Hero Images Across Various Screens With CSS Variables
In this short tutorial, I’ll show you a neat way to serve different hero images across various screens with the help of CSS variables. Let’s get into it!
Section With Single Background Image
Consider the following page layout:



Here, we have two sections: a hero section with a background image taken from Unsplash and an overlay, and another one with some text.
uk-*
is a UIkit class.UIKit Tutorials
HTML Markup
The page markup will look like this:
1 |
<section class="hero uk-background-cover uk-background-norepeat"> |
2 |
<div class="uk-container uk-container-small">...</div> |
3 |
</section>
|
4 |
<section class="uk-padding-large"> |
5 |
<div class="uk-container uk-container-small">...</div> |
6 |
</section>
|
Regarding the styles:
- The hero section won’t have a static height like 100vh. Its height will depend on the overlay content. Just to show a bigger part of the image, we’ll also give it some top and bottom paddings relevant to the viewport height.
- At this point, we’ll add the background image through the CSS.
Here’s the corresponding CSS rule:
1 |
.hero { |
2 |
padding: 20vh 0; |
3 |
background-image: url(IMAGE_URL); |
4 |
}
|
And the resulting demo:
Hero Section With Multiple Background Images
So far, so good! But let’s assume that this layout represents a single blog post or product design. Obviously, on a website, we can have multiple posts/products with different contents.
In such a case, there are two requirements:
- The website administrator should be able to change the image and its position through the admin.
- There should be three different background images depending on the viewport size. This is a common requirement as most of the time, a single image won't look nicely across all screens.
In terms of visualizing this in our CMS, we’ll have something like this:






For this example, I used the popular ACF WordPress plugin to create the fields. But, of course, in your case, you can build them as you wish and elaborate to display the recommended image dimensions for helping the content creators.
Under these requirements, we have to think of a way to show different images depending on the viewport size.
Method #1: Extra Markup
One solution is to create some extra div
elements that will be absolutely positioned inside the section and make them appear at different times with the help of the UIkit visibility classes. Then, as the images come dynamically through a server-side language like PHP, we’ll also add them through inline CSS. The same will happen for the background positions.
With that in mind, here’s the new version of the hero section markup:
1 |
<section class="hero uk-position-relative"> |
2 |
<div class="uk-background-cover uk-background-norepeat uk-position-cover uk-hidden@m" style="background-image: url(bg-hero-mobile.jpg)"></div> |
3 |
<div class="uk-background-cover uk-background-norepeat uk-cover uk-position-cover uk-visible@m uk-hidden@l" style="background-image: url(bg-hero-tablet.jpg)"></div> |
4 |
<div class="uk-background-cover uk-background-norepeat uk-cover uk-position-cover uk-visible@l" style="background-image: url(bg-hero-desk.jpg)"></div> |
5 |
<div class="uk-container uk-container-small">...</div> |
6 |
</section>
|
Be sure to inspect these div
s and examine what their attached UIkit classes do.
The related demo:
Method #2: CSS Variables
A more elegant way that helps us avoid bloating the markup with empty elements, or even duplicating things, takes advantage of CSS variables. This idea is simple; we keep the initial markup and define three CSS variables; one variable for each image. The same should happen for the background positions, although we’ll skip it for now.
Then, within the CSS, we set appropriate rules based on the UIkit breakpoints that handle what image should appear each time. That way, we keep the simplicity of the initial demo and allow receiving dynamic content.
With that in mind, here’s the new version of the hero section markup:
1 |
<section class="hero uk-background-cover uk-background-norepeat" style="--bg-image-mobile: url(bg-hero-mobile.jpg); --bg-image-tablet: url(bg-hero-tablet.jpg); --bg-image-desktop: url(bg-hero-desk.jpg)"> |
2 |
<div class="uk-container uk-container-small">...</div> |
3 |
</section>
|
The associated styles:
1 |
.hero { |
2 |
background-image: var(--bg-image-mobile); |
3 |
}
|
4 |
|
5 |
@media (min-width: 960px) { |
6 |
.hero { |
7 |
background-image: var(--bg-image-tablet); |
8 |
}
|
9 |
}
|
10 |
|
11 |
@media (min-width: 1200px) { |
12 |
.hero { |
13 |
background-image: var(--bg-image-desktop); |
14 |
}
|
15 |
}
|
And finally, the related demo:
Conclusion
As you see, CSS variables can help us accomplish effortless common tasks without involving JavaScript. Apart from the trick we discussed here with images, another great use for them is the creation of staggering animations—we’ve covered this many times! For instance, check out these tutorials:
- How to Build a JavaScript Page Loading AnimationGeorge Martsoukos22 Mar 2023
- How to Animate a “Twisting Text Effect” With CSS and JavaScriptGeorge Martsoukos30 Aug 2022
As always, thanks a lot for reading!