tailwindcss-aspect-ratio
A Tailwind CSS plugin that adds composable aspect-w/aspect-h utility classes for locking element aspect ratios.
Repository Health
Technical Analysis
@tailwindcss/aspect-ratio is an official Tailwind Labs plugin that provides composable aspect-w-{n} and aspect-h-{n} utility classes for constraining an element’s aspect ratio using the classic padding-bottom trick. It was built to fill the gap before native CSS aspect-ratio support landed in browsers, and remains useful for projects that still need Safari 14 compatibility.
The plugin registers custom Tailwind components rather than raw utilities, generating paired width/height classes (defaulting to ratios 1 through 16) that can be mixed and matched, plus an aspect-none escape hatch to remove the behavior entirely at a given breakpoint. It supports both Tailwind CSS v2’s variants API and v3’s matchComponents API, so it keeps working across major Tailwind versions despite being effectively feature-frozen since Tailwind v3 shipped native aspect-ratio utilities.
What You Get
- Composable
aspect-w-{n}/aspect-h-{n}classes for ratios 1 through 16 out of the box - An
aspect-noneutility to disable the aspect-ratio behavior at any breakpoint - Dual compatibility with both Tailwind CSS v2 (variants API) and v3 (matchComponents API)
- A configurable
aspectRatiotheme key to define custom ratio values and variants
Common Use Cases
- Embedding responsive YouTube/Vimeo iframes that need to preserve a 16:9 ratio
- Building responsive image or video galleries with consistent card ratios
- Supporting Safari 14 users who lack native CSS aspect-ratio support
- Maintaining legacy Tailwind v2 projects that already depend on the plugin’s variants API
Under The Hood
Architecture
The plugin is a single file (src/index.js, ~125 lines) registered via plugin() from tailwindcss/plugin. It exports one function that, at Tailwind build time, checks whether the passed helpers include matchComponents (Tailwind v3’s dynamic-class API) — if so it uses matchComponents for aspect-w/aspect-h plus addComponents for the static .aspect-none reset; if not (Tailwind v2), it falls back to enumerating the configured aspectRatio theme values manually, building selector strings with the e() escape helper, and calling addComponents with the v2 variants() API. There’s no build system and no runtime state beyond that closure — the entire architecture is one conditional branch selecting between two plugin APIs, consumed directly by Tailwind’s own compiler.
Tech Stack
Shipped as plain CommonJS (require/module.exports) with no bundler or transpiler — main and types point straight at src/. devDependencies include Jest for tests, PostCSS for running the plugin against real CSS output, and both tailwindcss (v3) and an aliased tailwindcss-v2 (npm:tailwindcss@^2.2.16) so the test suite can exercise both plugin APIs side by side. The peerDependencies range (>=2.0.0 || >=3.0.0-alpha.1) is intentionally broad for the same reason. A .github/workflows/release.yml handles publishing; there’s no visible lint config beyond a prettier block in package.json.
Code Quality
tests/test.js runs the plugin through actual PostCSS processing and asserts the generated CSS matches expected snapshot strings for both Tailwind v2 and v3, including arbitrary-value classes like aspect-w-[123] — a concrete, behavior-level test rather than a superficial one, though coverage is limited to two fixtures. Types are declared by hand in src/index.d.ts but are minimal and imprecise (declare const plugin: { handler: () => void }), not a full description of the plugin’s options. No ESLint configuration or PR-triggered CI workflow is present in the repo.
API Design
The public surface is exactly one line — require('@tailwindcss/aspect-ratio') in a plugins array, plus disabling Tailwind’s core aspectRatio plugin — about as low-boilerplate as a Tailwind plugin gets. Class naming (aspect-w-{n}, aspect-h-{n}, aspect-none) is consistent with Tailwind’s own conventions, and the README documents every option, including custom ratio overrides and arbitrary values, with runnable examples. The acknowledged rough edge, stated directly in the README, is structural: the padding-bottom technique requires an extra wrapper element and re-declaring child width/height classes at each breakpoint, a workaround the native CSS aspect-ratio property now avoids entirely.
Used by 8 apps in this directory
Bugsink
Developer Tools · Monitoring
Self-hosted error tracking that accepts Sentry SDKs out of the box, so you keep your instrumentation and drop the monthly bill.
Chaskiq
CRM · Customer Support
Self-hosted live chat, video calls, help center, and marketing automation — a full-stack Intercom alternative you run on your own infrastructure.
Crater
Invoicing Finance
Open source invoicing and billing platform for freelancers and small businesses — create estimates, track expenses, accept Stripe payments, and run recurring invoices from your own server.
Invoice Ninja
Invoicing Finance · Project Management
Self-hostable invoicing, time-tracking, and multi-gateway payment platform for freelancers and small businesses, with built-in e-invoicing compliance for EU and global standards.
Logseq
Note Taking · Knowledge Management
A privacy-first, open-source knowledge graph platform combining Markdown, Org-mode, bidirectional linking, and local-first storage for building your second brain.
Teable
Databases · No Code Platforms
A no-code PostgreSQL database with spreadsheet UX, real-time collaboration, and native AI agents — built for teams that outgrow Airtable.
TinaCMS
CMS
An open-source, Git-backed headless CMS that gives editors a live visual editing UI over Markdown, MDX, JSON, and YAML content while developers keep everything in version control.
Unkey
Developer Tools
An open-source developer platform for API infrastructure — issue and verify API keys, enforce global rate limits, route traffic through a gateway, and get per-key analytics and audit logs.