Media query not working problems usually happen when the browser is reading a different viewport, a different CSS rule, or a more rigid layout than the one you think you are testing.
Responsive CSS Fix
Why is my media query not working?
If your mobile styles are not applying, your breakpoint seems ignored, or your layout stays stuck in desktop mode, the browser is usually not being random. The real issue is usually a missing viewport tag, invalid syntax, CSS order, specificity, cache, or a rigid layout that makes the media query look broken even when it is actually firing.
- Viewport setup
- Breakpoint logic
- CSS cascade
- Rigid layout traps
What the bug looks like
Your CSS says mobile should be one column, but the page stays in desktop mode. Or your media query changes one thing, but the layout still overflows and looks broken.
Why it happens
A media query does not magically make a layout responsive. It only applies CSS under a condition. If setup, cascade, or structure is wrong, the result still breaks.
What usually fixes it
Confirm the viewport tag, test the breakpoint in DevTools, inspect overridden rules, then replace rigid layout rules with flexible responsive patterns.
Missing viewport tag makes mobile CSS look ignored
This is one of the most common reasons a media query does not work on mobile. Without the viewport meta tag, the browser may render the page as a wide desktop canvas and scale it down. Your breakpoint may not match the real screen the way you expect.
Broken code
Missing viewport<head>
<title>My Page</title>
<link rel="stylesheet" href="style.css">
</head>
@media (max-width: 768px) {
.cards {
grid-template-columns: 1fr;
}
}
Broken visual result
Correct code
Real mobile viewport<head>
<meta name="viewport"
content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
@media (max-width: 768px) {
.cards {
grid-template-columns: 1fr;
}
}
Fixed visual result
Invalid media query syntax silently breaks the rule
Media query syntax is easy to almost get right. A missing space, missing unit, wrong parenthesis, or forgotten brace can make the browser skip the rule or read it differently than you intended.
Broken code
Syntax trap@media screen and(max-width: 768px) {
.menu {
display: none;
}
.cards {
grid-template-columns: 1fr;
}
}
Broken visual result
Correct code
Valid condition@media screen and (max-width: 768px) {
.menu {
display: none;
}
.cards {
grid-template-columns: 1fr;
}
}
Fixed visual result
The media query works, but CSS order overrides it
The browser may be applying your media query correctly, then immediately replacing it with a later rule. This is why media queries can “work” in DevTools but still not change what you see on the page.
Broken code
Later desktop rule wins@media (max-width: 768px) {
.card-title {
font-size: 18px;
}
}
.card-title {
font-size: 36px;
}
Broken visual result
Huge title on mobile
The media query fires, but the later desktop rule wins the cascade.
Correct code
Mobile rule comes after.card-title {
font-size: 36px;
}
@media (max-width: 768px) {
.card-title {
font-size: 22px;
}
}
Fixed visual result
Readable mobile title
The mobile rule appears later, so the cascade now matches the responsive intention.
The breakpoint fires, but the layout is still rigid
This is the grown-up version of the media query bug. The media query is not dead. The layout is still too rigid. A fixed-width wrapper, a wide grid, a long code block, or an image without responsive limits can make the page look broken even after the breakpoint activates.
Broken code
Breakpoint fires, layout still breaks.wrapper {
width: 1200px;
}
.cards {
display: grid;
grid-template-columns: repeat(3, 320px);
}
@media (max-width: 768px) {
.cards {
grid-template-columns: 1fr;
}
}
Broken visual result
Correct code
Flexible parent and grid.wrapper {
width: min(100%, 1200px);
margin-inline: auto;
padding-inline: 16px;
}
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
}
@media (max-width: 768px) {
.cards {
grid-template-columns: 1fr;
}
}
Fixed visual result
A production-minded media query setup
The best responsive fix is not just one media query. It is a layout system that starts flexible, uses safe grid tracks, lets children shrink, protects images, and only uses breakpoints to adjust behavior—not to rescue broken desktop code.
Premium code
Flexible first.layout {
width: min(100%, 1120px);
margin-inline: auto;
padding-inline: clamp(16px, 4vw, 32px);
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
gap: clamp(16px, 3vw, 28px);
}
.card,
.card * {
min-width: 0;
}
.card img {
display: block;
max-width: 100%;
height: auto;
}
@media (max-width: 768px) {
.layout {
padding-inline: 16px;
}
.card-title {
font-size: clamp(24px, 8vw, 34px);
}
}
Premium visual result
Fast practical rule
If your media query is not working, do not start by changing random breakpoint numbers. First confirm the viewport tag, then test whether the rule is firing in DevTools, then check whether another rule or a rigid parent is still winning.
Debug checklist
- Confirm the page includes
<meta name="viewport" content="width=device-width, initial-scale=1">. - Resize the page in DevTools and confirm whether the media query is actually firing.
- Check the media query syntax for missing spaces, braces, parentheses, units, and invalid conditions.
- Inspect whether a later CSS rule is overriding the media query.
- Check whether a stronger selector is beating your mobile selector.
- Verify whether the breakpoint should use
max-widthormin-width. - Look for a fixed-width wrapper, wide grid track, long word, code block, image, table, or child element that refuses to shrink.
- Clear browser, plugin, and CDN cache if your CSS changes are not showing at all.
Final takeaway
A media query not working rarely means the browser is broken. Most of the time, the browser is following the rules exactly: the viewport is wrong, the condition is invalid, the cascade is overriding the rule, specificity is too strong, cache is stale, or the layout is still too rigid to respond.
Start by proving whether the media query is active. Then debug the cascade. Then fix the structure. Once the layout is flexible first, media queries become precise adjustments instead of emergency rescue patches.
Want more fixes like this?
Browse more responsive debugging guides or jump to the full FrontFixer library.