The Responsive Immersive Header

Feb 26, 2015 | Blog

The key to making a fullscreen responsive web experience a good one.

the demo

The trend of using fullwidth images and video on the web these days is gaining a lot of popularity. No, I'm not talking about "parallax", but rather a more simplistic approach wherein you immerse the viewer into your site with large, fullscreen, media. This could be one header image or a series of images or videos.

How hard could that be? Well, it's not. But just setting some images to 100% width and using some arbitrary media queries isn't going to get you the best results.

The big idea

The idea is to create a reusable module that contains an image or video and some content (like text) that could be placed over the media. The entire module would scale the entire width and height of the browser, no matter the screen size. Note that this mostly intended for modern browsers.

Building the HTML

<div class="immersion">
  <div class="immersion-media">
    <img src="" />
  <div class="immersion-content">
    <h1>We love adventures.</h1>
    <p>Outdoors means getting out your door.</p>

Here we have a few key elements - an outer container, container for the media, the media, container for the content, and the content. Before we get too far here, let's do some really basic JavaScript to set the proper height for these modules.

Some quick jQuery

// Size immersion modules properly
var immersion = $('.immersion');
function sizeImmersion(){
// Size on load

// Size on window resize

This is a fast way to set all our modules to same height as the window's height, even on resize. I would really like to use the new CSS3 unit vh (viewport height), but they're simple not supported well enough to rely on them.

Now for some CSS

I'm using Sass here to write CSS, and so should you.

@mixin align-middle {
  &:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;

  > * {
    vertical-align: middle;
// Outside container
.immersion {
   width: 100%;
   position: relative;
   overflow: hidden;

   // Container for media
   .immersion-media {
     position: absolute;
     text-align: center;

     // Horizontal layout
     @media (min-aspect-ratio: 16 / 9) {
       top: -1000%;
       bottom: -1000%;
       left: -4px;
       right: 0;
       @include align-middle;

       > *:nth-child(1) {
         height: auto;
         width: calc(100% - 4px);

       &.top {
         top: 0;
         bottom: auto;

       &.bottom {
         top: auto;
         bottom: 0;

     // Vertical layout
     @media (max-aspect-ratio: 16 / 9) {
       top: 0;
       bottom: 0;
       left: -1000%;
       right: -1000%;

       > *:nth-child(1) {
         height: 100%;
         width: auto;

       &.left {
         left: 0;
         text-align: left;

       &.right {
         right: 0;
         text-align: right;

Let's look at this piece by piece:

align-middle mixin

A handy mixin to make children elements vertically align middle inside a container. It works by creating an inline-block pseudo element and setting every child to vertically-align middle. In CSS, vertical-alignment (unless a table-cell) is based on sibling elements; so, since the first element is 100% tall, it acts as a baseline for the remaining sibling to align to.


This container is the "viewport" for our module. We set this to have 100% width and 100% height (of the browser window). We're setting overflow: hidden so that we can crop the media as needed.


Setting this to use position: absolute lets us crop and align the image in any configuration. We're using some min-aspect-ratio and max-aspect-ratio media queries to correctly crop the media as the window size changes. Notice we're using an aspect ratio of 16/9, thus the image should exactly match that aspect ratio. Since this is the most common size for screens these days, it's a good starting point. Within our container, we simply grab the first child element and assume that's our media.

We're leveraging these media queries to determine which direction we should crop the media. When the screen is stretched wide (horizontal layout), the media should scale by its width, and when stretching vertically, we're scaling by its height.

Positioning the media

By default this will center the media vertically and horizontally. We accomplish this with the align-middle mixin and text-align: center. Why the crazy -1000%? Since by default the media is center-aligned, we need space to allow movement. If this value isn't large enough, the element will hit the container and won't crop on center. We've added modifier classes here so that the media can be positioned by any combination of top, bottom, left, or right.

Styling the content

  .immersion-content {
    position: relative;
    top: 30%;
    left: 5%;
    text-align: left;
    color: white;
    font-family: "Open Sans";
    font-size: 0.9em;
    text-shadow: 1px 1px 10px black;

This content can really be used however you like. It would be a good idea to create a series of classes that give some basic positioning that further define this class.


Delivering this sort of web experience can be incredibly rich and exciting. Accomplishing a similar effect can be done with a background, but it's inherently limiting. The fact that you can use video or images is enough of a reason to use something like this.

I'd love to hear what your thoughts on this or any improvements you would offer.

Recent Articles

Introducing Relatable

Keeping things organized within a Shopify store can be hard, so we built Relatable to help with that.

Why we use Cloud66 to launch Ruby on Rails apps

We use Cloud66 for deploy Ruby on Rails apps, and we love it.

5 Common Pitfalls when Developing a Shopify Theme

Learn some tips on developing Shopify themes and some pitfalls to avoid. Build Shopify themes that perform and are easy to update and edit.

How to create a Shopify email link from your theme navigation

Add an email link to your Shopify website from within your theme using your current link list in navigation.

How to flag Shopify products as "new" by date

Here's a quick way to mark a product as being new by the date it was added to your Shopify store.