
A guide to shoehorning Next.js projects into the GitHub Pages ecosystem, with GitHub Actions for building and deploying on push and Imgix for image hosting
Henry Bley-Vroman
Posted
A version of this post appeared on viget.com
Tailwind CSS's aspect ratio plugin uses the aspect-ratio
property, an exciting newish addition to CSS (MDN page). What front-end developers have been doing with extra elements or extra pseudoelements, tricky padding, and relative positioning which can have rippling effects complicating markup now takes just a single style rule.
As long as the browsers you support support it.
For developers using Tailwind CSS v3 (so developers not supporting Internet Explorer; Tailwind CSS browser support docs) the notable risk is desktop Safari 14 and mobile Safari on iOS 14 (caniuse page for aspect-ratio
). Global usage is dropping as more and more users upgrade to version 15, and it won't be too long before iOS 14 disappears from new contracts, visual QA checklists, and browserlist target configurations.
As of this writing Viget is in a transitional phase: our UI developers —early Tailwind CSS adopters and still true believers— have become accustomed to the ease of using .aspect-…
classes on the newest work where full iOS support starts at 15 (with very good to excellent experience on 14), but we do also still have active projects where iOS 14 is fully supported. On those projects we want to use Tailwind CSS's aspect ratio plugin, but we can't.
I recently happened on a single-selector aspect ratio solution that makes clever use of floated pseudoelements. Credit to https://github.com/takamoso/postcss-aspect-ratio-polyfill
css
el::before {content: "";float: left;padding-top: <100% / aspect ratio>;}el::after {clear: left;content: "";display: block;}Copied
Single-selector?? That got me thinking that a Safari 14-compatible aspect ratio plugin might be possible. Ideally it would
aspect-ratio
CSS property (but which Tailwind CSS v3 supports; the plugin will not bring .aspect-...
to Internet Explorer)aspect-ratio
CSS property for browsers which support itaspectRatio
Tailwind CSS configuration objectHere's my solution, in the context of a Tailwind CSS configuration file:
js
// tailwind.config.jsmodule.exports = {// …corePlugins: {aspectRatio: false,// …},plugins: [({ matchUtilities, theme /* … */ }) => {// …matchUtilities(// https://gist.github.com/olets/9b833a33d01384eed1e9f1e106003a3b{'aspect': (value) => ({'@supports (aspect-ratio: 1 / 1)': {aspectRatio: value,},'@supports not (aspect-ratio: 1 / 1)': {// https://github.com/takamoso/postcss-aspect-ratio-polyfill'&::before': {content: '""',float: 'left',paddingTop: `calc(100% / (${value}))`,},'&::after': {clear: 'left',content: '""',display: 'block',}},}),},{ values: theme('aspectRatio') })},],}Copied
Try it and heart it on Codepen. Try it on Tailwind Play. Cite the gist.
This is an advanced Tailwind CSS plugin. But a beauty of Tailwind CSS v3 is that even advanced plugins are legible. Here's how it works:
corePlugins({ aspectRatio: false })
disables the core aspect ratio plugin (corePlugins
docs). The aspectRatio
theme
configuration is still intact, but no CSS will be generated based on it.
matchUtilities
registers utilities that map to values defined in the user’s theme
configuration (matchUtilities
docs).
Skipping down to the end, { values: theme('aspectRatio') }
says "this plugin's configuration lives in theme.aspectRatio
".
Moving back up, the first matchUtilities
argument is a key/value pair where the key is the class prefix and the value is a function expression which receives the configuration values.
'aspect':
says "this plugin will generate CSS for the classes .aspect-<configuration key>
" (with the default theme.aspectRatio
, that's the default Tailwind CSS aspect ratio classes .aspect-auto
, .aspect-square
, and .aspect-video
).(value) => ({ ... })
is the CSS used in the generated classes, written in the Tailwind CSS CSS-in-JS idiom where selectors are keys and rules are key/value pairs. @supports
checks for browser support of CSS features (MDN page). Note the content: '""'
— content: ""
would compile to the CSS content: ;
.This plugin enhances Tailwind CSS aspect ratio classes with support for Safari <15. Use it on projects that support older versions of Safari. When the projects drop support for those browsers, remove the plugin and the corePlugins.aspectRatio
; CSS weight will decrease with no markup changes necessary.
You're welcome to use this plugin in your own projects! Its license, which requires attribution, disallows commercial use without prior agreement, and disallows use in projects which violate human rights, can be found at the gist.
A guide to shoehorning Next.js projects into the GitHub Pages ecosystem, with GitHub Actions for building and deploying on push and Imgix for image hosting
Your comprehensive guide for ERB front-end view templates.