Safe Areas

With the iPhone X release and further, Apple introduced so called safe areas, later implemented by Google Chrome with support in Android.

On devices with safe areas (like with top screen notch), app UI must include additional top/bottom spacing (to consider top notch and bottom bar) in portrait orientation and additional left/right spacing (to consider left/right notch) in landscape orientation.

Viewport

If your app targets full screen mobile devices, make sure you have viewport-fit=cover in your <meta name="viewport">, e.g.:

<!DOCTYPE html>
<html lang="en">
  <head>
    ...
    <!-- Make sure you have viewport-fit=cover in content -->
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover"
    />
  </head>

  <body>
    ...
  </body>
</html>

Safe Areas

To tell our components that our app is a full screen app and we need to consider safe areas, we need to add safe-areas class to Tailwind Mobile components parent element, preferably to the root app element.

/* App.jsx */
import React from 'react';

export default function MyApp() {
  return (
    <>
      {/* add "safe-areas" class to the app root element */}
      <div id="my-app" className="safe-areas">
        ...
      </div>
    </>
  );
}

If you use Tailwind Mobile's App component, then it can be enabled with safeAreas prop:

/* App.jsx */
import React from 'react';
import { App, ... } from 'tailwind-mobile/react';

export default function MyApp() {
  return (
    <>
      {/* enable with safeAreas prop */}
      <App safeAreas theme="ios">
        ...
      </App>
    </>
  );
}

This is how safe-areas class defined in CSS:

:root: {
  --twm-safe-area-left: 0px;
  --twm-safe-area-right: 0px;
  --twm-safe-area-top: 0px;
  --twm-safe-area-bottom: 0px;
}

@supports (left: env(safe-area-inset-left)):  {
  .safe-areas: {
    --twm-safe-area-left: env(safe-area-inset-left);
    --twm-safe-area-right: env(safe-area-inset-right);
    --twm-safe-area-top: env(safe-area-inset-top);
    --twm-safe-area-bottom: env(safe-area-inset-bottom);
  }
}

Disable Safe Areas

It can be useful to disable safe areas on modals and side panels which are not full screen elements.

We can disable safe areas on certain elements with the following utility classes:

Class
.no-safe-areasDisable all safe areas on element
.no-safe-areas-topDisable top safe area on element
.no-safe-areas-rightDisable right safe area on element
.no-safe-areas-bottomDisable bottom safe area on element
.no-safe-areas-leftDisable left safe area on element

This is how no-safe-areas classes defined in CSS:

@supports (left: env(safe-area-inset-left)):  {
  .no-safe-areas: {
    --twm-safe-area-left: 0px;
    --twm-safe-area-right: 0px;
    --twm-safe-area-top: 0px;
    --twm-safe-area-bottom: 0px;
  }
  .no-safe-areas-top: {
    --twm-safe-area-top: 0px;
  }
  .no-safe-areas-right: {
    --twm-safe-area-right: 0px;
  }
  .no-safe-areas-bottom: {
    --twm-safe-area-bottom: 0px;
  }
  .no-safe-areas-left: {
    --twm-safe-area-left: 0px;
  }
}

Safe Spacing & Placement

We can also consider safe areas when placing elements:

ClassCSS
.top-safetop: var(--twm-safe-area-top)
.top-[value]-safetop: calc([value] + var(--twm-safe-area-top))
.right-saferight: var(--twm-safe-area-right)
.right-[value]-saferight: calc([value] + var(--twm-safe-area-right))
.bottom-safebottom: var(--twm-safe-area-bottom)
.bottom-[value]-safebottom: calc([value] + var(--twm-safe-area-bottom))
.left-safeleft: var(--twm-safe-area-left)
.left-[value]-safeleft: calc([value] + var(--twm-safe-area-left))

And same with margin and padding:

ClassCSS
.pt-safepadding-top: var(--twm-safe-area-top)
.pt-[value]-safepadding-top: calc([value] + var(--twm-safe-area-top))
.pr-safepadding-right: var(--twm-safe-area-right)
.pr-[value]-safepadding-right: calc([value] + var(--twm-safe-area-right))
.pb-safepadding-bottom: var(--twm-safe-area-bottom)
.pb-[value]-safepadding-bottom: calc([value] + var(--twm-safe-area-bottom))
.pl-safepadding-left: var(--twm-safe-area-left)
.pl-[value]-safepadding-left: calc([value] + var(--twm-safe-area-left))
ClassCSS
.mt-safemargin-top: var(--twm-safe-area-top)
.mt-[value]-safemargin-top: calc([value] + var(--twm-safe-area-top))
.mr-safemargin-right: var(--twm-safe-area-right)
.mr-[value]-safemargin-right: calc([value] + var(--twm-safe-area-right))
.mb-safemargin-bottom: var(--twm-safe-area-bottom)
.mb-[value]-safemargin-bottom: calc([value] + var(--twm-safe-area-bottom))
.ml-safemargin-left: var(--twm-safe-area-left)
.ml-[value]-safemargin-left: calc([value] + var(--twm-safe-area-left))

For example:

{
/*
"left-safe" class will set:
  left: var(--twm-safe-area-top);

"bottom-4-safe" class will set:
  bottom: calc(1rem + var(--twm-safe-area-bottom));
*/
}
<div className="left-safe bottom-4-safe">...</div>;
Code licensed under MIT.
2021 © Tailwind Mobile by nolimits4web.