AnimeThemes Web is designed to work seamlessly across mobile, tablet, and desktop devices using responsive design patterns and media queries.
Breakpoints
The theme defines five standard breakpoints:
breakpoints : {
mobileMax : "720px" ,
tabletMin : "721px" ,
tabletMax : "870px" ,
desktopMin : "871px" ,
socialListMax : "1225px" ,
}
Breakpoint Strategy
Using Theme Breakpoints
Always reference theme breakpoints rather than hardcoding pixel values:
import styled from "styled-components" ;
const Container = styled . div `
padding: 24px;
@media (max-width: ${ ( props ) => props . theme . breakpoints . mobileMax } ) {
padding: 12px;
}
@media (min-width: ${ ( props ) => props . theme . breakpoints . desktopMin } ) {
padding: 32px;
}
` ;
Mobile-First Approach
Write styles for mobile devices first, then add media queries for larger screens:
const Grid = styled . div `
/* Mobile: single column */
display: grid;
grid-template-columns: 1fr;
gap: 16px;
/* Tablet: two columns */
@media (min-width: ${ ( props ) => props . theme . breakpoints . tabletMin } ) {
grid-template-columns: repeat(2, 1fr);
}
/* Desktop: three columns */
@media (min-width: ${ ( props ) => props . theme . breakpoints . desktopMin } ) {
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
` ;
The useMediaQuery hook provides a React-friendly way to respond to media queries:
src/hooks/useMediaQuery.ts
import useMediaQuery from "@/hooks/useMediaQuery" ;
import theme from "@/theme" ;
function ResponsiveComponent () {
const isMobile = useMediaQuery (
`(max-width: ${ theme . breakpoints . mobileMax } )` ,
false
);
return (
< div >
{ isMobile ? (
< MobileNavigation />
) : (
< DesktopNavigation />
)}
</ div >
);
}
Hook Signature
The media query string to match (e.g., "(max-width: 720px)")
The initial matching state for server-side rendering
Returns true if the media query matches, false otherwise
Real-World Example
From the IconTextButton component:
src/components/button/IconTextButton.tsx
import useMediaQuery from "@/hooks/useMediaQuery" ;
import theme from "@/theme" ;
export function IconTextButton ({ icon , children }) {
const showTextOnMobile = useMediaQuery (
`(max-width: ${ theme . breakpoints . mobileMax } )` ,
false
);
return (
< Button >
< Icon icon = { icon } />
{! showTextOnMobile && < span >{ children }</ span >}
</ Button >
);
}
Common Responsive Patterns
Responsive Navigation
Hide text labels on mobile, show on desktop:
const NavItem = styled . a `
display: flex;
align-items: center;
gap: 8px;
span {
display: none;
@media (min-width: ${ ( props ) => props . theme . breakpoints . tabletMin } ) {
display: inline;
}
}
` ;
Responsive Grid Layouts
Adapt column count based on screen size:
const CardGrid = styled . div `
display: grid;
gap: 16px;
/* Mobile: 1 column */
grid-template-columns: 1fr;
/* Tablet: 2 columns */
@media (min-width: ${ ( props ) => props . theme . breakpoints . tabletMin } ) and
(max-width: ${ ( props ) => props . theme . breakpoints . tabletMax } ) {
grid-template-columns: repeat(2, 1fr);
}
/* Desktop: 4 columns */
@media (min-width: ${ ( props ) => props . theme . breakpoints . desktopMin } ) {
grid-template-columns: repeat(4, 1fr);
}
` ;
Responsive Typography
const Heading = styled . h1 `
font-size: 24px;
line-height: 1.2;
@media (min-width: ${ ( props ) => props . theme . breakpoints . tabletMin } ) {
font-size: 32px;
}
@media (min-width: ${ ( props ) => props . theme . breakpoints . desktopMin } ) {
font-size: 40px;
}
` ;
Responsive Spacing
Use CSS custom properties for responsive spacing:
const Container = styled . div `
padding: var(--padding, 16px);
@media (max-width: ${ ( props ) => props . theme . breakpoints . mobileMax } ) {
--padding: 12px;
}
@media (min-width: ${ ( props ) => props . theme . breakpoints . desktopMin } ) {
--padding: 24px;
}
` ;
Server-Side Rendering Considerations
Initial State
When using useMediaQuery, provide an initial state for SSR:
const isMobile = useMediaQuery (
`(max-width: ${ theme . breakpoints . mobileMax } )` ,
false // Initial state for SSR
);
The initial state is used during server-side rendering. The hook will update to the correct value after client-side hydration. This may cause a brief flash of content.
Avoiding Hydration Mismatches
For critical layout differences, prefer CSS media queries over useMediaQuery to avoid hydration mismatches:
// Preferred for layout
const Layout = styled . div `
@media (max-width: ${ ( props ) => props . theme . breakpoints . mobileMax } ) {
flex-direction: column;
}
` ;
// Use useMediaQuery for content differences
function Component () {
const isMobile = useMediaQuery ( `(max-width: ${ theme . breakpoints . mobileMax } )` );
return isMobile ? < MobileContent /> : < DesktopContent />;
}
Testing Responsive Design
Open browser DevTools (F12)
Toggle device toolbar (Ctrl+Shift+M / Cmd+Shift+M)
Test at different viewport sizes
Check the defined breakpoints: 720px, 870px, 1225px
Common Test Sizes
Device Width Breakpoint Mobile (Portrait) 375px Mobile Mobile (Landscape) 667px Mobile Tablet (Portrait) 768px Tablet Tablet (Landscape) 1024px Desktop Desktop 1920px Desktop
Best Practices
Use theme breakpoints Always reference theme.breakpoints instead of hardcoding pixel values
Mobile-first Write base styles for mobile, then enhance for larger screens
Test thoroughly Test at all breakpoints, not just mobile and desktop
Consider performance Use CSS media queries for layout, useMediaQuery for content
For responsive images, consider using Next.js Image component with the sizes prop to serve appropriately sized images for each breakpoint.