Handling the Notch on iPhone X, XS, XR, XS Max and Google Pixel correctly.


Raise your hands if you love the notch on iPhone X, XS, XR or XS Max! 🙋‍♀️🙋‍♂️

Notched iPhones are in!
The notched iPhone with rounded corners.

Okay. Not many hands went up there, but I’m sure as a web developer (or designer) you will definitely love some extra real estate to play with on your tiny screen? A beautiful edge-to-edge display—well, almost—makes the notch at the top of the bezel disappear for most mobile users.  To me at least, the notch has never posed a problem as long as I am surfing the web in portrait mode, that is.

Update: Google has announced that Pixel 3—like the new iPhones—will carry a notch. The following post describes a graceful technique to handle the notch correctly for all your content, without using any javascript or css hacks. Shine away you crazy diamond!

Notch on Dev.to in portrait!
notch in portrait mode

The notch doesn’t appear on the list of nits to worry about for most websites in portrait mode. It is the landscape mode where the notch pokes in the eye. Pokes so badly that it hurts. Take a look at the Dev blog site, for example:

Safe gutters on dev.to

The header ends abruptly, both on the left and the right, leaving behind a feeling of a bug in the layout. This happens even when width: 100% is specified on CSS, which is kind of super weird. The bug is even worse for Youtube.com:

Default gutters on youtube.com

Terrible, I’d say. 🤢

It feels particularly bad on Youtube because we normally watch videos in landscape mode and after every video you get to see this glaring rectangle of a header in blood-red color. Youtube too has its header width set to 100% in the layout, but that fails.

There is blank gutter area on both sides of the webpage because mobile browsers like Safari (on iOS 12+) and Chrome v69 or higher on notched phones introduce/force these white bars on the webpage by adding a little bit of extra margin. They do this to avoid older content getting obscured by the notch, but it also means that our understanding about declaring 100% width on CSS being equal to full screen width is no longer true. Especially for non-rectangular screens. Lame, I know!

This extra margin thing is called a safe area margin.

Now the question is how to handle the notch correctly for your website and can you do it without using any sort of non-standard hacks like the safe area margins?

Here’s a simple fix to use all the extra space:

To tell the browser to expand into the display cutout (notched) area, set the viewport-fit property to cover like so:

<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>

viewport-fit cover for notched viewports

This should do the trick, especially for the sticky header on top, but also for the rest of the content on page. If you want to apply full screen width just to the header but avoid the body or main content from going under the notch, you can use an environment variable (not recommended) on a css class like so:


.content {
  padding: 16px;
  padding-left: env(safe-area-inset-left); /* Apply safe area */
  padding-right: env(safe-area-inset-right);
}

/* The are four safe-area padding options:
* padding: env(safe-area-inset-top) 
*         env(safe-area-inset-right) 
*         env(safe-area-inset-bottom) 
*         env(safe-area-inset-left);
*/

safe-area environment variables

Basically, there are four options to handle the notch from all four sides of the notched mobile, providing a safe area for the webpage’s overall environment. While these insets do solve rendering content away from the notched region mostly, it is generally not recommended to use these properties (special hacks) created specifically for non-rectangular viewports simply because they are non-standard.

There’s a much simpler solution to avoid the clash of notch with content using simple and _standard_ CSS rules. For our solution we’ll use ordinary width definitions per single @media-query, like so:


/* scss snippet */

@media only screen and (orientation: portrait) {
    body {
        .shrink {
            width: 95%;        
        }
    }
}

@media only screen and (orientation: landscape) {
    body {
        .shrink {
            width: 90%;      /* Shrink a little more to avoid the notch. */
        }
    }
}


.center {
    text-align: center;
    margin: 0 auto;
}


Media-query to handle notch

That’s it! And then in your HTML, the main container element can sit with css classes shrink center to work across all devices and all viewports with just one definition.

<header>
    <!--Sticky header with 100% width running across the notched screen -->
<header>
<main class="shrink center">
    <!-- Body here -->
</main>
<footer>
    <!-- Full screen width under the notch -->
</footer>

I prefer handling the notch this way because it helps us avoid using device specific hacks (the safe-area-insets) on our layout. That’s how Bubblin scales from an Apple Watch to the iPad to a desktop all the way up to an OLED TV. 🎩

There are few other solutions floating around on the web that solve the same problem using javascript but I do not recommend that. CSS is better suited for solving this layout nit than javascript ever will be. Also, less code often means better maintainability, better scalability etc.

Bubblin Superbooks

Superbook landscape mode

That’s all for this post folks.

Now, remember this: When the notch pokes you in the eye again, you poke them back! ❤️


  • About the author: Hi. I am Marvin Danig, CEO of Bubblin Superbooks (link) and a lousy web developer. You should probably follow me on Twitter, DMs open.
  • This blog was first published in September, 2018 but is still relevant.