Jomatter

CSS Media Query Generator

Generate CSS media queries instantly with custom breakpoints, screen sizes, orientations, and responsive conditions. Preview layouts, customize CSS, and copy or download responsive code directly in your browser.

Media Query Settings

Presets fill the relevant breakpoint field. Choose breakpoints based on where your layout actually breaks, not on device names.

Orientation reflects the viewport's width-to-height relationship, not a guaranteed physical device orientation.

Advanced Media Features

Nonnegative integer for the color media feature.

Some media features describe user-agent or device capabilities rather than viewport size. Not every browser or device implements every feature.

Generated CSS

Auto

CSS Rules

Responsive Preview

—

Preview uses browser rendering at the selected viewport size. Features such as hover, pointer, contrast preferences, print media, forced colors, and resolution may not be fully simulatable in an ordinary preview.

Query Information

Generated Query

—

Breakpoint Summary

—

Validation

No issues detected by the available checks.

Example Media Queries
', '', '
', '

Responsive Preview

', '

Viewport: —

', '
', '
', '

Sample Card

', '

This card demonstrates the effect of your media query at the selected viewport width.

', 'Example Button', '
', '
', '

Another Card

', '

Content inside a responsive container.

', '
', '
', '

Third Card

', '

Add more cards or sections to test more complex layouts.

', '
', '', '' ].join('\n'); } function previewDimensions() { var w, h; if (state.previewMode === 'mobile') { w = 375; h = 700; } else if (state.previewMode === 'tablet') { w = 768; h = 900; } else if (state.previewMode === 'custom') { w = isNum(Number(state.previewWidth)) ? Number(state.previewWidth) : 900; h = isNum(Number(state.previewHeight)) ? Number(state.previewHeight) : 600; } else { w = '100%'; h = 700; } return { width: w, height: h }; } function applyViewportSize() { if (!previewViewport) { return; } var d = previewDimensions(); if (d.width === '100%') { previewViewport.style.width = '100%'; previewViewport.style.maxWidth = '100%'; } else { previewViewport.style.width = d.width + 'px'; previewViewport.style.maxWidth = '100%'; } } function evaluateMatch() { // Evaluate the width/height portion of the condition against the iframe's rendered viewport. if (!previewIframe) { return { match: null, note: '' }; } var w = previewIframe.clientWidth; var h = previewIframe.clientHeight; if (!w || !h) { return { match: null, note: '' }; } var mode = state.queryMode; var unit = state.unit; var ok = true; var has = false; function toPx(v, u) { if (!isNum(v)) { return null; } if (u === 'px') { return v; } if (u === 'em' || u === 'rem') { return v * 16; } return v; } if (mode === 'max-width') { var mw = toPx(state.maxWidth, unit); if (mw != null) { has = true; ok = ok && (w <= mw); } } else if (mode === 'min-width') { var mn = toPx(state.minWidth, unit); if (mn != null) { has = true; ok = ok && (w >= mn); } } else if (mode === 'range') { var mn2 = toPx(state.minWidth, unit); var mx2 = toPx(state.maxWidth, unit); if (mn2 != null) { has = true; ok = ok && (w >= mn2); } if (mx2 != null) { has = true; ok = ok && (w <= mx2); } } else if (mode === 'min-height') { var mnh = toPx(state.minHeight, unit); if (mnh != null) { has = true; ok = ok && (h >= mnh); } } else if (mode === 'max-height') { var mxh = toPx(state.maxHeight, unit); if (mxh != null) { has = true; ok = ok && (h <= mxh); } } else { var a = toPx(state.minWidth, unit); if (a != null) { has = true; ok = ok && (w >= a); } var b = toPx(state.maxWidth, unit); if (b != null) { has = true; ok = ok && (w <= b); } var c = toPx(state.minHeight, unit); if (c != null) { has = true; ok = ok && (h >= c); } var d2 = toPx(state.maxHeight, unit); if (d2 != null) { has = true; ok = ok && (h <= d2); } } if (state.orientation !== 'any') { has = true; var isPortrait = h > w; var isLandscape = w > h; if (state.orientation === 'portrait') { ok = ok && isPortrait; } if (state.orientation === 'landscape') { ok = ok && isLandscape; } } if (!has) { return { match: null, note: '' }; } return { match: ok, note: '' }; } function updatePreviewInfo() { if (!previewInfo) { return; } var w = previewIframe ? previewIframe.clientWidth : 0; var h = previewIframe ? previewIframe.clientHeight : 0; var res = evaluateMatch(); var txt = 'Viewport: ' + w + ' × ' + h + 'px'; previewInfo.textContent = txt; previewInfo.className = 'jm-mq-preview-info'; if (res.match === true) { previewInfo.className += ' is-match'; previewInfo.textContent = txt + ' · condition matches'; } else if (res.match === false) { previewInfo.className += ' is-nomatch'; previewInfo.textContent = txt + ' · condition does not match'; } // Update header width label inside the iframe using srcdoc reload only when we can't reach into it. // The iframe has no allow-same-origin, so we cannot reach into its DOM. We include the width via CSS content if needed. } function renderPreview() { if (!previewIframe) { return; } var css = outputEl ? outputEl.value : ''; applyViewportSize(); var doc; try { doc = buildPreviewDocument(css); } catch (e) { setStatus('The preview could not be updated.', 'error'); return; } try { previewIframe.srcdoc = doc; } catch (e) { setStatus('The preview could not be updated.', 'error'); return; } // Wait a tick for layout to settle, then read dimensions and evaluate match. setTimeout(function () { updatePreviewInfo(); }, 60); setStatus('Preview updated successfully.', 'success'); } function schedulePreviewRender() { if (previewTimer) { clearTimeout(previewTimer); } previewTimer = setTimeout(function () { previewTimer = null; renderPreview(); }, 120); } /* ============================================================ Event wiring — settings ============================================================ */ function bindInput(el, setter, opts) { if (!el) { return; } el.addEventListener('input', function () { setter(el); onAnySettingChange(); }); el.addEventListener('change', function () { setter(el); onAnySettingChange(); }); } function numSetter(field) { return function (el) { var v = el.value === '' ? '' : Number(el.value); if (v === '' || isNum(v)) { state[field] = v; } }; } function numOrEmptySetter(field) { return function (el) { var raw = el.value; if (raw === '') { state[field] = ''; return; } var v = Number(raw); if (isNum(v)) { state[field] = v; } }; } function rawSetter(field) { return function (el) { state[field] = el.value; }; } bindInput(mediaTypeSel, function (el) { state.mediaType = el.value; }); bindInput(queryModeSel, function (el) { state.queryMode = el.value; }); bindInput(unitSel, function (el) { state.unit = el.value; }); bindInput(orientationSel, function (el) { state.orientation = el.value; }); bindInput(minWidthIn, numSetter('minWidth')); bindInput(maxWidthIn, numSetter('maxWidth')); bindInput(minHeightIn, numSetter('minHeight')); bindInput(maxHeightIn, numSetter('maxHeight')); bindInput(minAspectIn, rawSetter('minAspect')); bindInput(maxAspectIn, rawSetter('maxAspect')); bindInput(minResIn, numOrEmptySetter('minRes')); bindInput(maxResIn, numOrEmptySetter('maxRes')); bindInput(resUnitSel, function (el) { state.resUnit = el.value; }); bindInput(hoverSel, function (el) { state.hover = el.value; }); bindInput(pointerSel, function (el) { state.pointer = el.value; }); bindInput(colorSchemeSel, function (el) { state.colorScheme = el.value; }); bindInput(reducedMotionSel, function (el) { state.reducedMotion = el.value; }); bindInput(contrastSel, function (el) { state.contrast = el.value; }); bindInput(forcedColorsSel, function (el) { state.forcedColors = el.value; }); bindInput(minColorIn, rawSetter('minColor')); if (presetSel) { presetSel.addEventListener('change', function () { var v = presetSel.value; if (!v) { return; } var num = Number(v); if (!isNum(num)) { return; } var mode = state.queryMode; if (mode === 'max-width') { state.maxWidth = num; if (maxWidthIn) { maxWidthIn.value = String(num); } } else if (mode === 'min-width') { state.minWidth = num; if (minWidthIn) { minWidthIn.value = String(num); } } else if (mode === 'range') { // apply to the "current" bound; use max for range unless max is empty if (state.maxWidth === '' || state.maxWidth == null) { state.maxWidth = num; if (maxWidthIn) { maxWidthIn.value = String(num); } } else if (state.minWidth === '' || state.minWidth == null) { state.minWidth = num; if (minWidthIn) { minWidthIn.value = String(num); } } else { // update max state.maxWidth = num; if (maxWidthIn) { maxWidthIn.value = String(num); } } } else if (mode === 'min-height') { state.minHeight = num; if (minHeightIn) { minHeightIn.value = String(num); } } else if (mode === 'max-height') { state.maxHeight = num; if (maxHeightIn) { maxHeightIn.value = String(num); } } onAnySettingChange(); }); } /* ============================================================ Event wiring — rules ============================================================ */ if (addRuleBtn) { addRuleBtn.addEventListener('click', function () { state.rules.push({ selector: '.responsive-element', declarations: 'display: block;' }); renderRules(); onAnySettingChange(); setStatus('CSS rule added.', 'success'); }); } if (rulesWrap) { rulesWrap.addEventListener('input', function (e) { var t = e.target; if (!t) { return; } var selIdx = t.getAttribute && t.getAttribute('data-rule-selector'); var declIdx = t.getAttribute && t.getAttribute('data-rule-declarations'); if (selIdx != null) { var i = parseInt(selIdx, 10); if (isNum(i) && state.rules[i]) { state.rules[i].selector = t.value; } } else if (declIdx != null) { var j = parseInt(declIdx, 10); if (isNum(j) && state.rules[j]) { state.rules[j].declarations = t.value; } } else { return; } onAnySettingChange(); }); rulesWrap.addEventListener('click', function (e) { var t = e.target; if (!t || !t.getAttribute) { return; } var rm = t.getAttribute('data-remove-rule'); if (rm == null) { return; } var idx = parseInt(rm, 10); if (!isNum(idx)) { return; } if (state.rules.length <= 1) { return; } state.rules.splice(idx, 1); renderRules(); onAnySettingChange(); setStatus('CSS rule removed.', 'success'); }); } /* ============================================================ Event wiring — output ============================================================ */ if (outputEl) { outputEl.addEventListener('input', function () { state.manualEdit = true; state.stale = false; syncOutputBadge(); setStatus('Manual CSS edits detected.', ''); schedulePreviewRender(); }); } if (generateBtn) { generateBtn.addEventListener('click', function () { generate(false); }); } if (regenerateBtn) { regenerateBtn.addEventListener('click', function () { generate(false); }); } if (autoCb) { autoCb.addEventListener('change', function () { state.autoGenerate = !!autoCb.checked; syncOutputBadge(); if (state.autoGenerate) { generate(true); setStatus('Auto Generate enabled. CSS regenerated.', 'success'); } else { setStatus('Auto Generate disabled. Generate CSS to update the output.', ''); } }); } if (resetOutputBtn) { resetOutputBtn.addEventListener('click', function () { if (outputEl) { outputEl.value = ''; } state.manualEdit = false; state.stale = false; syncOutputBadge(); renderValidation(); schedulePreviewRender(); setStatus('Output reset.', 'success'); }); } /* ---------- Copy ---------- */ function fallbackCopy(text) { try { var ta = document.createElement('textarea'); ta.value = text; ta.setAttribute('readonly', 'readonly'); ta.style.position = 'fixed'; ta.style.top = '-1000px'; ta.style.left = '-1000px'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); ta.setSelectionRange(0, text.length); var ok = document.execCommand('copy'); document.body.removeChild(ta); return ok; } catch (e) { return false; } } function copyText(text, successMsg, failMsg) { if (!text) { setStatus(failMsg || 'Nothing to copy yet.', 'error'); return; } if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') { navigator.clipboard.writeText(text).then(function () { setStatus(successMsg, 'success'); }).catch(function () { if (fallbackCopy(text)) { setStatus(successMsg, 'success'); } else { setStatus(failMsg || 'Unable to copy CSS.', 'error'); } }); } else if (fallbackCopy(text)) { setStatus(successMsg, 'success'); } else { setStatus(failMsg || 'Unable to copy CSS.', 'error'); } } if (copyBtn) { copyBtn.addEventListener('click', function () { var text = outputEl ? outputEl.value : ''; if (!text || !text.trim()) { setStatus('Nothing to copy yet.', 'error'); return; } copyText(text, 'CSS copied successfully.', 'Unable to copy CSS.'); }); } /* ---------- Download ---------- */ if (downloadBtn) { downloadBtn.addEventListener('click', function () { var text = outputEl ? outputEl.value : ''; if (!text || !text.trim()) { setStatus('Nothing to download yet.', 'error'); return; } var url = null; try { var blob = new Blob([text], { type: 'text/css;charset=utf-8' }); url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'media-query.css'; a.style.display = 'none'; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function () { if (url) { try { URL.revokeObjectURL(url); } catch (e) {} } }, 1500); setStatus('CSS file downloaded successfully.', 'success'); } catch (e) { if (url) { try { URL.revokeObjectURL(url); } catch (err) {} } setStatus('Unable to download the CSS file.', 'error'); } }); } /* ---------- Format / minify ---------- */ if (formatBtn) { formatBtn.addEventListener('click', function () { var text = outputEl ? outputEl.value : ''; if (!text || !text.trim()) { setStatus('Nothing to format yet.', 'error'); return; } var formatted = formatCSS(text); if (formatted == null) { setStatus('CSS formatting could not be completed safely. The original text was preserved.', 'error'); return; } outputEl.value = formatted; state.manualEdit = true; syncOutputBadge(); schedulePreviewRender(); setStatus('CSS formatted.', 'success'); }); } if (minifyBtn) { minifyBtn.addEventListener('click', function () { var text = outputEl ? outputEl.value : ''; if (!text || !text.trim()) { setStatus('Nothing to minify yet.', 'error'); return; } var min; try { min = minifyCSS(text); } catch (e) { setStatus('Unable to minify the CSS safely.', 'error'); return; } if (!min) { setStatus('Unable to minify the CSS safely.', 'error'); return; } outputEl.value = min; state.manualEdit = true; syncOutputBadge(); schedulePreviewRender(); setStatus('CSS minified.', 'success'); }); } /* ============================================================ Event wiring — preview ============================================================ */ for (var v = 0; v < viewBtns.length; v++) { (function (btn) { btn.addEventListener('click', function () { var mode = btn.getAttribute('data-view'); if (!mode) { return; } state.previewMode = mode; for (var k = 0; k < viewBtns.length; k++) { viewBtns[k].setAttribute('aria-pressed', viewBtns[k] === btn ? 'true' : 'false'); } if (customViewportWrap) { customViewportWrap.hidden = (mode !== 'custom'); } applyViewportSize(); schedulePreviewRender(); setStatus('Preview mode: ' + mode + '.', ''); }); })(viewBtns[v]); } if (previewRefreshBtn) { previewRefreshBtn.addEventListener('click', function () { renderPreview(); }); } if (customWIn) { customWIn.addEventListener('input', function () { var v = Number(customWIn.value); if (isNum(v) && v > 0) { state.previewWidth = v; if (state.previewMode === 'custom') { applyViewportSize(); schedulePreviewRender(); } } }); } if (customHIn) { customHIn.addEventListener('input', function () { var v = Number(customHIn.value); if (isNum(v) && v > 0) { state.previewHeight = v; } }); } /* ============================================================ Examples ============================================================ */ var EXAMPLES = [ { title: 'Mobile First', css: 'min-width 768', apply: function () { state.mediaType = 'screen'; state.queryMode = 'min-width'; state.unit = 'px'; state.minWidth = 768; state.orientation = 'any'; state.rules = [{ selector: '.responsive-element', declarations: 'font-size: 18px;' }]; } }, { title: 'Mobile Maximum Width', css: 'max-width 767', apply: function () { state.mediaType = 'screen'; state.queryMode = 'max-width'; state.unit = 'px'; state.maxWidth = 767; state.orientation = 'any'; state.rules = [{ selector: '.responsive-element', declarations: 'font-size: 14px;' }]; } }, { title: 'Tablet Range', css: '768 – 1023', apply: function () { state.mediaType = 'screen'; state.queryMode = 'range'; state.unit = 'px'; state.minWidth = 768; state.maxWidth = 1023; state.orientation = 'any'; state.rules = [{ selector: '.responsive-element', declarations: 'padding: 20px;' }]; } }, { title: 'Landscape Orientation', css: 'orientation: landscape', apply: function () { state.mediaType = 'screen'; state.queryMode = 'custom'; state.unit = 'px'; state.minWidth = ''; state.maxWidth = ''; state.minHeight = ''; state.maxHeight = ''; state.orientation = 'landscape'; state.rules = [{ selector: '.responsive-element', declarations: 'display: flex;' }]; } }, { title: 'Print Styles', css: '@media print', apply: function () { state.mediaType = 'print'; state.queryMode = 'custom'; state.unit = 'px'; state.minWidth = ''; state.maxWidth = ''; state.minHeight = ''; state.maxHeight = ''; state.orientation = 'any'; state.rules = [{ selector: '.responsive-element', declarations: 'color: #000;\nbackground: #fff;' }]; } }, { title: 'Dark Mode', css: 'prefers-color-scheme: dark', apply: function () { state.mediaType = 'screen'; state.queryMode = 'custom'; state.unit = 'px'; state.minWidth = ''; state.maxWidth = ''; state.minHeight = ''; state.maxHeight = ''; state.orientation = 'any'; state.colorScheme = 'dark'; state.rules = [{ selector: '.responsive-element', declarations: 'color: #fff;\nbackground: #0A1220;' }]; } }, { title: 'Reduced Motion', css: 'prefers-reduced-motion: reduce', apply: function () { state.mediaType = 'screen'; state.queryMode = 'custom'; state.unit = 'px'; state.minWidth = ''; state.maxWidth = ''; state.minHeight = ''; state.maxHeight = ''; state.orientation = 'any'; state.reducedMotion = 'reduce'; state.rules = [{ selector: '.responsive-element', declarations: 'animation: none;\ntransition: none;' }]; } }, { title: 'High-Density Displays', css: 'min-resolution: 2dppx', apply: function () { state.mediaType = 'screen'; state.queryMode = 'custom'; state.unit = 'px'; state.minWidth = ''; state.maxWidth = ''; state.minHeight = ''; state.maxHeight = ''; state.orientation = 'any'; state.minRes = 2; state.resUnit = 'dppx'; state.rules = [{ selector: '.responsive-element', declarations: 'background-size: 100% auto;' }]; } } ]; function renderExamples() { if (!examplesWrap) { return; } examplesWrap.innerHTML = ''; for (var i = 0; i < EXAMPLES.length; i++) { (function (ex, idx) { var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'jm-mq-example'; btn.setAttribute('data-example', String(idx)); var title = document.createElement('span'); title.className = 'jm-mq-example-title'; title.textContent = ex.title; var code = document.createElement('pre'); code.className = 'jm-mq-example-code'; code.textContent = ex.css; btn.appendChild(title); btn.appendChild(code); examplesWrap.appendChild(btn); })(EXAMPLES[i], i); } } if (examplesWrap) { examplesWrap.addEventListener('click', function (e) { var t = e.target; while (t && t !== examplesWrap && !t.getAttribute('data-example')) { t = t.parentNode; } if (!t || t === examplesWrap) { return; } var idx = parseInt(t.getAttribute('data-example'), 10); if (!isNum(idx) || !EXAMPLES[idx]) { return; } EXAMPLES[idx].apply(); syncAllControlsFromState(); onAnySettingChange(); if (state.autoGenerate) { generate(true); } setStatus('Example loaded: ' + EXAMPLES[idx].title + '.', 'success'); }); } /* ============================================================ Full sync from state to controls ============================================================ */ function syncAllControlsFromState() { if (mediaTypeSel) { mediaTypeSel.value = state.mediaType; } if (queryModeSel) { queryModeSel.value = state.queryMode; } if (unitSel) { unitSel.value = state.unit; } if (orientationSel) { orientationSel.value = state.orientation; } if (minWidthIn) { minWidthIn.value = state.minWidth === '' ? '' : String(state.minWidth); } if (maxWidthIn) { maxWidthIn.value = state.maxWidth === '' ? '' : String(state.maxWidth); } if (minHeightIn) { minHeightIn.value = state.minHeight === '' ? '' : String(state.minHeight); } if (maxHeightIn) { maxHeightIn.value = state.maxHeight === '' ? '' : String(state.maxHeight); } if (minAspectIn) { minAspectIn.value = state.minAspect || ''; } if (maxAspectIn) { maxAspectIn.value = state.maxAspect || ''; } if (minResIn) { minResIn.value = state.minRes === '' ? '' : String(state.minRes); } if (maxResIn) { maxResIn.value = state.maxRes === '' ? '' : String(state.maxRes); } if (resUnitSel) { resUnitSel.value = state.resUnit; } if (hoverSel) { hoverSel.value = state.hover; } if (pointerSel) { pointerSel.value = state.pointer; } if (colorSchemeSel) { colorSchemeSel.value = state.colorScheme; } if (reducedMotionSel) { reducedMotionSel.value = state.reducedMotion; } if (contrastSel) { contrastSel.value = state.contrast; } if (forcedColorsSel) { forcedColorsSel.value = state.forcedColors; } if (minColorIn) { minColorIn.value = state.minColor === '' ? '' : String(state.minColor); } if (autoCb) { autoCb.checked = !!state.autoGenerate; } for (var k = 0; k < viewBtns.length; k++) { viewBtns[k].setAttribute('aria-pressed', viewBtns[k].getAttribute('data-view') === state.previewMode ? 'true' : 'false'); } if (customViewportWrap) { customViewportWrap.hidden = state.previewMode !== 'custom'; } if (customWIn) { customWIn.value = String(state.previewWidth); } if (customHIn) { customHIn.value = String(state.previewHeight); } renderRules(); syncModeVisibility(); syncOutputBadge(); syncInfo(); updatePresetFromValues(); renderValidation(); applyViewportSize(); } /* ============================================================ Reset ============================================================ */ function resetWorkspace() { state.mediaType = DEFAULTS.mediaType; state.queryMode = DEFAULTS.queryMode; state.unit = DEFAULTS.unit; state.orientation = DEFAULTS.orientation; state.minWidth = DEFAULTS.minWidth; state.maxWidth = DEFAULTS.maxWidth; state.minHeight = DEFAULTS.minHeight; state.maxHeight = DEFAULTS.maxHeight; state.minAspect = ''; state.maxAspect = ''; state.minRes = ''; state.maxRes = ''; state.resUnit = 'dppx'; state.hover = 'any'; state.pointer = 'any'; state.colorScheme = 'any'; state.reducedMotion = 'any'; state.contrast = 'any'; state.forcedColors = 'any'; state.minColor = ''; state.rules = DEFAULTS.rules.map(function (r) { return { selector: r.selector, declarations: r.declarations }; }); state.autoGenerate = true; state.previewMode = 'desktop'; state.previewWidth = DEFAULTS.previewWidth; state.previewHeight = DEFAULTS.previewHeight; state.manualEdit = false; state.stale = false; if (autoTimer) { clearTimeout(autoTimer); autoTimer = null; } if (previewTimer) { clearTimeout(previewTimer); previewTimer = null; } syncAllControlsFromState(); generate(true); renderPreview(); setStatus('Workspace reset.', 'success'); } /* ============================================================ Bind reset button (added dynamically to match prompt) ============================================================ */ // The Reset button is placed in the output toolbar as "Reset Output", // and the full workspace Reset is added beside it. (function addResetWorkspaceButton() { if (!resetOutputBtn || !resetOutputBtn.parentNode) { return; } var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'jm-mq-btn'; btn.id = 'jm-mq-reset-workspace'; btn.textContent = 'Reset Workspace'; resetOutputBtn.parentNode.insertBefore(btn, resetOutputBtn.nextSibling); btn.addEventListener('click', function () { resetWorkspace(); }); })(); /* ============================================================ Initial render ============================================================ */ renderExamples(); syncAllControlsFromState(); generate(true); renderPreview(); setStatus('Ready. Adjust settings or pick a preset.', ''); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();

All Developer Tools

Browse free online tools for JSON, HTML, CSS, XML, JavaScript, data conversion, and everyday development tasks.

50 tools

What Is a CSS Media Query Generator?

A CSS Media Query Generator is an online tool that helps you create responsive CSS rules without manually writing every @media condition. Choose a screen size, select a responsive design approach, and generate clean CSS for mobile phones, tablets, laptops, desktops, and other display sizes.

CSS media queries let you apply styles only when specific conditions are met. These conditions can include viewport width, screen orientation, user color-scheme preferences, reduced-motion settings, and print requirements. They help websites adapt their layouts to different devices and user needs.

For example, @media (min-width: 768px) applies styles when the viewport is at least 768 pixels wide. A generator makes it easier to create this rule, customize the breakpoint, and add the CSS declarations you need.

Build responsive CSS faster: Use Jomatter's CSS Media Query Generator to select a device preset or custom breakpoint, choose mobile-first or desktop-first syntax, and generate CSS you can copy into your project.

What Can You Create With This CSS Media Query Generator?

Mobile-First Media Queries

Generate min-width rules that apply styles at a breakpoint and continue applying them at larger viewport widths.

Desktop-First Media Queries

Create max-width rules for adapting desktop layouts to smaller screens, including tablets and mobile devices.

Custom Breakpoints

Enter your own breakpoint values in pixels, em, or rem to match your layout requirements and existing design system.

Range-Based Media Queries

Generate modern range conditions such as (width >= 768px) or (768px <= width < 1024px).

Dark Mode and Reduced Motion

Create media queries for dark color schemes, reduced motion, contrast preferences, and other supported user settings.

Copy-Ready CSS Output

Generate formatted CSS blocks for your stylesheet and copy the output without rebuilding each media query manually.

You can also use media query rules for portrait and landscape orientation, print layouts, high-resolution displays, and pointer or hover capabilities.

Who Should Use a CSS Media Query Generator?

User Common Use Case
Front-End Developers Create responsive page layouts, component styles, navigation menus, and grid breakpoints.
UI and UX Designers Turn design specifications and viewport requirements into usable CSS rules.
WordPress Developers Write custom responsive styles for WordPress themes, page builders, and website components.
Web Design Agencies Speed up responsive styling during website builds, redesigns, and maintenance projects.
Students and Beginners Learn how breakpoints, min-width, max-width, and media conditions work.
Accessibility Specialists Implement reduced-motion, color-scheme, contrast, and device-capability preferences where supported.

How to Use the CSS Media Query Generator

Generate responsive CSS in a few simple steps. Start with the viewport or condition you want to target, then customize the rule for your project.

1

Choose a Device Preset or Custom Breakpoint

Select a common mobile, tablet, laptop, or desktop breakpoint. You can also enter a custom value in px, em, or rem.

2

Select Mobile-First or Desktop-First

Choose min-width for styles that apply from a breakpoint upward, or max-width for styles that apply up to a specified width.

3

Add Optional Media Conditions

Include conditions such as portrait orientation, landscape orientation, dark mode, reduced motion, print, or high-resolution displays when needed.

4

Enter Your CSS Rules

Specify the selector and declarations you want to change, such as container padding, grid columns, font size, or navigation visibility.

5

Generate and Copy the CSS

Review the generated media query, copy the CSS, and paste it into your stylesheet. Test it at the intended viewport widths before publishing.

Mobile-First vs. Desktop-First Media Queries

Mobile-first and desktop-first describe two common ways to organize responsive CSS. The right approach depends on your existing styles, layout, and development workflow.

Use min-width

Write your base styles for smaller screens, then add or adjust styles as the viewport gets wider. This approach is widely used for modern responsive layouts.

/* Base styles */
.container {
  padding: 16px;
}

/* Tablet and larger */
@media (min-width: 768px) {
  .container {
    padding: 24px;
  }
}

/* Desktop and larger */
@media (min-width: 1024px) {
  .container {
    padding: 40px;
  }
}

Use max-width

Write the main styles for larger screens, then override or reduce them as the viewport becomes narrower. This can be useful when adapting an existing desktop-focused design.

/* Base desktop styles */
.container {
  padding: 40px;
}

/* Tablet and smaller */
@media (max-width: 1023.98px) {
  .container {
    padding: 24px;
  }
}

/* Mobile and smaller */
@media (max-width: 767.98px) {
  .container {
    padding: 16px;
  }
}

Which approach should you choose? Mobile-first is a useful default for new responsive projects because it starts with a simple layout and adds enhancements for larger screens. Desktop-first is also valid when it fits your project or existing stylesheet better.

Common CSS Breakpoints for Responsive Design

Breakpoints are viewport widths at which a design changes to accommodate available space. These values are common starting points, not universal device standards. Choose breakpoints based on how your content behaves rather than assuming every phone or tablet has the same width.

Screen Category Example Width Example Media Query
Small mobile 480px and below @media (max-width: 480px)
Mobile Below 768px @media (max-width: 767.98px)
Tablet 768px–1023px @media (min-width: 768px) and (max-width: 1023.98px)
Laptop 1024px and above @media (min-width: 1024px)
Desktop 1280px and above @media (min-width: 1280px)
Wide screen 1536px and above @media (min-width: 1536px)

Breakpoint tip: Do not rely on device labels alone. Resize your layout and introduce a breakpoint when the content needs a meaningful change, such as a navigation menu collapsing, a grid gaining another column, or text becoming difficult to read.

Generate Non-Overlapping Media Queries

When you create separate media query ranges, make sure their boundaries match your intended behavior. Overlapping conditions can cause multiple sets of CSS rules to apply at the same viewport width, which may produce unexpected results when the selectors and specificity interact.

For example, a desktop-first rule ending at 767.98px can sit alongside a mobile-first rule beginning at 768px without an intended overlap at the breakpoint.

/* Up to 767.98px */
@media (max-width: 767.98px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

/* 768px and above */
@media (min-width: 768px) {
  .layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

A small fractional adjustment such as 0.02px is one convention used for upper boundaries in pixel-based queries. It is not required in every stylesheet. Modern range syntax can also express exclusive upper bounds, such as (768px <= width < 1024px), where supported.

When generating multiple ranges, check the lower and upper limits carefully. Ensure that no viewport widths are unintentionally left out and that the CSS matches the browser support requirements of your project.

CSS Framework Breakpoint Presets

If your project uses a CSS framework, matching its breakpoint system can make your styles easier to maintain. A media query generator can offer framework presets so you do not need to look up each breakpoint manually.

Tailwind CSS

Generate queries that match the breakpoint values configured in your Tailwind project. Check the project's theme configuration because breakpoints can be customized.

Bootstrap

Use Bootstrap-style responsive breakpoints for common container, grid, navigation, and component adjustments.

Foundation

Match Foundation's configured responsive breakpoints when adding custom styles to a Foundation-based website.

Material UI

Use breakpoint values aligned with your Material UI theme and responsive component rules.

Framework defaults and project configurations can change. Always confirm that the selected preset matches the version and settings used by your application.

Media Query Features and CSS Syntax

Media queries can target more than screen width. The following examples show common conditions you can use when building responsive and accessible interfaces.

Feature Example Syntax Purpose
Minimum width (min-width: 768px) Applies when the viewport is at least 768 pixels wide.
Maximum width (max-width: 767.98px) Applies when the viewport is no wider than the specified limit.
Modern width range (768px <= width < 1024px) Targets a width range using modern range syntax.
Portrait orientation (orientation: portrait) Targets a viewport whose height is greater than or equal to its width.
Landscape orientation (orientation: landscape) Targets a viewport whose width is greater than its height.
Dark mode (prefers-color-scheme: dark) Responds to a user's dark color-scheme preference.
Reduced motion (prefers-reduced-motion: reduce) Allows reduced-animation styles for users who request less motion.
Print @media print Applies styles when a document is printed or presented in print preview.
High resolution (min-resolution: 2dppx) Targets displays with a high pixel density.
Hover capability (hover: hover) Targets a primary input mechanism that can conveniently hover.
Pointer precision (pointer: fine) Targets a primary pointing device with fine control, such as a mouse.

How to Create Dark Mode Media Queries

The prefers-color-scheme media feature lets a website respond to a user's preferred light or dark color scheme. It is useful for changing backgrounds, text colors, borders, and other interface styles without requiring users to manually change every element.

/* Default light theme */
:root {
  color-scheme: light;
  --page-bg: #ffffff;
  --text-color: #172033;
}

/* Dark theme preference */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --page-bg: #111827;
    --text-color: #f3f4f6;
  }
}

body {
  background: var(--page-bg);
  color: var(--text-color);
}

For websites with a manual theme toggle, combine your chosen theme strategy with the user's system preference. Make sure that text, links, form controls, borders, and focus indicators remain readable in both themes.

Accessibility Media Queries for Better User Experiences

Responsive design should account for user preferences and device capabilities, not just viewport width. Accessibility-focused media queries can help reduce unnecessary animation and adapt interfaces to different input methods and display preferences.

Respect Reduced Motion

Use prefers-reduced-motion to reduce nonessential animations and transitions for users who request less motion.

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Review this type of rule against your application before using it globally. Some animations communicate important state changes, so preserve necessary feedback while reducing nonessential movement.

Adapt to Contrast Preferences

The prefers-contrast media feature can help provide styles for users who prefer increased or decreased contrast, where the browser and operating system support the preference.

@media (prefers-contrast: more) {
  .card {
    border: 2px solid currentColor;
  }

  .muted-text {
    color: inherit;
  }
}

Consider Hover and Pointer Capabilities

Hover and pointer media features help distinguish between input capabilities. They can be useful when deciding whether to apply hover-specific effects or make controls easier to use on touch devices.

@media (hover: hover) and (pointer: fine) {
  .button:hover {
    filter: brightness(0.92);
  }
}

Do not make essential actions available only on hover. Interactive controls should remain usable with touch, keyboard, and other supported input methods.

How to Create Print Media Queries

Print media queries let you adjust a page when someone prints it or opens print preview. A print stylesheet can hide navigation and interactive controls, remove unnecessary backgrounds, and make the main content easier to read on paper.

@media print {
  nav,
  .site-header,
  .site-footer,
  .no-print {
    display: none !important;
  }

  body {
    color: #000;
    background: #fff;
    font-size: 12pt;
  }

  main {
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  a {
    color: inherit;
    text-decoration: underline;
  }
}

Before using print rules, check that the content remains complete and understandable without navigation, decorative backgrounds, or interactive controls. Avoid hiding information that readers need in the printed document.

Responsive Design Best Practices

Media queries are most effective when used alongside flexible layouts and content that can adapt naturally. Follow these practices when creating responsive styles for a new website or improving an existing one.

  • Start with a flexible layout: Use CSS Grid, Flexbox, and fluid sizing where appropriate instead of relying entirely on fixed widths.
  • Choose content-based breakpoints: Add a breakpoint when the layout starts to look crowded or difficult to use, rather than targeting device names alone.
  • Use relative units when suitable: Consider percentages, rem, em, and flexible grid tracks to support different screen sizes and text settings.
  • Keep media queries organized: Use a consistent mobile-first or desktop-first strategy where practical, and group related responsive rules together.
  • Avoid unnecessary breakpoints: Add only the conditions that improve the layout or user experience.
  • Test between common widths: Check intermediate viewport sizes, not just a few standard phone and desktop dimensions.
  • Account for accessibility: Consider keyboard access, readable contrast, reduced motion, and touch-friendly controls.
  • Check the cascade: Verify that media query rules interact correctly with existing selectors, specificity, and source order.
  • Confirm browser support: Check compatibility before relying on newer media features or range syntax.

Frequently Asked Questions

Is the CSS Media Query Generator free?

Jomatter positions this tool as a free way to generate CSS media queries. You can use it to create responsive breakpoint rules without manually writing each condition. Check the tool interface for its available options.

What is a CSS media query?

A CSS media query applies styles when specified conditions are met. Common conditions include viewport width, orientation, color-scheme preference, reduced motion, and print context.

What is the difference between min-width and max-width?

min-width targets viewports at or above a specified width. max-width targets viewports at or below a specified width. Mobile-first styles commonly use min-width, while desktop-first styles often use max-width.

Should I use mobile-first or desktop-first CSS?

Mobile-first is a useful starting point for many new responsive projects because it begins with the simplest layout and adds styles for larger screens. Desktop-first can also work well when adapting an existing design or maintaining a project built around that approach.

Can I generate custom CSS breakpoints?

Yes. A media query generator can let you enter custom breakpoint values in units such as pixels, em, or rem, so you can match your layout instead of relying only on preset screen sizes.

What breakpoints should I use for mobile, tablet, and desktop?

Common starting points include 480px for smaller mobile layouts, 768px for tablet-sized layouts, 1024px for larger layouts, and 1280px or more for wider screens. These are guidelines, not fixed standards. Choose breakpoints based on your content and design.

Can I generate Tailwind CSS or Bootstrap media queries?

Framework breakpoint presets can help you create rules aligned with Tailwind CSS, Bootstrap, Foundation, or Material UI. Verify the values against your framework version and any custom breakpoint configuration in your project.

Can media queries support dark mode?

Yes. The prefers-color-scheme media feature can detect a user's light or dark color-scheme preference, allowing your CSS to adjust interface colors accordingly.

Can I use media queries for accessibility?

Yes. Features such as prefers-reduced-motion and prefers-contrast can help your styles respond to user preferences. Hover and pointer conditions can also help adapt interactions to different input capabilities.

Does the generator create modern CSS range syntax?

A generator that supports range syntax can produce conditions such as (width >= 768px) and (768px <= width < 1024px). Check browser compatibility when using newer syntax in production projects.

Can I use generated media queries in WordPress?

Yes. You can use generated CSS in a WordPress theme, child theme, custom stylesheet, or an appropriate custom CSS area. Test the rules with your theme and page builder to make sure they do not conflict with existing styles.

Is my CSS private when I use the tool?

Privacy depends on how the tool is implemented. If media queries are generated entirely in your browser, the entered values do not need to be uploaded to a server. Only make this claim when the implementation has been verified to work client-side.

Generate Responsive CSS Without Writing Every Rule Manually

Writing responsive CSS can take time when you need several breakpoints, custom screen ranges, and user-preference conditions. A CSS media query generator simplifies this process by helping you build the syntax, select the conditions, and prepare CSS for your stylesheet.

Use Jomatter's CSS Media Query Generator to create mobile-first or desktop-first rules, work with custom breakpoints, and prepare responsive styles for different viewport sizes. Review the generated code, test it across screen widths, and adjust it to fit your project's layout and browser support requirements.

Generate Your CSS Media Queries

Create responsive CSS for mobile, tablet, laptop, and desktop layouts. Choose your breakpoint, customize media conditions, and prepare CSS to use in your project.

Free, fast, browser-based CSS media query generation for responsive websites.