算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
frontend-responsive-design【设计与创意】Use this skill when the user says 'responsive design', 'container queries', 'breakpoints', 'mobile-first', 'fluid typography', 'responsive layout', 'media queries', 'clamp', 'adaptive design', or when building responsive frontend UIs. This skill enforces: mobile-first CSS, container queries for component-level responsiveness, a consistent breakpoint …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Build mobile-first responsive UIs with container queries, consistent breakpoints, fluid typography, and no horizontal overflow.
Exact user phrases: "responsive design", "container queries", "breakpoints", "mobile-first", "fluid typography", "responsive layout", "media queries", "clamp", "adaptive design".
Before activating, verify:
No file output. Produces responsive CSS, layout code, or breakpoint config as text.
Pattern: {name}
Breakpoint: {value}
CSS: {code block}
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
clamp() — no fixed font sizes.4096 tokens.
Page-level layout or component-level?
|-- Page-level (header, main grid, footer) -->
| Viewport media queries are appropriate
| Use standard breakpoints (640/768/1024/1280)
| Mobile-first: base = mobile, expand via min-width
|
|-- Component-level (card, sidebar, widget) -->
| Container queries preferred (container-type: inline-size)
| Component responds to its own container, not the viewport
| Fallback: viewport media queries for older browsers
|
|-- Typography -->
Fluid: clamp() with viewport-relative preferred value
Scale: --text-sm to --text-2xl as fluid values
How many unique layouts?
|-- 2 (mobile + desktop) -->
| Single breakpoint: 768px
| Simple, manageable, fewer edge cases
|
|-- 3 (mobile + tablet + desktop) -->
| Breakpoints: 640px + 1024px
| Balance between specificity and complexity
|
|-- 4+ (fine-grained responsive) -->
| Breakpoints: 640px + 768px + 1024px + 1280px
| Use CSS custom properties: --bp-sm, --bp-md, etc.
|
|-- Component-level -->
Container queries with breakpoints at 300px, 400px, 600px
These are container-relative, not viewport-relative
Number of columns needed?
|-- Fixed (2 columns on mobile, 3 on desktop) -->
| CSS Grid with media queries or container queries
| grid-template-columns: 1fr 1fr (mobile) → 1fr 1fr 1fr (desktop)
|
|-- Fluid (automatic columns based on available space) -->
| CSS Grid with auto-fill + minmax
| grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr))
|
|-- Sidebar + content -->
| |-- Mobile: stack vertically (sidebar on top)
| |-- Desktop: grid with sidebar-fixed + content-fluid
/* Mobile first — base styles target mobile */
.card {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1rem;
}
/* Then expand for larger screens */
@media (min-width: 768px) {
.card {
flex-direction: row;
padding: 1.5rem;
}
}
/* Define once, use everywhere */
:root {
--bp-sm: 640px;
--bp-md: 768px;
--bp-lg: 1024px;
--bp-xl: 1280px;
}
/* Usage with Tailwind-like approach */
@media (min-width: 640px) { /* sm */ }
@media (min-width: 768px) { /* md */ }
@media (min-width: 1024px) { /* lg */ }
@media (min-width: 1280px) { /* xl */ }
/* Define container */
.card-container {
container-type: inline-size;
container-name: card;
}
/* Query based on container width, not viewport */
@container card (min-width: 400px) {
.card {
flex-direction: row;
}
}
@container card (min-width: 600px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
/* clamp(min, preferred, max) */
h1 {
font-size: clamp(1.5rem, 4vw + 1rem, 3rem);
line-height: 1.1;
}
p {
font-size: clamp(0.875rem, 1vw + 0.75rem, 1.125rem);
line-height: 1.6;
}
/* Fluid type scale */
--text-sm: clamp(0.75rem, 0.5vw + 0.625rem, 0.875rem);
--text-base: clamp(0.875rem, 1vw + 0.75rem, 1.125rem);
--text-lg: clamp(1rem, 1.5vw + 0.75rem, 1.375rem);
--text-xl: clamp(1.25rem, 2vw + 0.75rem, 1.75rem);
--text-2xl: clamp(1.5rem, 3vw + 0.75rem, 2.25rem);
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
gap: 1rem;
}
/* Or with container query */
@container (min-width: 300px) {
.grid {
grid-template-columns: 1fr 1fr;
}
}
@container (min-width: 600px) {
.grid {
grid-template-columns: 1fr 1fr 1fr;
}
}
/* Minimum touch target size */
button, a, input, select {
min-height: 44px;
min-width: 44px;
}
/* Adequate spacing between touch targets */
.toolbar {
display: flex;
gap: 12px; /* at least 8px gap between targets */
}
/* Mobile: hamburger menu */
.nav-links {
display: none; /* hidden on mobile */
}
.nav-toggle:checked + .nav-links {
display: flex; /* shown when toggled */
flex-direction: column;
}
/* Desktop: horizontal nav */
@media (min-width: 768px) {
.nav-links {
display: flex;
flex-direction: row;
gap: 1rem;
}
.nav-toggle {
display: none; /* hide hamburger on desktop */
}
}
<!-- Responsive image with srcset -->
<img
src="photo-640.jpg"
srcset="
photo-640.jpg 640w,
photo-768.jpg 768w,
photo-1024.jpg 1024w,
photo-1280.jpg 1280w
"
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
alt="Description"
style="max-width: 100%; height: auto;"
/>
/* BAD -- desktop-first: base = desktop, then override for mobile */
.card { flex-direction: row; }
@media (max-width: 767px) { .card { flex-direction: column; } }
/* GOOD -- mobile-first: base = mobile, then expand */
.card { flex-direction: column; }
@media (min-width: 768px) { .card { flex-direction: row; } }
Using @media (max-width: 850px) or @media (min-width: 900px) creates inconsistencies. Always use a predefined breakpoint system.
A Card component should respond to its container, not the viewport. A card in a narrow sidebar and a card in a wide main area should use the same breakpoint values — which is only possible with container queries.
/* BAD -- text too large on mobile, too small on 4K */
font-size: 16px;
/* GOOD -- fluid typography scales naturally */
font-size: clamp(0.875rem, 1vw + 0.75rem, 1.125rem);
Mobile users need touch-friendly navigation. Hamburger menus, bottom nav bars, or collapsible sections are essential.
| Approach | Responsiveness | Browser Support | Component-Level | Complexity |
|---|---|---|---|---|
| Viewport media queries | Page-level | 100% | No | Low |
| Container queries | Component-level | ~90% | Yes | Medium |
| CSS Grid auto-fill | Layout-level | 98% | Yes | Low |
| Flexbox wrap | Simple layout | 100% | Yes | Low |
| Tailwind responsive | Utility-level | 100% | No | Low |
contain: layout style to limit scopeclamp() is evaluated once per render and has no runtime overheadauto-fill/minmax is highly optimized in modern browsersResizeObserver-based responsive JS — prefer native container queriesmin-width media queries.clamp() with viewport-relative preferred value, never fixed px.overflow-x: hidden on body, use min-width: 0 on flex children.max-width: 100%; height: auto on all images by default.rem for padding/margin, not px.No artifact produced.
Next skill: tailwind-css — implement breakpoints via Tailwind utility classes.
Carry forward: breakpoint values, container query approach, fluid type scale.
import { ReactNode } from 'react';
type Breakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl';
interface ResponsiveProps {
children: ReactNode;
/** Hide below this breakpoint */
hideBelow?: Breakpoint;
/** Hide above this breakpoint */
hideAbove?: Breakpoint;
/** Tailwind class overrides */
className?: string;
}
const BREAKPOINTS: Record<Breakpoint, string> = {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px',
};
export function Responsive({ children, hideBelow, hideAbove, className }: ResponsiveProps) {
const classes = [];
if (hideBelow) {
classes.push(`hidden ${hideBelow}:block`);
}
if (hideAbove) {
const nextBreakpoint = getNextBreakpoint(hideAbove);
if (nextBreakpoint) {
classes.push(`${nextBreakpoint}:hidden`);
} else {
classes.push('hidden');
}
}
return (
<div className={[...classes, className].filter(Boolean).join(' ')}>
{children}
</div>
);
}
function getNextBreakpoint(bp: Breakpoint): Breakpoint | null {
const order: Breakpoint[] = ['sm', 'md', 'lg', 'xl', '2xl'];
const idx = order.indexOf(bp);
if (idx >= 0 && idx < order.length - 1) return order[idx + 1];
return null;
}
/* Fluid type scale using clamp() */
:root {
/*
* Formula: clamp(min, preferred, max)
* Preferred: (minSize / viewportWidth * 100) for responsive scaling
*/
--text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
--text-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
--text-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
--text-lg: clamp(1.125rem, 1rem + 0.625vw, 1.25rem);
--text-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem);
--text-2xl: clamp(1.5rem, 1.25rem + 1.25vw, 2rem);
--text-3xl: clamp(1.875rem, 1.5rem + 1.875vw, 2.5rem);
--text-4xl: clamp(2.25rem, 1.75rem + 2.5vw, 3rem);
}
/* Usage */
body {
font-size: var(--text-base);
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
/* Card component with container queries */
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
.card-image {
width: 100%;
height: auto;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
.card-image {
width: 100%;
max-height: 200px;
object-fit: cover;
}
}
What's the layout requirement?
├── Page-level layout (sidebar, header, main)
│ └── Viewport media queries
│ ├── min-width for mobile-first breakpoints
│ └── Global layout changes (sidebar collapse, header resize)
│
├── Component-level layout (card, list, grid)
│ └── Container queries
│ ├── Component responds to its own container width
│ ├── No dependency on viewport for reusable components
│ └── Ideal for design system components
│
├── Typography and spacing
│ └── Fluid scaling with clamp()
│ ├── Linear scaling between min and max viewport
│ ├── No breakpoint jumps for text size
│ └── Rem-based spacing with fluid base
│
└── Images and media
└── Responsive images with srcset/sizes
├── Browser picks optimal resolution
├── Art direction with <picture> element
└── WebP with AVIF fallback
| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Desktop-first media queries | More CSS overrides, harder to maintain | Mobile-first with min-width queries |
| Fixed pixel values for everything | Doesn't scale with user font preferences | rem/em for spacing and typography |
| Only viewport media queries | Components don't adapt to their container | Container queries for reusable components |
| Too many breakpoints | Fragile, hard to test, maintenance burden | 5-6 breakpoints max, system-defined |
| Horizontal overflow on small screens | Content extends beyond viewport | overflow-x: hidden; min-width: 0 on flex items |
| Images without max-width | Images overflow their container | max-width: 100%; height: auto on all images |
contain: layout style paint on independent components. Prevents style recalculation outside the container. Improves rendering performance for large component trees.window.matchMedia in JS or <picture> element for responsive images. Reduce data transfer by 40% on mobile.