Saltar al contenido

馃帀 Material UI v5 is out! Head to the migration guide to get started.


This is a CSS media query hook for React. It listens for matches to a CSS media query. It allows the rendering of components based on whether the query matches or not.

Some of the key features:

  • 鈿 Tiene una API de React idiom谩tica.
  • 馃殌 It's performant, it observes the document to detect when its media queries change, instead of polling the values periodically.
  • 馃摝 1 kB comprimido.
  • 馃 It supports server-side rendering.

Simple media query

You should provide a media query to the first argument of the hook. The media query string can be any valid CSS media query, e.g. '(prefers-color-scheme: dark)'.

(min-width:600px) matches: false
import React from 'react';
import useMediaQuery from '@material-ui/core/useMediaQuery';

export default function SimpleMediaQuery() {
  const matches = useMediaQuery('(min-width:600px)');

  return <span>{`(min-width:600px) matches: ${matches}`}</span>;

鈿狅笍 You can't use 'print' per browsers limitation, e.g. Firefox.

Using Material-UI's breakpoint helpers

You can use Material-UI's breakpoint helpers as follows:

import { useTheme } from '@material-ui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';

function MyComponent() {
  const theme = useTheme();
  const matches = useMediaQuery(theme.breakpoints.up('sm'));

  return <span>{`theme.breakpoints.up('sm') matches: ${matches}`}</span>;
theme.breakpoints.up('sm') matches: false

Alternatively, you can use a callback function, accepting the theme as a first argument:

import useMediaQuery from '@material-ui/core/useMediaQuery';

function MyComponent() {
  const matches = useMediaQuery(theme => theme.breakpoints.up('sm'));

  return <span>{`theme.breakpoints.up('sm') matches: ${matches}`}</span>;

鈿狅笍 There is no default theme support, you have to inject it in a parent theme provider.

Utilizando sintaxis de JavaScript

You can use json2mq to generate media query string from a JavaScript object.

{ minWidth: 600 } matches: false
import React from 'react';
import json2mq from 'json2mq';
import useMediaQuery from '@material-ui/core/useMediaQuery';

export default function JavaScriptMedia() {
  const matches = useMediaQuery(
      minWidth: 600,

  return <span>{`{ minWidth: 600 } matches: ${matches}`}</span>;


Necesitas una implementaci贸n de matchMedia en tu entorno de pruebas.

Por ejemplo, jsdom a煤n no lo soporta. You should polyfill it. Using css-mediaquery to emulate it is recommended.

import mediaQuery from 'css-mediaquery';

function createMatchMedia(width) {
  return query => ({
    matches: mediaQuery.match(query, { width }),
    addListener: () => {},
    removeListener: () => {},

describe('MisTests', () => {
  beforeAll(() => {
    window.matchMedia = createMatchMedia(window.innerWidth);

Server-side rendering

鈿狅笍 Server-side rendering and client-side media queries are fundamentally at odds. Be aware of the tradeoff. The support can only be partial.

Try relying on client-side CSS media queries first. For instance, you could use:

If none of the above alternatives are an option, you can proceed reading this section of the documentation.

First, you need to guess the characteristics of the client request, from the server. You have the choice between using:

  • User agent. Parse the user agent string of the client to extract information. Using ua-parser-js to parse the user agent is recommended.
  • Client hints. Read the hints the client is sending to the server. Be aware that this feature is not supported everywhere.

Finally, you need to provide an implementation of matchMedia to the useMediaQuery with the previously guessed characteristics. Using css-mediaquery to emulate matchMedia is recommended.

For instance on the server-side:

width: deviceType === 'mobile' ?
      import ReactDOMServer from 'react-dom/server';
import parser from 'ua-parser-js';
import mediaQuery from 'css-mediaquery';
import { ThemeProvider } from '@material-ui/core/styles';

function handleRender(req, res) {
  const deviceType = parser(req.headers['user-agent']).device.type || 'desktop';
  const ssrMatchMedia = query => ({
    matches: mediaQuery.match(query, {
      // The estimated CSS width of the browser. '0px' : '1024px',

  const html = ReactDOMServer.renderToString(
        props: {
          // Change the default options of useMediaQuery
          MuiUseMediaQuery: { ssrMatchMedia },
      <App />

  // 鈥
(min-width:600px) matches: true

Make sure you provide the same custom match media implementation to the client-side to guarantee a hydration match.

Migraci贸n de withWidth()

The withWidth() higher-order component injects the screen width of the page. You can reproduce the same behavior with a useWidth hook:

width: xs
<ThemeProvider theme={theme}>
  <MyComponent />


useMediaQuery(query, [options]) => matches


  1. query (String | Function): A string representing the media query to handle or a callback function accepting the theme (in the context) that returns a string.
  2. options (Object [optional]):
    • options.defaultMatches (Boolean [optional]): As window.matchMedia() is unavailable on the server, we return a default matches during the first mount. The default value is false.
    • options.matchMedia (Function [optional]) You can provide your own implementation of matchMedia. This can be used for handling an iframe content window.
    • options.noSsr (Boolean [optional]): Default false. In order to perform the server-side rendering reconciliation, it needs to render twice. A first time with nothing and a second time with the children. This double pass rendering cycle comes with a drawback. It's slower. You can set this flag to true if you are not doing server-side rendering.
    • options.ssrMatchMedia (Function [optional]) You can provide your own implementation of matchMedia in a server-side rendering context.

Note: You can change the default options using the default props feature of the theme with the MuiUseMediaQuery key.


matches: Matches is true if the document currently matches the media query and false when it does not.


import React from 'react';
import useMediaQuery from '@material-ui/core/useMediaQuery';

export default function SimpleMediaQuery() {
  const matches = useMediaQuery('(min-width:600px)');

  return <span>{`(min-width:600px) matches: ${matches}`}</span>;