style: format all files with prettier

This commit is contained in:
Seth Hobson
2026-01-19 17:07:03 -05:00
parent 8d37048deb
commit 56848874a2
355 changed files with 15215 additions and 10241 deletions

View File

@@ -21,24 +21,28 @@ Master modern responsive design techniques to create interfaces that adapt seaml
## Core Capabilities
### 1. Container Queries
- Component-level responsiveness independent of viewport
- Container query units (cqi, cqw, cqh)
- Style queries for conditional styling
- Fallbacks for browser support
### 2. Fluid Typography & Spacing
- CSS clamp() for fluid scaling
- Viewport-relative units (vw, vh, dvh)
- Fluid type scales with min/max bounds
- Responsive spacing systems
### 3. Layout Patterns
- CSS Grid for 2D layouts
- Flexbox for 1D distribution
- Intrinsic layouts (content-based sizing)
- Subgrid for nested grid alignment
### 4. Breakpoint Strategy
- Mobile-first media queries
- Content-based breakpoints
- Design token integration
@@ -51,11 +55,21 @@ Master modern responsive design techniques to create interfaces that adapt seaml
```css
/* Mobile-first breakpoints */
/* Base: Mobile (< 640px) */
@media (min-width: 640px) { /* sm: Landscape phones, small tablets */ }
@media (min-width: 768px) { /* md: Tablets */ }
@media (min-width: 1024px) { /* lg: Laptops, small desktops */ }
@media (min-width: 1280px) { /* xl: Desktops */ }
@media (min-width: 1536px) { /* 2xl: Large desktops */ }
@media (min-width: 640px) {
/* sm: Landscape phones, small tablets */
}
@media (min-width: 768px) {
/* md: Tablets */
}
@media (min-width: 1024px) {
/* lg: Laptops, small desktops */
}
@media (min-width: 1280px) {
/* xl: Desktops */
}
@media (min-width: 1536px) {
/* 2xl: Large desktops */
}
/* Tailwind CSS equivalent */
/* sm: @media (min-width: 640px) */
@@ -148,10 +162,18 @@ function ResponsiveCard({ title, image, description }) {
}
/* Usage */
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
p { font-size: var(--text-base); }
h1 {
font-size: var(--text-4xl);
}
h2 {
font-size: var(--text-3xl);
}
h3 {
font-size: var(--text-2xl);
}
p {
font-size: var(--text-base);
}
/* Fluid spacing scale */
:root {
@@ -165,7 +187,12 @@ p { font-size: var(--text-base); }
```tsx
// Utility function for fluid values
function fluidValue(minSize: number, maxSize: number, minWidth = 320, maxWidth = 1280) {
function fluidValue(
minSize: number,
maxSize: number,
minWidth = 320,
maxWidth = 1280,
) {
const slope = (maxSize - minSize) / (maxWidth - minWidth);
const yAxisIntersection = -minWidth * slope + minSize;
@@ -178,7 +205,7 @@ const fluidTypeScale = {
base: fluidValue(1, 1.125),
lg: fluidValue(1.25, 1.5),
xl: fluidValue(1.5, 2),
'2xl': fluidValue(2, 3),
"2xl": fluidValue(2, 3),
};
```
@@ -230,19 +257,23 @@ const fluidTypeScale = {
}
}
.header { grid-area: header; }
.main { grid-area: main; }
.sidebar { grid-area: sidebar; }
.footer { grid-area: footer; }
.header {
grid-area: header;
}
.main {
grid-area: main;
}
.sidebar {
grid-area: sidebar;
}
.footer {
grid-area: footer;
}
```
```tsx
// Responsive grid component
function ResponsiveGrid({
children,
minItemWidth = '250px',
gap = '1.5rem',
}) {
function ResponsiveGrid({ children, minItemWidth = "250px", gap = "1.5rem" }) {
return (
<div
className="grid"
@@ -292,12 +323,12 @@ function ResponsiveNav({ items }) {
id="nav-menu"
className={cn(
// Base: hidden on mobile
'absolute top-full left-0 right-0 bg-background border-b',
'flex flex-col',
"absolute top-full left-0 right-0 bg-background border-b",
"flex flex-col",
// Mobile: slide down
isOpen ? 'flex' : 'hidden',
isOpen ? "flex" : "hidden",
// Desktop: always visible, horizontal
'lg:static lg:flex lg:flex-row lg:border-0 lg:bg-transparent'
"lg:static lg:flex lg:flex-row lg:border-0 lg:bg-transparent",
)}
>
{items.map((item) => (
@@ -305,9 +336,9 @@ function ResponsiveNav({ items }) {
<a
href={item.href}
className={cn(
'block px-4 py-3',
'lg:px-3 lg:py-2',
'hover:bg-muted lg:hover:bg-transparent lg:hover:text-primary'
"block px-4 py-3",
"lg:px-3 lg:py-2",
"hover:bg-muted lg:hover:bg-transparent lg:hover:text-primary",
)}
>
{item.label}

View File

@@ -52,11 +52,21 @@ Start with the smallest screen, then progressively enhance for larger screens.
/* xl: 1280px - Desktops */
/* 2xl: 1536px - Large desktops */
@media (min-width: 640px) { /* sm */ }
@media (min-width: 768px) { /* md */ }
@media (min-width: 1024px) { /* lg */ }
@media (min-width: 1280px) { /* xl */ }
@media (min-width: 1536px) { /* 2xl */ }
@media (min-width: 640px) {
/* sm */
}
@media (min-width: 768px) {
/* md */
}
@media (min-width: 1024px) {
/* lg */
}
@media (min-width: 1280px) {
/* xl */
}
@media (min-width: 1536px) {
/* 2xl */
}
```
### Bootstrap 5
@@ -69,11 +79,21 @@ Start with the smallest screen, then progressively enhance for larger screens.
/* xl: 1200px */
/* xxl: 1400px */
@media (min-width: 576px) { /* sm */ }
@media (min-width: 768px) { /* md */ }
@media (min-width: 992px) { /* lg */ }
@media (min-width: 1200px) { /* xl */ }
@media (min-width: 1400px) { /* xxl */ }
@media (min-width: 576px) {
/* sm */
}
@media (min-width: 768px) {
/* md */
}
@media (min-width: 992px) {
/* lg */
}
@media (min-width: 1200px) {
/* xl */
}
@media (min-width: 1400px) {
/* xxl */
}
```
### Minimalist Scale
@@ -89,8 +109,12 @@ Start with the smallest screen, then progressively enhance for larger screens.
--bp-lg: 1024px;
}
@media (min-width: 600px) { /* Medium */ }
@media (min-width: 1024px) { /* Large */ }
@media (min-width: 600px) {
/* Medium */
}
@media (min-width: 1024px) {
/* Large */
}
```
## Content-Based Breakpoints
@@ -101,7 +125,9 @@ Instead of using device-based breakpoints, identify where your content naturally
```css
/* Bad: Device-based thinking */
@media (min-width: 768px) { /* iPad breakpoint */ }
@media (min-width: 768px) {
/* iPad breakpoint */
}
/* Good: Content-based thinking */
/* Breakpoint where sidebar fits comfortably next to content */
@@ -133,7 +159,7 @@ function findBreakpoints(selector) {
// Check for overflow, wrapping, or layout issues
if (element.scrollWidth > element.clientWidth) {
breakpoints.push({ width, issue: 'overflow' });
breakpoints.push({ width, issue: "overflow" });
}
}
@@ -179,7 +205,7 @@ export const breakpoints = {
md: 768,
lg: 1024,
xl: 1280,
'2xl': 1536,
"2xl": 1536,
} as const;
// Media query hook
@@ -191,8 +217,8 @@ function useMediaQuery(query: string): boolean {
setMatches(media.matches);
const listener = () => setMatches(media.matches);
media.addEventListener('change', listener);
return () => media.removeEventListener('change', listener);
media.addEventListener("change", listener);
return () => media.removeEventListener("change", listener);
}, [query]);
return matches;
@@ -209,7 +235,15 @@ function useBreakpoint() {
isMobile: !isSmall,
isTablet: isSmall && !isLarge,
isDesktop: isLarge,
current: isXLarge ? 'xl' : isLarge ? 'lg' : isMedium ? 'md' : isSmall ? 'sm' : 'base',
current: isXLarge
? "xl"
: isLarge
? "lg"
: isMedium
? "md"
: isSmall
? "sm"
: "base",
};
}
```
@@ -444,11 +478,14 @@ function useBreakpoint() {
}
/* Handle page breaks */
h1, h2, h3 {
h1,
h2,
h3 {
page-break-after: avoid;
}
img, table {
img,
table {
page-break-inside: avoid;
}
@@ -519,13 +556,16 @@ async function testBreakpoints(page, breakpoints) {
// Check for horizontal overflow
const hasOverflow = await page.evaluate(() => {
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
return (
document.documentElement.scrollWidth >
document.documentElement.clientWidth
);
});
// Check for elements going off-screen
const offscreenElements = await page.evaluate(() => {
const elements = document.querySelectorAll('*');
return Array.from(elements).filter(el => {
const elements = document.querySelectorAll("*");
return Array.from(elements).filter((el) => {
const rect = el.getBoundingClientRect();
return rect.right > window.innerWidth || rect.left < 0;
}).length;

View File

@@ -63,22 +63,30 @@ Container queries have excellent modern browser support (Chrome 105+, Firefox 11
/* Minimum width */
@container (min-width: 300px) {
.element { /* styles */ }
.element {
/* styles */
}
}
/* Maximum width */
@container (max-width: 500px) {
.element { /* styles */ }
.element {
/* styles */
}
}
/* Range syntax */
@container (300px <= width <= 600px) {
.element { /* styles */ }
.element {
/* styles */
}
}
/* Exact width */
@container (width: 400px) {
.element { /* styles */ }
.element {
/* styles */
}
}
```
@@ -87,17 +95,23 @@ Container queries have excellent modern browser support (Chrome 105+, Firefox 11
```css
/* AND condition */
@container (min-width: 400px) and (max-width: 800px) {
.element { /* styles */ }
.element {
/* styles */
}
}
/* OR condition */
@container (max-width: 300px) or (min-width: 800px) {
.element { /* styles */ }
.element {
/* styles */
}
}
/* NOT condition */
@container not (min-width: 400px) {
.element { /* styles */ }
.element {
/* styles */
}
}
```
@@ -403,9 +417,7 @@ Style queries allow querying CSS custom property values. Currently limited suppo
// Tailwind v3.2+ supports container queries
// tailwind.config.js
module.exports = {
plugins: [
require('@tailwindcss/container-queries'),
],
plugins: [require("@tailwindcss/container-queries")],
};
// Component usage
@@ -437,13 +449,9 @@ function Dashboard() {
return (
<div className="@container/main">
<aside className="@container/sidebar">
<nav className="flex flex-col @lg/sidebar:flex-row">
{/* ... */}
</nav>
<nav className="flex flex-col @lg/sidebar:flex-row">{/* ... */}</nav>
</aside>
<main className="@lg/main:grid @lg/main:grid-cols-2">
{/* ... */}
</main>
<main className="@lg/main:grid @lg/main:grid-cols-2">{/* ... */}</main>
</div>
);
}
@@ -506,10 +514,18 @@ function Dashboard() {
```css
/* Avoid over-nesting containers */
/* Bad: Too many nested containers */
.level-1 { container-type: inline-size; }
.level-2 { container-type: inline-size; }
.level-3 { container-type: inline-size; }
.level-4 { container-type: inline-size; }
.level-1 {
container-type: inline-size;
}
.level-2 {
container-type: inline-size;
}
.level-3 {
container-type: inline-size;
}
.level-4 {
container-type: inline-size;
}
/* Good: Strategic container placement */
.component-wrapper {
@@ -528,16 +544,16 @@ function Dashboard() {
```javascript
// Test container query support
const supportsContainerQueries = CSS.supports('container-type', 'inline-size');
const supportsContainerQueries = CSS.supports("container-type", "inline-size");
// Resize observer for testing
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
console.log('Container width:', entry.contentRect.width);
console.log("Container width:", entry.contentRect.width);
}
});
observer.observe(document.querySelector('.container'));
observer.observe(document.querySelector(".container"));
```
## Resources

View File

@@ -61,9 +61,9 @@ const typeScale = {
base: fluidType({ minFontSize: 16, maxFontSize: 18 }),
lg: fluidType({ minFontSize: 18, maxFontSize: 20 }),
xl: fluidType({ minFontSize: 20, maxFontSize: 24 }),
'2xl': fluidType({ minFontSize: 24, maxFontSize: 32 }),
'3xl': fluidType({ minFontSize: 30, maxFontSize: 48 }),
'4xl': fluidType({ minFontSize: 36, maxFontSize: 60 }),
"2xl": fluidType({ minFontSize: 24, maxFontSize: 32 }),
"3xl": fluidType({ minFontSize: 30, maxFontSize: 48 }),
"4xl": fluidType({ minFontSize: 36, maxFontSize: 60 }),
};
```
@@ -98,14 +98,34 @@ body {
line-height: var(--leading-normal);
}
h1 { font-size: var(--text-4xl); line-height: var(--leading-tight); }
h2 { font-size: var(--text-3xl); line-height: var(--leading-tight); }
h3 { font-size: var(--text-2xl); line-height: var(--leading-tight); }
h4 { font-size: var(--text-xl); line-height: var(--leading-normal); }
h5 { font-size: var(--text-lg); line-height: var(--leading-normal); }
h6 { font-size: var(--text-base); line-height: var(--leading-normal); }
h1 {
font-size: var(--text-4xl);
line-height: var(--leading-tight);
}
h2 {
font-size: var(--text-3xl);
line-height: var(--leading-tight);
}
h3 {
font-size: var(--text-2xl);
line-height: var(--leading-tight);
}
h4 {
font-size: var(--text-xl);
line-height: var(--leading-normal);
}
h5 {
font-size: var(--text-lg);
line-height: var(--leading-normal);
}
h6 {
font-size: var(--text-base);
line-height: var(--leading-normal);
}
small { font-size: var(--text-sm); }
small {
font-size: var(--text-sm);
}
```
## Fluid Spacing
@@ -184,10 +204,7 @@ small { font-size: var(--text-sm); }
/* Grid that fills available space */
.auto-grid {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(100%, 250px), 1fr)
);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
gap: var(--space-md);
}
@@ -338,8 +355,8 @@ small { font-size: var(--text-sm); }
}
/* Limit columns */
.switcher > :nth-last-child(n+4),
.switcher > :nth-last-child(n+4) ~ * {
.switcher > :nth-last-child(n + 4),
.switcher > :nth-last-child(n + 4) ~ * {
flex-basis: 100%;
}
```
@@ -405,10 +422,7 @@ small { font-size: var(--text-sm); }
.card-grid {
/* Each card at least 200px, fill available space */
grid-template-columns: repeat(
auto-fit,
minmax(max(200px, 100%/4), 1fr)
);
grid-template-columns: repeat(auto-fit, minmax(max(200px, 100%/4), 1fr));
}
```
@@ -473,21 +487,47 @@ small { font-size: var(--text-sm); }
```css
/* Tailwind-style fluid utilities */
.text-fluid-sm { font-size: var(--text-sm); }
.text-fluid-base { font-size: var(--text-base); }
.text-fluid-lg { font-size: var(--text-lg); }
.text-fluid-xl { font-size: var(--text-xl); }
.text-fluid-2xl { font-size: var(--text-2xl); }
.text-fluid-3xl { font-size: var(--text-3xl); }
.text-fluid-4xl { font-size: var(--text-4xl); }
.text-fluid-sm {
font-size: var(--text-sm);
}
.text-fluid-base {
font-size: var(--text-base);
}
.text-fluid-lg {
font-size: var(--text-lg);
}
.text-fluid-xl {
font-size: var(--text-xl);
}
.text-fluid-2xl {
font-size: var(--text-2xl);
}
.text-fluid-3xl {
font-size: var(--text-3xl);
}
.text-fluid-4xl {
font-size: var(--text-4xl);
}
.p-fluid-sm { padding: var(--space-sm); }
.p-fluid-md { padding: var(--space-md); }
.p-fluid-lg { padding: var(--space-lg); }
.p-fluid-sm {
padding: var(--space-sm);
}
.p-fluid-md {
padding: var(--space-md);
}
.p-fluid-lg {
padding: var(--space-lg);
}
.gap-fluid-sm { gap: var(--space-sm); }
.gap-fluid-md { gap: var(--space-md); }
.gap-fluid-lg { gap: var(--space-lg); }
.gap-fluid-sm {
gap: var(--space-sm);
}
.gap-fluid-md {
gap: var(--space-md);
}
.gap-fluid-lg {
gap: var(--space-lg);
}
```
## Resources