Responsive Design Guidelinesο
Comprehensive guidelines for building responsive, mobile-first applications with Buildly.
Overviewο
Responsive design ensures your application works seamlessly across all devices and screen sizes. This guide covers Buildlyβs responsive design patterns, breakpoints, and best practices.
Design Philosophyο
Mobile-First Approach
Start with mobile design and progressively enhance for larger screens:
Design for smallest screens first
Add complexity as screen size increases
Ensure core functionality works on all devices
Progressive enhancement over graceful degradation
Fluid Layouts
Use percentage-based widths
Flexible grids and containers
Scalable images and media
Relative units (rem, em, %, vw, vh)
Breakpoint Systemο
Standard Breakpointsο
Buildly uses a consistent breakpoint system across frameworks:
const breakpoints = {
xs: '0px', // Extra small: phones (portrait)
sm: '600px', // Small: phones (landscape)
md: '960px', // Medium: tablets
lg: '1280px', // Large: desktops
xl: '1920px', // Extra large: large desktops
};
Usage in CSS:
/* Mobile first - base styles */
.container {
padding: 16px;
font-size: 14px;
}
/* Tablet and up */
@media (min-width: 960px) {
.container {
padding: 24px;
font-size: 16px;
max-width: 1200px;
margin: 0 auto;
}
}
/* Desktop and up */
@media (min-width: 1280px) {
.container {
padding: 32px;
}
}
Material-UI Breakpoints:
import { useTheme, useMediaQuery } from '@mui/material';
function ResponsiveComponent() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const isTablet = useMediaQuery(theme.breakpoints.between('sm', 'md'));
const isDesktop = useMediaQuery(theme.breakpoints.up('lg'));
return (
<Box
sx={{
padding: { xs: 2, sm: 3, md: 4 },
fontSize: { xs: '14px', md: '16px' },
display: { xs: 'block', md: 'flex' },
}}
>
{isMobile && <MobileLayout />}
{isTablet && <TabletLayout />}
{isDesktop && <DesktopLayout />}
</Box>
);
}
Grid Systemsο
Flexible Grid Layoutο
CSS Grid:
.grid-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 24px;
padding: 24px;
}
.grid-item {
grid-column: span 12; /* Full width on mobile */
}
@media (min-width: 960px) {
.grid-item {
grid-column: span 6; /* Half width on tablet */
}
}
@media (min-width: 1280px) {
.grid-item {
grid-column: span 4; /* Third width on desktop */
}
}
Material-UI Grid:
import { Grid, Container } from '@mui/material';
function ResponsiveGrid() {
return (
<Container maxWidth="xl">
<Grid container spacing={3}>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Card>Content 1</Card>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Card>Content 2</Card>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Card>Content 3</Card>
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<Card>Content 4</Card>
</Grid>
</Grid>
</Container>
);
}
Flexbox Patternsο
/* Responsive flex layout */
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.flex-item {
flex: 1 1 100%; /* Stack on mobile */
min-width: 280px;
}
@media (min-width: 960px) {
.flex-item {
flex: 1 1 calc(50% - 16px); /* Two columns on tablet */
}
}
@media (min-width: 1280px) {
.flex-item {
flex: 1 1 calc(33.333% - 16px); /* Three columns on desktop */
}
}
Typographyο
Responsive Font Sizingο
Fluid Typography:
/* Using clamp() for fluid scaling */
h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
line-height: 1.2;
}
h2 {
font-size: clamp(1.25rem, 3vw, 2.5rem);
}
body {
font-size: clamp(0.875rem, 1.5vw, 1rem);
line-height: 1.6;
}
Breakpoint-Based Scaling:
const theme = createTheme({
typography: {
h1: {
fontSize: '2rem',
'@media (min-width:960px)': {
fontSize: '2.5rem',
},
'@media (min-width:1280px)': {
fontSize: '3rem',
},
},
},
});
Images and Mediaο
Responsive Imagesο
HTML Picture Element:
<picture>
<source
media="(min-width: 1280px)"
srcset="image-large.jpg"
/>
<source
media="(min-width: 960px)"
srcset="image-medium.jpg"
/>
<img
src="image-small.jpg"
alt="Responsive image"
loading="lazy"
/>
</picture>
CSS Background Images:
.hero {
background-image: url('hero-small.jpg');
background-size: cover;
background-position: center;
}
@media (min-width: 960px) {
.hero {
background-image: url('hero-medium.jpg');
}
}
@media (min-width: 1280px) {
.hero {
background-image: url('hero-large.jpg');
}
}
React Responsive Images:
function ResponsiveImage({ alt, sizes }) {
return (
<img
src={sizes.default}
srcSet={`
${sizes.small} 600w,
${sizes.medium} 960w,
${sizes.large} 1280w
`}
sizes="(max-width: 600px) 100vw,
(max-width: 960px) 80vw,
1200px"
alt={alt}
loading="lazy"
style={{ width: '100%', height: 'auto' }}
/>
);
}
Tables and Data Displayο
Responsive Tablesο
Scrollable Tables:
import { TableContainer, Paper } from '@mui/material';
function ResponsiveTable() {
return (
<TableContainer
component={Paper}
sx={{
maxWidth: '100%',
overflowX: 'auto',
}}
>
<Table sx={{ minWidth: 650 }}>
{/* Table content */}
</Table>
</TableContainer>
);
}
Card-Based Mobile Layout:
function ResponsiveDataDisplay({ data }) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
if (isMobile) {
return (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
{data.map(item => (
<Card key={item.id}>
<CardContent>
<Typography variant="h6">{item.title}</Typography>
<Typography variant="body2">{item.description}</Typography>
</CardContent>
</Card>
))}
</Box>
);
}
return <DataTable data={data} />;
}
Formsο
Responsive Form Layoutsο
function ResponsiveForm() {
return (
<Box
component="form"
sx={{
display: 'grid',
gridTemplateColumns: {
xs: '1fr',
sm: 'repeat(2, 1fr)',
md: 'repeat(3, 1fr)',
},
gap: 2,
padding: 2,
}}
>
<TextField label="First Name" fullWidth />
<TextField label="Last Name" fullWidth />
<TextField
label="Email"
fullWidth
sx={{ gridColumn: { xs: 'span 1', sm: 'span 2', md: 'span 1' } }}
/>
<TextField
label="Address"
fullWidth
multiline
rows={3}
sx={{ gridColumn: { xs: 'span 1', sm: 'span 2', md: 'span 3' } }}
/>
<Button
variant="contained"
sx={{ gridColumn: { xs: 'span 1', sm: 'span 2', md: 'span 3' } }}
>
Submit
</Button>
</Box>
);
}
Touch Optimizationο
Touch Targetsο
Ensure interactive elements are large enough for touch:
/* Minimum touch target size */
.button,
.link,
.interactive {
min-height: 44px;
min-width: 44px;
padding: 12px 16px;
}
/* Spacing between touch targets */
.button-group button {
margin: 8px;
}
Material-UI Touch Ripple:
<Button
variant="contained"
sx={{
minHeight: 44,
minWidth: 44,
padding: '12px 24px',
}}
TouchRippleProps={{
style: { color: 'rgba(0, 0, 0, 0.3)' }
}}
>
Touch Optimized Button
</Button>
Performance Optimizationο
Viewport Configurationο
<!-- In public/index.html -->
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=5.0"
/>
Lazy Loadingο
import { lazy, Suspense } from 'react';
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
);
}
CSS Optimizationο
/* Use CSS containment for performance */
.card {
contain: layout style paint;
}
/* Hardware acceleration for animations */
.animated {
will-change: transform;
transform: translateZ(0);
}
Testing Responsive Designsο
Browser DevToolsο
Open Chrome DevTools (F12)
Click device toolbar icon (Ctrl+Shift+M)
Test different device presets
Test custom dimensions
Test network throttling
Automated Testingο
// Using Cypress for responsive testing
describe('Responsive Layout', () => {
const sizes = ['iphone-6', 'ipad-2', [1280, 720]];
sizes.forEach(size => {
it(`displays correctly on ${size}`, () => {
if (Cypress._.isArray(size)) {
cy.viewport(size[0], size[1]);
} else {
cy.viewport(size);
}
cy.visit('/');
cy.get('.main-nav').should('be.visible');
cy.screenshot(`${size}-viewport`);
});
});
});
Best Practicesο
β DO:
Start with mobile design
Use relative units (rem, em, %)
Test on real devices
Optimize images for different sizes
Use CSS containment
Implement touch-friendly interactions
Test with slow network speeds
β DONβT:
Use fixed pixel widths
Ignore small screen sizes
Load desktop-sized images on mobile
Make touch targets too small
Use hover-only interactions
Forget about landscape orientation
Assume screen dimensions
Common Patternsο
Dashboard Layoutο
function ResponsiveDashboard() {
return (
<Box sx={{ display: 'flex', flexDirection: { xs: 'column', md: 'row' } }}>
<Sidebar
sx={{
width: { xs: '100%', md: 240 },
borderRight: { xs: 'none', md: '1px solid #e0e0e0' }
}}
/>
<Box sx={{ flex: 1, padding: { xs: 2, md: 3 } }}>
<Grid container spacing={{ xs: 2, md: 3 }}>
<Grid item xs={12} sm={6} lg={3}>
<StatCard />
</Grid>
{/* More grid items */}
</Grid>
</Box>
</Box>
);
}
Resourcesο
Tools:
Chrome DevTools Device Mode
Firefox Responsive Design Mode
BrowserStack for real device testing
Lighthouse for performance auditing
Further Reading:
Frontend Development Guide - Frontend development guide
MDN Responsive Design Guide
Google Web Fundamentals
Video Resources:
Buildly YouTube Channel - Responsive design tutorials and best practices
OpenBuild YouTube Channel - Mobile-first design patterns
Note
Continuously test your responsive designs on real devices and various browsers to ensure the best user experience.