Media Query Generator
StylingEverything runs locally in your browser — nothing is uploaded
Pick a condition and get an `@media` block you can paste straight into a stylesheet. ⚠️ Breakpoint ownership needs a rule. `max-width: 767.98px` meets `min-width: 768px`, not `max-width: 767px` — leaving out that `0.02` means a 767.5px viewport matches neither rule, and that width exists in practice (browser zoom, fractional pixels). So every generated range uses “upper bound − 0.02”. If you swap the two numbers it corrects itself rather than producing a query that can never match. ⚠️ Two queries that are widely misread: · `prefers-color-scheme: dark` means “the user has expressed a preference for dark”, not “the user is in dark mode”. A page that writes styles only under `dark` is white for anyone who has said nothing — while the author believes it “adapts automatically”. · `prefers-reduced-motion` only tells you the user asked for less motion. It stops no animation for you. Writing the query without actually disabling anything inside is the same as not writing it. ⚠️ The preview shows the effect of the declarations inside the block — a media query is a condition and cannot be applied to an element. What you copy is the text on the right.
Features
- Width breakpoints: `min-width`, `max-width` and ranges
- ⚠️ A range’s upper bound is reduced by 0.02 so it meets the next `min-width` exactly, leaving no gap that nothing covers
- ⚠️ Swapping the two numbers corrects itself instead of producing a query that can never match
- Preferences: dark and light mode, reduced motion, higher contrast
- Devices: orientation, hover capability, whether the primary input is touch
- A live preview (showing the effect of the declarations inside the block)
- ⚠️ The dark-mode entry says it is not “currently dark”; the reduced-motion entry says it does not stop animations by itself
- Copies the complete `@media … { }` block
How to use
- Pick a condition
- For width conditions, set the breakpoint; for a range, also the upper bound
- Copy the text on the right and change the selector and declarations
FAQ
- Why is max-width 767.98px rather than 767px?
- So that the ranges meet exactly. `max-width: 767px` and `min-width: 768px` leave `767px ~ 768px` covered by neither rule, and styles then go wrong at certain window widths for no visible reason. That gap is real: browser zoom at 110%, a non-integer device pixel ratio, or a layout computed with `clamp()` all produce fractional viewport widths. Subtracting 0.02 is the established practice (it is what Bootstrap does) — smaller than any integer, larger than the first fraction after 767.98.
- Why does prefers-color-scheme: dark not apply?
- Because it means “the user has expressed a preference for dark”, not “the user is in dark mode”. When someone has never set a theme preference, the query does not match — so a page that writes styles only under `dark` appears white-on-black-default to them, that is, your base styles. The correct approach is to write the light styles by default and override inside `dark`, not to treat dark as the default and put light inside a `light` query. That second approach leaves users who have said nothing with something designed for neither.
- I added prefers-reduced-motion but animations still run. Why?
- Because the query does nothing by itself — it is only a condition telling you the user asked for less motion. To take effect, you have to disable things inside it: `animation: none;`, `transition: none;`, or a near-zero duration. An empty `@media (prefers-reduced-motion: reduce) { }` block is the same as not writing it, while looking in the code as though it were handled — which is the most common misuse of this feature.
- Should I use min-width or max-width?
- Prefer `min-width` (mobile first). The reason is not style but the cascade: a later `min-width` rule naturally overrides an earlier one, so adding a new breakpoint just means appending; `max-width` rules have to be inserted in the right place and get tangled as they accumulate. And writing base styles for the phone first, then adding for larger screens, forces you to confront what does not fit on a small screen — easier to get right than building the desktop version and then trying to squeeze it into a phone.
- Can a media query tell whether the user is on a touch device?
- Not reliably — you can only ask the right question. `(pointer: coarse)` asks whether the primary input is coarse (a finger) and `(hover: hover)` asks whether hovering is possible. But on hybrid devices (a laptop with a touchscreen, a tablet with a mouse attached) both can be true at once, and users switch input method whenever they like. So do not use these to guess a device; use them to enhance when the capability exists: put `:hover` styles inside `@media (hover: hover)`, which is the accurate use, since on a touchscreen the concept of hovering does not exist in the first place.
Related tools
Flexbox
StylingClick through flex-direction, justify-content, align-items and more, watch the layout change live, and copy the complete CSS with matching HTML.
Vertical Text
StylingAdjust direction, font size, column gap and height to preview vertical text live and copy the CSS. The height decides where columns wrap.
Cursor Preview
StylingMove the mouse over the preview block to see what each cursor keyword looks like — there are more than thirty, and half cannot be guessed from the name.
CSS Gradient Generator
StylingAdjust the angle, colours and shape, preview the gradient live, copy the CSS. Linear, radial and conic, with an optional middle stop.
CSS Border Radius
StylingSet each corner radius, preview it live and copy the CSS. px, rem or percent — and the preview shows why a percentage gives an ellipse.
Glassmorphism Generator
StylingAdjust blur, opacity, saturation and border, preview the glassmorphism live and copy the CSS, -webkit- prefix included so it works on iOS.