responsive-design
Use this skill when building responsive layouts, implementing fluid typography, using container queries, or defining breakpoint strategies. Triggers on responsive design, mobile-first, media queries, container queries, fluid typography, clamp(), viewport units, grid layout, flexbox patterns, and any task requiring adaptive or responsive web design.
design responsivemobile-firstcsscontainer-queriesfluid-typographyWhat is responsive-design?
Use this skill when building responsive layouts, implementing fluid typography, using container queries, or defining breakpoint strategies. Triggers on responsive design, mobile-first, media queries, container queries, fluid typography, clamp(), viewport units, grid layout, flexbox patterns, and any task requiring adaptive or responsive web design.
responsive-design
responsive-design is a production-ready AI agent skill for claude-code, gemini-cli, openai-codex. Building responsive layouts, implementing fluid typography, using container queries, or defining breakpoint strategies.
Quick Facts
| Field | Value |
|---|---|
| Category | design |
| Version | 0.1.0 |
| Platforms | claude-code, gemini-cli, openai-codex |
| License | MIT |
How to Install
- Make sure you have Node.js installed on your machine.
- Run the following command in your terminal:
npx skills add AbsolutelySkilled/AbsolutelySkilled --skill responsive-design- The responsive-design skill is now available in your AI coding agent (Claude Code, Gemini CLI, OpenAI Codex, etc.).
Overview
A production-grade reference for building responsive web experiences that adapt
fluidly across every screen size. This skill encodes specific, opinionated rules
for mobile-first CSS architecture, fluid typography with clamp(), container
queries, breakpoint strategy, and intrinsic layout techniques. Every pattern
includes concrete, copy-paste-ready CSS - not vague advice.
The difference between a truly responsive site and a barely-functional one comes down to architecture: fluid values over hard breakpoints, container awareness over viewport assumptions, and content-driven layout over device-targeted hacks.
Tags
responsive mobile-first css container-queries fluid-typography
Platforms
- claude-code
- gemini-cli
- openai-codex
Related Skills
Pair responsive-design with these complementary skills:
Frequently Asked Questions
What is responsive-design?
Use this skill when building responsive layouts, implementing fluid typography, using container queries, or defining breakpoint strategies. Triggers on responsive design, mobile-first, media queries, container queries, fluid typography, clamp(), viewport units, grid layout, flexbox patterns, and any task requiring adaptive or responsive web design.
How do I install responsive-design?
Run npx skills add AbsolutelySkilled/AbsolutelySkilled --skill responsive-design in your terminal. The skill will be immediately available in your AI coding agent.
What AI agents support responsive-design?
This skill works with claude-code, gemini-cli, openai-codex. Install it once and use it across any supported AI coding agent.
Maintainers
Generated from AbsolutelySkilled
SKILL.md
Responsive Design
A production-grade reference for building responsive web experiences that adapt
fluidly across every screen size. This skill encodes specific, opinionated rules
for mobile-first CSS architecture, fluid typography with clamp(), container
queries, breakpoint strategy, and intrinsic layout techniques. Every pattern
includes concrete, copy-paste-ready CSS - not vague advice.
The difference between a truly responsive site and a barely-functional one comes down to architecture: fluid values over hard breakpoints, container awareness over viewport assumptions, and content-driven layout over device-targeted hacks.
When to use this skill
Trigger this skill when the user:
- Asks how to build a responsive layout or page structure
- Needs a breakpoint strategy or media query system
- Wants to implement fluid typography that scales with the viewport
- Is using or learning container queries
- Needs responsive images with
srcsetor<picture> - Asks about
clamp(),min(),max(), or viewport units (vw,vh,dvh) - Wants a responsive navigation pattern (hamburger, bottom nav, drawer)
- Needs a responsive spacing or sizing scale
- Asks about mobile-first CSS architecture
- Needs adaptive layout for components like cards, grids, or sidebars
Do NOT trigger this skill for:
- Pure visual styling that isn't adaptive (colors, shadows, typography scale with no fluid values)
- Backend or API concerns, even if a mobile app is involved
Key principles
Mobile-first always - Write base CSS for the smallest screen. Use
min-widthmedia queries to progressively enhance for larger screens.max-widthqueries lead to override chains and maintenance nightmares.Use fluid values over fixed breakpoints -
clamp(),min(),max(), andvw/cqiunits create layouts that work at every size, not just at your three chosen breakpoints. Breakpoints should be rare exceptions for layout shifts, not the primary mechanism for responsiveness.Container queries over media queries for components - Components should respond to the space they're placed in, not the viewport. Use
@containerfor any component that might appear in different-width contexts (sidebars, cards, modals). Reserve media queries for page-level layout changes only.Content determines breakpoints, not devices - Add a breakpoint when the content breaks, not because you want to target iPhone vs tablet. Resize your browser slowly and add breakpoints where the layout actually needs help.
Test on real devices - DevTools device mode is not a substitute. Test on actual hardware at key points: 320px minimum width (small Android), 375px (iPhone), 768px (tablet portrait), 1024px (tablet landscape), and 1440px (desktop). Check landscape orientation and unusual sizes like 900px.
Core concepts
Viewport vs container - The viewport is the browser window. The container is
the nearest ancestor with container-type set. Media queries respond to the
viewport; container queries respond to the container. Use media queries to
change page layout structure; use container queries to change component layout
within a space.
Fluid vs adaptive - Adaptive design has discrete breakpoints where it "snaps" between layouts. Fluid design scales continuously. The best responsive systems combine both: fluid typography and spacing everywhere, with adaptive layout changes at a handful of content-driven breakpoints.
Intrinsic design - Coined by Jen Simmons. Letting content inform size using
CSS Grid's auto-fill/auto-fit/minmax() and Flexbox's flex-wrap. Fewer
media queries, more resilient layouts.
CSS logical properties - Use margin-inline, padding-block, inset-inline
instead of margin-left/right, padding-top/bottom, left/right. These adapt
automatically to writing direction (LTR/RTL) and block axis, making
internationalised responsive layouts trivial.
Common tasks
1. Mobile-first breakpoint system
Define a single breakpoint token set. Apply them consistently with min-width
only. Never mix min-width and max-width in the same component.
:root {
--bp-sm: 640px; /* large phones landscape */
--bp-md: 768px; /* tablets portrait */
--bp-lg: 1024px; /* tablets landscape */
--bp-xl: 1280px; /* desktop */
--bp-2xl: 1536px; /* large desktop */
}
/* Usage pattern - always mobile base, then expand */
.component {
/* mobile base styles */
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
}
@media (min-width: 768px) {
.component {
flex-direction: row;
gap: 24px;
padding: 24px;
}
}
@media (min-width: 1024px) {
.component {
gap: 32px;
padding: 32px 48px;
}
}Never write
@media (max-width: 767px)- that's desktop-first and leads to specificity battles. The base styles ARE the mobile styles.
2. Fluid typography with clamp()
clamp(min, preferred, max) - the preferred value is a viewport-relative
expression. The browser picks the middle value, clamped to min/max.
:root {
/* fluid body text: 15px at 320px viewport, 18px at 1280px */
--text-base: clamp(0.9375rem, 0.8rem + 0.6vw, 1.125rem);
/* fluid headings */
--text-lg: clamp(1.125rem, 0.9rem + 1vw, 1.5rem);
--text-xl: clamp(1.25rem, 0.9rem + 1.5vw, 2rem);
--text-2xl: clamp(1.5rem, 1rem + 2vw, 2.5rem);
--text-3xl: clamp(1.875rem, 1rem + 3vw, 3.5rem);
--text-4xl: clamp(2.25rem, 1rem + 4.5vw, 5rem);
/* fluid spacing */
--space-section: clamp(2rem, 1rem + 4vw, 6rem);
--space-gap: clamp(1rem, 0.5rem + 2vw, 2rem);
}
body { font-size: var(--text-base); }
h1 { font-size: var(--text-4xl); line-height: 1.1; }
h2 { font-size: var(--text-3xl); line-height: 1.2; }
h3 { font-size: var(--text-2xl); line-height: 1.3; }Calculate fluid
clamp()values precisely using Utopia (utopia.fyi) or the formula:clamp(min, min + (max - min) * ((100vw - minVp) / (maxVp - minVp)), max). Never guess the middle value.
3. Container queries for components
Container queries let components adapt to their available space regardless of viewport. Essential for any component used in varied layout contexts.
/* 1. Establish a containment context on the wrapper */
.card-wrapper {
container-type: inline-size;
container-name: card; /* optional, enables named queries */
}
/* 2. Style the component to respond to its container */
.card {
/* base: narrow container (e.g. sidebar, 240px wide) */
display: flex;
flex-direction: column;
gap: 12px;
}
/* 3. Expand when container is wide enough */
@container card (min-width: 480px) {
.card {
flex-direction: row;
gap: 24px;
}
.card-image {
width: 200px;
flex-shrink: 0;
}
}
@container card (min-width: 720px) {
.card {
gap: 32px;
}
.card-image {
width: 280px;
}
}
container-type: inline-sizeis the common case - it tracks width only. Usecontainer-type: sizeonly when you also need to query height. The container element itself cannot be styled by@container- only its descendants can.
4. Responsive grid layouts
Combine intrinsic CSS Grid with a fallback for very small screens.
/* Intrinsic auto-fill grid - no breakpoints needed */
.grid-auto {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
gap: clamp(12px, 2vw, 24px);
}
/* Explicit breakpoint grid for controlled column counts */
.grid-explicit {
display: grid;
grid-template-columns: 1fr; /* mobile: 1 col */
gap: 16px;
}
@media (min-width: 640px) {
.grid-explicit { grid-template-columns: repeat(2, 1fr); gap: 20px; }
}
@media (min-width: 1024px) {
.grid-explicit { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}
@media (min-width: 1280px) {
.grid-explicit { grid-template-columns: repeat(4, 1fr); gap: 32px; }
}
/* Sidebar layout with fluid sidebar width */
.layout-sidebar {
display: grid;
grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
.layout-sidebar {
grid-template-columns: clamp(200px, 20%, 280px) 1fr;
gap: 32px;
}
}Prefer
minmax(min(100%, Npx), 1fr)overminmax(Npx, 1fr)- themin()prevents overflow on very narrow screens whereNpxexceeds container width.
5. Responsive images with srcset and picture
Always provide multiple image sizes. Let the browser pick the best one.
<!-- Fluid image: browser picks from srcset based on display width -->
<img
src="hero-800.jpg"
srcset="
hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w
"
sizes="
(min-width: 1280px) 1200px,
(min-width: 768px) calc(100vw - 64px),
100vw
"
alt="Descriptive alt text"
width="1200"
height="600"
loading="lazy"
decoding="async"
/>
<!-- Art direction with <picture>: different crop per breakpoint -->
<picture>
<source
media="(min-width: 1024px)"
srcset="hero-landscape-1600.jpg 1600w, hero-landscape-800.jpg 800w"
sizes="100vw"
/>
<source
media="(min-width: 480px)"
srcset="hero-square-800.jpg 800w, hero-square-400.jpg 400w"
sizes="100vw"
/>
<img
src="hero-portrait-400.jpg"
srcset="hero-portrait-400.jpg 400w, hero-portrait-800.jpg 800w"
sizes="100vw"
alt="Descriptive alt text"
width="400"
height="600"
/>
</picture>Always include
widthandheightattributes to prevent layout shift (CLS). Useloading="lazy"for images below the fold. Useloading="eager"for the LCP hero image. Thesizesattribute is the most important part - a wrongsizeswastes bandwidth by downloading the wrong resolution.
6. Responsive navigation patterns
For detailed responsive navigation patterns (hamburger drawer, bottom tab bar, safe area handling), see references/navigation-patterns.md.
7. Responsive spacing scale
Fluid spacing that adapts to viewport size without breakpoints.
:root {
--space-1: clamp(0.25rem, 0.2rem + 0.25vw, 0.375rem); /* 4px -> 6px */
--space-2: clamp(0.5rem, 0.4rem + 0.5vw, 0.75rem); /* 8px -> 12px */
--space-3: clamp(0.75rem, 0.6rem + 0.75vw, 1rem); /* 12px -> 16px */
--space-4: clamp(1rem, 0.75rem + 1.25vw, 1.5rem); /* 16px -> 24px */
--space-6: clamp(1.5rem, 1rem + 2vw, 2.5rem); /* 24px -> 40px */
--space-8: clamp(2rem, 1.25rem + 3vw, 4rem); /* 32px -> 64px */
--space-12: clamp(3rem, 2rem + 4vw, 6rem); /* 48px -> 96px */
--space-16: clamp(4rem, 2.5rem + 6vw, 8rem); /* 64px -> 128px */
}
/* Apply fluid section padding */
.section {
padding-block: var(--space-12);
padding-inline: var(--space-4);
}
/* Fluid gap for grids and flex containers */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
gap: var(--space-4);
}Anti-patterns
| Anti-pattern | Why it fails | What to do instead |
|---|---|---|
Writing desktop CSS first, then overriding with max-width queries |
Override chains grow into unmaintainable specificity battles | Start with mobile base styles, add min-width queries to expand |
Fixed px font sizes |
Breaks user's browser font-size preference, fails WCAG 1.4.4 | Use rem for all font sizes so they scale with user's base preference |
| Using viewport media queries for component styling | Component breaks when placed in a sidebar or different layout | Use @container queries for component-level responsiveness |
| Hiding content on mobile instead of reorganizing it | Content hidden by CSS is still downloaded; important info becomes inaccessible | Reflow content using Grid/Flexbox direction changes; only hide decorative elements |
Static px values in clamp() middle expression |
The preferred value won't scale; clamp becomes a fixed value | Use a viewport-relative unit (e.g. 0.8rem + 2vw) as the middle value |
100vw width causing horizontal scrollbar |
100vw includes scrollbar width; overflows container by ~15px |
Use 100% for widths inside containers; use 100vw only for truly full-bleed elements |
Gotchas
clamp()middle value not viewport-relative -clamp(1rem, 1.5rem, 2rem)looks like a fluid value but the middle is a fixedrem, so it never actually scales. The middle value must contain a viewport-relative unit (vw,cqi) to produce fluid scaling. Always verify the preferred expression includes a fluid unit.container-typeset on the element being styled -@containerqueries style descendants, not the container element itself. If you setcontainer-typeon.cardand write@container (.card) { .card { ... } }, the inner rule never applies. The containment context must be on a wrapper element, one level up from the component being styled.100vwcausing horizontal scrollbar -100vwincludes the scrollbar width (typically 15-17px on desktop). Using it for full-width elements inside a document with a vertical scrollbar overflows by that amount. Use100%for widths inside layout containers; reserve100vwfor truly viewport-edge elements like modals and overlays.Fixed
pxfont sizes breaking user's zoom preference - WCAG 1.4.4 requires text to be resizable to 200% without loss of content. Fonts set inpxdon't scale with the browser's base font size preference. Useremfor all font sizes.env(safe-area-inset-bottom)missing on bottom-fixed elements - On notched iOS devices,position: fixed; bottom: 0elements overlap the home indicator. Always addpadding-bottom: env(safe-area-inset-bottom)to fixed bottom bars and tab bars. Missing this creates an unusable UI on iPhone X and later models.
References
For detailed pattern examples, load the relevant reference file:
references/breakpoint-patterns.md- Common responsive layout patterns with CSS examplesreferences/navigation-patterns.md- Hamburger drawer, bottom tab bar, and safe area handling
References
breakpoint-patterns.md
Breakpoint Patterns
Common responsive layout patterns with production-ready CSS. All patterns follow
mobile-first convention: base styles target mobile, min-width queries expand
for larger screens.
Page-level layout patterns
Holy grail (header, sidebar, content, aside, footer)
.page {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-rows: auto 1fr auto;
min-height: 100dvh;
}
@media (min-width: 1024px) {
.page {
grid-template-columns: clamp(200px, 20%, 280px) 1fr clamp(160px, 16%, 240px);
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
}
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main { grid-area: main; }
.page-aside { grid-area: aside; }
.page-footer { grid-area: footer; }Dashboard: sidebar + content
.dashboard {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
.dashboard-sidebar {
width: 100%;
border-bottom: 1px solid #e5e7eb;
}
.dashboard-content {
flex: 1;
padding: 16px;
}
@media (min-width: 1024px) {
.dashboard {
flex-direction: row;
}
.dashboard-sidebar {
width: 256px;
flex-shrink: 0;
height: 100dvh;
position: sticky;
top: 0;
overflow-y: auto;
border-bottom: none;
border-right: 1px solid #e5e7eb;
}
.dashboard-content {
padding: 32px;
overflow-y: auto;
}
}Centered content with max-width
.content-wrapper {
width: 100%;
max-width: 1280px;
margin-inline: auto;
padding-inline: clamp(16px, 4vw, 48px);
}
/* Narrow reading column */
.prose-wrapper {
width: 100%;
max-width: 720px;
margin-inline: auto;
padding-inline: clamp(16px, 4vw, 32px);
}Reading content max-width: 65-75 characters (~720px). App/dashboard: 1280px. Wide/full-bleed sections: no max-width, but pad content inside them.
Component-level patterns
Card: stacked to horizontal
.card-container {
container-type: inline-size;
}
.card {
display: flex;
flex-direction: column;
border-radius: 8px;
overflow: hidden;
border: 1px solid #e5e7eb;
}
.card-media {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
.card-body {
padding: 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
@container (min-width: 480px) {
.card {
flex-direction: row;
}
.card-media {
width: 200px;
aspect-ratio: 1 / 1;
flex-shrink: 0;
}
}
@container (min-width: 640px) {
.card-media {
width: 280px;
}
.card-body {
padding: 24px;
gap: 12px;
}
}Form: stacked to inline labels
.form-group {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 20px;
}
.form-group label {
font-size: 0.875rem;
font-weight: 500;
color: #374151;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 10px 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
font-size: 1rem;
}
@media (min-width: 768px) {
.form-group {
flex-direction: row;
align-items: baseline;
gap: 16px;
}
.form-group label {
width: 160px;
flex-shrink: 0;
text-align: right;
padding-top: 2px;
}
.form-group > *:not(label) {
flex: 1;
}
}Modal: full-screen on mobile, centered on desktop
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
padding: 0;
z-index: 100;
}
.modal {
width: 100%;
max-height: 95dvh;
background: #ffffff;
border-radius: 16px 16px 0 0;
overflow-y: auto;
padding: 24px 16px;
padding-bottom: calc(24px + env(safe-area-inset-bottom));
}
@media (min-width: 640px) {
.modal-overlay {
align-items: center;
padding: 24px;
}
.modal {
width: auto;
min-width: 400px;
max-width: 600px;
max-height: 90dvh;
border-radius: 12px;
padding: 32px;
}
}Table: scrollable wrapper on mobile
.table-container {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
/* Visual cue that content is scrollable */
background:
linear-gradient(to right, #fff 30%, rgba(255,255,255,0)),
linear-gradient(to right, rgba(255,255,255,0), #fff 70%) right,
radial-gradient(farthest-side at 0 50%, rgba(0,0,0,0.12), transparent),
radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,0.12), transparent) right;
background-repeat: no-repeat;
background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
background-attachment: local, local, scroll, scroll;
}
.table {
width: 100%;
min-width: 600px; /* enforce minimum so columns don't collapse */
border-collapse: collapse;
}
.table th,
.table td {
padding: 12px 16px;
text-align: left;
white-space: nowrap;
}The
backgroundscroll-shadow technique provides a visual affordance that the table can be scrolled horizontally, without JavaScript.
Reflow strategies
Priority+ navigation (show/hide items based on space)
Use container queries to progressively show nav items as width grows.
.nav-container {
container-type: inline-size;
}
.nav {
display: flex;
align-items: center;
gap: 4px;
}
/* Hide lower-priority links by default */
.nav-item[data-priority="2"],
.nav-item[data-priority="3"] {
display: none;
}
@container (min-width: 480px) {
.nav-item[data-priority="2"] {
display: flex;
}
}
@container (min-width: 720px) {
.nav-item[data-priority="3"] {
display: flex;
}
}Reverse source order for mobile
When visual order on desktop doesn't match reading/DOM order needed for mobile,
use CSS Grid order property rather than duplicating HTML.
.article-layout {
display: grid;
grid-template-areas:
"image"
"content"
"meta";
}
@media (min-width: 768px) {
.article-layout {
grid-template-columns: 1fr 360px;
grid-template-areas:
"content image"
"meta image";
gap: 32px;
}
}
.article-image { grid-area: image; }
.article-content { grid-area: content; }
.article-meta { grid-area: meta; }Responsive hero with text overlay
.hero {
position: relative;
display: flex;
flex-direction: column;
min-height: clamp(320px, 50vw, 600px);
padding: clamp(32px, 6vw, 96px) clamp(16px, 4vw, 48px);
background-color: #0f172a;
overflow: hidden;
}
.hero-image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.4;
}
.hero-content {
position: relative;
z-index: 1;
max-width: 720px;
}
.hero-title {
font-size: clamp(2rem, 1rem + 5vw, 5rem);
line-height: 1.1;
color: #ffffff;
}
@media (min-width: 768px) {
.hero {
justify-content: center;
min-height: clamp(400px, 60vh, 700px);
}
}Viewport unit reference
| Unit | What it represents | When to use |
|---|---|---|
vw |
1% of viewport width | Fluid font sizes, hero dimensions |
vh |
1% of viewport height | Full-screen sections (use dvh instead) |
dvh |
1% of dynamic viewport height | Full-screen mobile (accounts for browser chrome) |
svh |
1% of small viewport height | Conservative full-screen (never taller than visible) |
lvh |
1% of large viewport height | Full-screen desktop where browser chrome doesn't shift |
cqw |
1% of container query width | Fluid sizing inside @container queries |
cqi |
1% of container inline size | Preferred over cqw for writing-mode independence |
Always prefer
dvhovervhfor full-screen mobile layouts.vhon iOS Safari historically measured the viewport without browser chrome, causing elements to be obscured.dvhupdates dynamically as chrome shows/hides.
Testing checklist
- 320px - minimum supported Android width
- 375px - iPhone SE / standard iPhone width
- 430px - iPhone Pro Max width
- 768px - tablet portrait
- 900px - the "awkward" size many breakpoints miss
- 1024px - tablet landscape / small laptop
- 1280px - standard desktop
- 1440px - large desktop
- Landscape orientation on mobile
- With browser zoom at 150% and 200%
- With OS font size set to "Large" or "Extra Large"
navigation-patterns.md
Responsive Navigation Patterns
Hamburger drawer (mobile) / horizontal nav (desktop)
/* Mobile: hide main nav, show toggle */
.nav-links {
display: none;
position: fixed;
inset: 0;
background: #ffffff;
flex-direction: column;
padding: 80px 24px 24px;
gap: 8px;
z-index: 50;
}
.nav-links.open {
display: flex;
}
.nav-toggle {
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
background: none;
border: none;
cursor: pointer;
}
/* Desktop: inline nav, no toggle */
@media (min-width: 1024px) {
.nav-links {
display: flex;
position: static;
flex-direction: row;
padding: 0;
gap: 4px;
background: transparent;
inset: auto;
z-index: auto;
}
.nav-toggle {
display: none;
}
}Bottom tab bar (mobile app-style)
.bottom-tab-bar {
display: flex;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 56px;
background: #ffffff;
border-top: 1px solid #e5e7eb;
padding-bottom: env(safe-area-inset-bottom);
z-index: 40;
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
min-height: 44px;
color: #6b7280;
font-size: 0.7rem;
font-weight: 500;
text-decoration: none;
}
.tab-item.active { color: #2563eb; }
@media (min-width: 1024px) {
.bottom-tab-bar { display: none; }
}Always use
env(safe-area-inset-bottom)for bottom-fixed elements on iOS. Useenv(safe-area-inset-top)for fixed headers on notched devices.
Frequently Asked Questions
What is responsive-design?
Use this skill when building responsive layouts, implementing fluid typography, using container queries, or defining breakpoint strategies. Triggers on responsive design, mobile-first, media queries, container queries, fluid typography, clamp(), viewport units, grid layout, flexbox patterns, and any task requiring adaptive or responsive web design.
How do I install responsive-design?
Run npx skills add AbsolutelySkilled/AbsolutelySkilled --skill responsive-design in your terminal. The skill will be immediately available in your AI coding agent.
What AI agents support responsive-design?
responsive-design works with claude-code, gemini-cli, openai-codex. Install it once and use it across any supported AI coding agent.