Giter VIP home page Giter VIP logo

tailwindcss-safe-area's Introduction

tailwindcss-safe-area

Safe area inset utilities extending margin, padding, and height. The plugin provides base, offset, and or utilities for better adaptability across various scenarios.

Getting started

npm install --dev tailwindcss-safe-area

Then add the plugin to your tailwind.config.js file:

// tailwind.config.js
module.exports = {
	theme: {},
	plugins: [require('tailwindcss-safe-area')],
}

Usage

This plugin extends the padding and margin utilities with three types:

  1. Base Utilities: The base safe area inset utilities. These include the initial padding and margin utilities with the safe area in consideration. They can be used where you want the element to respect the safe area insets.

  2. Offset Utilities: These utilities allow you to extend the base safe area inset by a given offset. This can be particularly useful when you want a bit more spacing than the safe area provides, for example in situations where you have a translucent UI over a background image or video and want to ensure important visual content isn't covered.

  3. Or Utilities: These utilities let you specify a minimum value to use if it's greater than the safe area inset. This can be used when you have certain layout elements that should respect the safe area but should never be smaller than a certain size.

Here are some examples:

Base utilities

<header class="pt-safe">...</header>

<main class="px-safe">
	<p>ciao</p>
</main>

<footer class="pb-safe">...</footer>

Offset utilities

The offset utilities can be used by appending -offset-{value} to the base utility. This applies an additional margin or padding equal to the specified value. For example, if you want to apply a right padding that is equal to the safe area inset plus 4 units of your spacing scale, you can use:

<div class="pr-safe-offset-4">...</div>

Or utilities

The or utilities can be used by appending -or-{value} to the base utility. This applies a margin or padding that is the larger of the safe area inset and the specified value. For example, if you want to apply a bottom padding that is the larger of the safe area inset and 8 units of your spacing scale, you can use:

<div class="pb-safe-or-8">...</div>

Provided utilities

Utilities Styles
m-safe, p-safe env(safe-area-inset-{top, right, bottom, left})
mx-safe, px-safe env(safe-area-inset-{right, left})
my-safe, py-safe env(safe-area-inset-{top, bottom})
mt-safe, pt-safe env(safe-area-inset-top)
mr-safe, pr-safe env(safe-area-inset-right)
mb-safe, pb-safe env(safe-area-inset-bottom)
ml-safe, pl-safe env(safe-area-inset-left)
min-h-screen-safe, max-h-screen-safe, h-screen-safe calc(100vh - (env(safe-area-inset-top) + env(safe-area-inset-bottom)))
-webkit-fill-available
*-safe-offset-{value} calc(env(safe-area-inset-*) + {value})
*-safe-or-{value} max(env(safe-area-inset-*), {value})

Tip: To extend html content behind the safe area, set viewport-fit=cover

<meta
	name="viewport"
	content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>

Examples with generated output

Base Utility Example

<header class="pt-safe">...</header>

This applies a top padding to the header that is equal to the safe area inset at the top. The generated CSS would be:

.pt-safe {
	padding-top: env(safe-area-inset-top);
}

Offset Utility Example

<div class="pr-safe-offset-4">...</div>

This applies a right padding to the div that is equal to the safe area inset on the right plus 4 units of your spacing scale. Assuming your spacing scale unit is 8px (default in Tailwind CSS), the generated CSS would be:

.pr-safe-offset-4 {
	padding-right: calc(env(safe-area-inset-right) + 1rem);
}

Or Utility Example

<div class="pb-safe-or-8">...</div>

This applies a bottom padding to the div that is the larger of the safe area inset at the bottom and 8 units of your spacing scale. Assuming your spacing scale unit is 8px (default in Tailwind CSS), the generated CSS would be:

.pb-safe-or-8 {
	padding-bottom: max(env(safe-area-inset-bottom), 2rem);
}

Troubleshooting

The h-screen-safe and min-h-screen-safe utilities may not work as expected on Google Chrome. Add height: -webkit-fill-available on parent nodes:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
	html {
		height: -webkit-fill-available;
	}

	body {
		height: -webkit-fill-available;
	}

	/* If using React, set height on the root div as well */
	#root {
		height: -webkit-fill-available;
	}
}

tailwindcss-safe-area's People

Contributors

adamwathan avatar bpisano avatar brandonmcconnell avatar felixgeissler avatar kogomre avatar lukebennett88 avatar mgn901 avatar mvllow avatar robinmalfait avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tailwindcss-safe-area's Issues

Wrong dependency throwing error with Yarn

Project builds with Yarn that utilizes tailwindcss-safe-area as a Tailwind plugin will fail. I assume this is due to tailwindcss-safe-area depending on the tailwindcss package as a devDependency only.

See this Yarn output:

Executing task: yarn workspace frontend run start 

Application bundle generation failed. [1.333 seconds]
✘ [ERROR] Your application tried to access tailwindcss-safe-area, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.

Required package: tailwindcss-safe-area
Required by: /Users/felix/test-tw-safe-area/packages/frontend/

Require stack:
- /Users/felix/test-tw-safe-area/packages/frontend/tailwind.config.ts [plugin angular-sass]

    angular:styles/global:styles:1:8:
      1 │ @import 'src/styles.scss';
        ╵         ~~~~~~~~~~~~~~~~~

  This error came from the "onLoad" callback registered here:

    ../../.yarn/__virtual__/@angular-devkit-build-angular-virtual-db07bc24ee/3/.yarn/berry/cache/@angular-devkit-build-angular-npm-17.1.2-94d5f6ed53-10c0.zip/node_modules/@angular-devkit/build-angular/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js:113:22:
      113 │                 build.onLoad({ filter: language.fileFilter }, (0,...
          ╵                       ~~~~~~

    at setup (/Users/felix/test-tw-safe-area/.yarn/__virtual__/@angular-devkit-build-angular-virtual-db07bc24ee/3/.yarn/berry/cache/@angular-devkit-build-angular-npm-17.1.2-94d5f6ed53-10c0.zip/node_modules/@angular-devkit/build-angular/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js:113:23)
    at async handlePlugins (/Users/felix/test-tw-safe-area/.yarn/unplugged/esbuild-npm-0.19.11-b091158d92/node_modules/esbuild/lib/main.js:1340:9)

I will provide a quick fix for this. :)

Should height-safe-offset-8 work?

I guess I misunderstood the docs since I thought *-safe-offset-{value} would mean I could do something like height-safe-offset-8?

Need help setting up p-safe class strategy for a Next.js pwa app with a fixed top and bottom navbar

Hi there. Thanks for the plugin. I'm trying to perform an optmized UX for my pwa app (Next.js 12 / Tailwindcss / Shadcn ui) when installed on iOS fullscreen / standalone mode.

The issue is I can't find the right "recipe" when applying p-safe classes to my app's layout structure, as it is shown bellow...

The top and bottom navbars are working as expected with the safe padding apllied properly when in fullscreen / standalone mode. However, I'm still having issues with the body that ends up getting a huge extra top padding when the app is opened on iOS standalone mode, it also seems to block interactivity until it is touched or scrolled, which is when it kind of falls back to a normal acceptable padding.

Even if I remove the safe padding from the body and then try to apply a top and bottom padding to the main layout, something is just not right in fullscreen mode. I'd really appreciate any guidance regarding the layout. Thanks in advance!

global.css

  html {
    display: flex;
    flex-direction: column;
  }

  html,
  body {
    height: -webkit-fill-available;
  }

  body {
    flex-grow: 1;
    /* PWA enhancements */
    -webkit-overflow-scrolling: touch;
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    overflow-x: hidden;
    @apply flex flex-col bg-background text-foreground antialiased select-none pt-safe pb-safe;
  }

top-navbar.tsx

interface TopNavProps {
  title?: string
}

export const TopNav = ({ title }: TopNavProps) => {
  return (
    <header className='site-header fixed left-0 top-0 z-40 w-full border-b border-border bg-secondary px-safe pt-safe'>
      <div className='mx-auto flex h-16 w-full max-w-screen-lg items-center justify-between px-6'>
        ...
      </div>
    </header>
  )
}

bottom-nav.tsx

export const BottomNav = () => {
    return (
        <nav className='bottom-nav fixed bottom-0 left-0 z-40 w-full border-t border-border bg-secondary pb-safe'>
            <div className='mx-auto flex h-16 max-w-md items-center justify-around px-6'>
                ...
            </div>
        </nav>
    )
}

layout.tsx

import Head from 'next/head'
import { Appbar } from '@/components/nav-top'
import { BottomNav } from '@/components/nav-bottom'
import { cn } from '@/lib/utils'

interface PageLayoutProps {
  title?: string
  className?: string
  children: React.ReactNode
}

export const PageLayout = ({ title, className, children }: PageLayoutProps): JSX.Element => (
  <>
    {title ? (
      <Head>
        <title>{title} - Mio Vino</title>
      </Head>
    ) : null}

    <Appbar title={title} />

    <main
      /**
       * Padding top = `appbar` height
       * Padding bottom = `bottom-nav` height
       */
      className={cn('mx-auto max-w-screen-lg px-safe pt-16 pb-20', className)}
    >
      <div className='px-6 py-4'>{children}</div>
    </main>

    <BottomNav />
  </>
)

Views are always scrolling over the end when applying min-h-screen-safe

The min-height: -webkit-fill-available; part of min-h-screen-safe makes the page be scrollable over the end, even if the content is occupying less than half of it.

I'm using a calc instead of the utility class to overcome this issue, but would it make sense to have a class that doesn't imply adding that part?

Doesn't work on Chrome?

Hi,

Thanks for this nice little package. This is exactly what I was looking for. It works pretty well on Safari and Firefox, but I couldn't get it to work on Chrome. I'm using React, and here is the code of a div at the root of the app:

<div className="bg-red-500 h-screen-safe">Test</div>

And the result on different browsers.

Safari iOS

Capture d’écran 2022-10-18 à 20 53 24

Safari macOS

Capture d’écran 2022-10-18 à 20 53 41

Firefox

Capture d’écran 2022-10-18 à 20 53 29

Chrome

Capture d’écran 2022-10-18 à 20 55 07

On Chrome, the div doesn't want to fit the window height. Do you have any idea of the cause of the issue? Maybe I'm missing something.

Add new option bottom-safe for using with position directions

I want to suggest an improvement for your package, add the ability to specify directions when using a fixed position, absolute, etc. We have a case in which padding, margin is not suitable for solving the problem.
'.bottom-safe': {
bottom: 'env(safe-area-inset-bottom)',
},
For example, to use *-safe-offset-{value} in this case, and maybe it will help other users of the package, I do not exclude that you can consider other directions if you see fit.
This option also solves the problem with problems on iPhone devices related to its menu area.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.