Responsive Design
supercent-io/skills-templateThis skill provides guidance on creating responsive web layouts that adapt seamlessly across mobile, tablet, and desktop screens. It covers best practices such as mobile-first design, flexible layouts using Flexbox and CSS Grid, responsive images and typography, and the use of container queries. Ideal for developers seeking to optimize site performance, accessibility, and visual consistency across diverse devices.
Responsive Design
When to use this skill
- New website/app: Layout design for combined mobile-desktop use
- Legacy improvement: Converting fixed layouts to responsive
- Performance optimization: Image optimization per device
- Multiple screens: Tablet, desktop, and large screen support
Instructions
Step 1: Mobile-First Approach
Design from small screens and progressively expand. Example:
/* Default: Mobile (320px~) */
.container {
padding: 1rem;
font-size: 14px;
}
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
/* Tablet (768px~) */
@media (min-width: 768px) {
.container {
padding: 2rem;
font-size: 16px;
}
.grid {
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
}
}
/* Desktop (1024px~) */
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
padding: 3rem;
}
.grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}
/* Large screen (1440px~) */
@media (min-width: 1440px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
Step 2: Flexbox/Grid Layout
Leverage modern CSS layout systems. Flexbox (1-dimensional layout):
/* Navigation bar */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
/* Card list */
.card-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
@media (min-width: 768px) {
.card-list {
flex-direction: row;
flex-wrap: wrap;
}
.card {
flex: 1 1 calc(50% - 0.5rem); /* 2 columns */
}
}
@media (min-width: 1024px) {
.card {
flex: 1 1 calc(33.333% - 0.667rem); /* 3 columns */
}
}
CSS Grid (2-dimensional layout):
/* Dashboard layout */
.dashboard {
display: grid;
grid-template-areas:
"header"
"sidebar"
"main"
"footer";
gap: 1rem;
}
@media (min-width: 768px) {
.dashboard {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
}
}
@media (min-width: 1024px) {
.dashboard {
grid-template-columns: 300px 1fr;
}
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Step 3: Responsive Images
Provide images suited to the device. Using srcset:
<img
src="image-800.jpg"
srcset="
image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w,
image-1600.jpg 1600w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 900px) 50vw,
33vw
"
alt="Responsive image"
/>
picture element (Art Direction):
<picture>
<!-- Mobile: portrait image -->
<source media="(max-width: 767px)" srcset="portrait.jpg">
<!-- Tablet: square image -->
<source media="(max-width: 1023px)" srcset="square.jpg">
<!-- Desktop: landscape image -->
<img src="landscape.jpg" alt="Art direction example">
</picture>
CSS background images:
.hero {
background-image: url('hero-mobile.jpg');
}
@media (min-width: 768px) {
.hero {
background-image: url('hero-tablet.jpg');
}
}
@media (min-width: 1024px) {
.hero {
background-image: url('hero-desktop.jpg');
}
}
/* Or use image-set() */
.hero {
background-image: image-set(
url('hero-1x.jpg') 1x,
url('hero-2x.jpg') 2x
);
}
Step 4: Responsive Typography
Adjust text size based on screen size. clamp() function (fluid sizing):
:root {
/* min, preferred, max */
--font-size-body: clamp(14px, 2.5vw, 18px);
--font-size-h1: clamp(24px, 5vw, 48px);
--font-size-h2: clamp(20px, 4vw, 36px);
}
body {
font-size: var(--font-size-body);
}
h1 {
font-size: var(--font-size-h1);
line-height: 1.2;
}
h2 {
font-size: var(--font-size-h2);
line-height: 1.3;
}
Media query approach:
body {
font-size: 14px;
line-height: 1.6;
}
@media (min-width: 768px) {
body { font-size: 16px; }
}
@media (min-width: 1024px) {
body { font-size: 18px; }
}
Step 5: Container Queries (New Feature)
Apply styles based on parent container size.
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
padding: 1rem;
}
.card h2 {
font-size: 1.2rem;
}
/* When container is 400px or wider */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
padding: 1.5rem;
}
.card h2 {
font-size: 1.5rem;
}
}
/* When container is 600px or wider */
@container card (min-width: 600px) {
.card {
grid-template-columns: 300px 1fr;
padding: 2rem;
}
}
Output format
Standard Breakpoints
/* Mobile (default): 320px ~ 767px */
/* Tablet: 768px ~ 1023px */
/* Desktop: 1024px ~ 1439px */
/* Large: 1440px+ */
:root {
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px;
}
/* Usage example */
@media (min-width: 768px) { /* Tablet */ }
@media (min-width: 1024px) { /* Desktop */ }
Constraints
Mandatory Rules (MUST)
- Viewport meta tag: Must be included in HTML
<meta name="viewport" content="width=device-width, initial-scale=1.0"> - Mobile-First: Mobile default, use min-width media queries
- ✅
@media (min-width: 768px) - ❌
@media (max-width: 767px)(Desktop-first)
- ✅
- Relative units: Use rem, em, %, vw/vh instead of px
- font-size: rem
- padding/margin: rem or em
- width: % or vw
Prohibited (MUST NOT)
- Fixed width prohibited: Avoid
width: 1200px- Use
max-width: 1200px
- Use
- Duplicate code: Avoid repeating same styles across all breakpoints
- Common styles as default, only differences in media queries
Examples
Example 1: Responsive Navigation
function ResponsiveNav() {
const [isOpen, setIsOpen] = useState(false);
return (
<nav className="navbar">
{/* Logo */}
<a href="/" className="logo">MyApp</a>
{/* Hamburger button (mobile) */}
<button
className="menu-toggle"
onClick={() => setIsOpen(!isOpen)}
aria-label="Toggle menu"
aria-expanded={isOpen}
>
<span></span>
<span></span>
<span></span>
</button>
{/* Navigation links */}
<ul className={`nav-links ${isOpen ? 'active' : ''}`}>
<li><a href="/about">About</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
);
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
/* Hamburger button (mobile only) */
.menu-toggle {
display: flex;
flex-direction: column;
gap: 4px;
}
.nav-links {
display: none;
position: absolute;
top: 60px;
left: 0;
right: 0;
background: white;
flex-direction: column;
}
.nav-links.active {
display: flex;
}
/* Tablet and above: hide hamburger, always show */
@media (min-width: 768px) {
.menu-toggle {
display: none;
}
.nav-links {
display: flex;
position: static;
flex-direction: row;
gap: 2rem;
}
}
Example 2: Responsive Grid Card
function ProductGrid({ products }) {
return (
<div className="product-grid">
{products.map(product => (
<div key={product.id} className="product-card">
<img src={product.image} alt={product.name} />
<h3>{product.name}</h3>
<p className="price">${product.price}</p>
<button>Add to Cart</button>
</div>
))}
</div>
);
}
.product-grid {
display: grid;
grid-template-columns: 1fr; /* Mobile: 1 column */
gap: 1rem;
padding: 1rem;
}
@media (min-width: 640px) {
.product-grid {
grid-template-columns: repeat(2, 1fr); /* 2 columns */
}
}
@media (min-width: 1024px) {
.product-grid {
grid-template-columns: repeat(3, 1fr); /* 3 columns */
gap: 1.5rem;
}
}
@media (min-width: 1440px) {
.product-grid {
grid-template-columns: repeat(4, 1fr); /* 4 columns */
gap: 2rem;
}
}
.product-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
}
.product-card img {
width: 100%;
height: auto;
aspect-ratio: 1 / 1;
object-fit: cover;
}
Best practices
- Container queries first: Use container queries instead of media queries when possible
- Flexbox vs Grid: Flexbox for 1-dimensional, Grid for 2-dimensional
- Performance: Image lazy loading, use WebP format
- Testing: Chrome DevTools Device Mode, BrowserStack
References
Metadata
Version
- Current Version: 1.0.0
- Last Updated: 2025-01-01
- Compatible Platforms: Claude, ChatGPT, Gemini
Related Skills
- ui-component-patterns: Responsive components
- web-accessibility: Consider alongside accessibility
Tags
#responsive #mobile-first #CSS #Flexbox #Grid #media-query #frontend
GitHub Owner
Owner: supercent-io