{"id":13394269,"url":"https://github.com/ReactTraining/react-media","last_synced_at":"2025-03-13T20:31:24.275Z","repository":{"id":49828447,"uuid":"64814946","full_name":"ReactTraining/react-media","owner":"ReactTraining","description":"CSS media queries for React","archived":false,"fork":false,"pushed_at":"2020-07-15T09:45:27.000Z","size":873,"stargazers_count":2439,"open_issues_count":8,"forks_count":115,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-10-29T14:59:18.071Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReactTraining.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-03T04:25:43.000Z","updated_at":"2024-10-17T16:25:08.000Z","dependencies_parsed_at":"2022-08-25T16:41:10.275Z","dependency_job_id":null,"html_url":"https://github.com/ReactTraining/react-media","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactTraining%2Freact-media","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactTraining%2Freact-media/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactTraining%2Freact-media/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactTraining%2Freact-media/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReactTraining","download_url":"https://codeload.github.com/ReactTraining/react-media/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243382923,"owners_count":20282049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T17:01:14.397Z","updated_at":"2025-03-13T20:31:24.243Z","avatar_url":"https://github.com/ReactTraining.png","language":"JavaScript","readme":"# react-media [![Travis][build-badge]][build] [![npm package][npm-badge]][npm]\n\n[build-badge]: https://img.shields.io/travis/ReactTraining/react-media/master.svg?style=flat-square\n[build]: https://travis-ci.org/ReactTraining/react-media\n[npm-badge]: https://img.shields.io/npm/v/react-media.svg?style=flat-square\n[npm]: https://www.npmjs.org/package/react-media\n\n[`react-media`](https://www.npmjs.com/package/react-media) is a CSS media query component for React.\n\nA `\u003cMedia\u003e` component listens for matches to a [CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries) and renders stuff based on whether the query matches or not.\n\n## Installation\n\nUsing npm:\n\n    $ npm install --save react-media\n\nThen, use as you would anything else:\n\n```js\n// using ES modules\nimport Media from 'react-media';\n\n// using CommonJS modules\nvar Media = require('react-media');\n```\n\nThe UMD build is also available on [unpkg](https://unpkg.com):\n\n```html\n\u003cscript src=\"https://unpkg.com/react-media\"\u003e\u003c/script\u003e\n```\n\nYou can find the library on `window.ReactMedia`.\n\n## Hooks are coming soon!\n\nHooks are available in 2.X branch.\n\nInstall `react-media@next` to get it.\n\n`useMedia` accepts a single options argument to handle both single and multiple queries, so the same properties as Media are available (except of course render and children props).\n\n\nSimple usage with multiple queries:\n\n```tsx\nimport { useMedia } from 'react-media';\n\nconst GLOBAL_MEDIA_QUERIES = {\n    small: \"(max-width: 599px)\",\n    medium: \"(min-width: 600px) and (max-width: 1199px)\",\n    large: \"(min-width: 1200px)\"\n};\nconst matches = useMedia({ queries: GLOBAL_MEDIA_QUERIES });\n\nconst marginBottom = matches.large ? 0 : 10;\n```\n\nWith single query : \n\n```tsx\nimport { useMedia } from 'react-media';\n\nconst isSmallScreen = useMedia({ query: \"(max-width: 599px)\" });\n\n```\n\n\n## Basic usage\n\n### queries\n\nRender a `\u003cMedia\u003e` component with a `queries` prop whose value is an object,\nwhere each value is a valid\n[CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries).\nThe `children` prop should be a function whose argument will be an object with the\nsame keys as your `queries` object, and whose values are booleans indicating whether\neach query matches.\n\n```jsx\nimport React, { Fragment } from 'react';\nimport Media from 'react-media';\n\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cMedia queries={{\n          small: \"(max-width: 599px)\",\n          medium: \"(min-width: 600px) and (max-width: 1199px)\",\n          large: \"(min-width: 1200px)\"\n        }}\u003e\n          {matches =\u003e (\n            \u003cFragment\u003e\n              {matches.small \u0026\u0026 \u003cp\u003eI am small!\u003c/p\u003e}\n              {matches.medium \u0026\u0026 \u003cp\u003eI am medium!\u003c/p\u003e}\n              {matches.large \u0026\u0026 \u003cp\u003eI am large!\u003c/p\u003e}\n            \u003c/Fragment\u003e\n          )}\n        \u003c/Media\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n### query\n\nAlternatively, if you only need to match against a single media query, the `query` prop provides a less-verbose approach.\nMore documentation about the difference between `query` and `queries` can be found below.\n\n```jsx\nimport React, { Fragment } from 'react';\nimport Media from 'react-media';\n\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cMedia query=\"(max-width: 599px)\" render={() =\u003e\n          (\n            \u003cp\u003eI am small!\u003c/p\u003e\n          )}\n        /\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n## `query` vs `queries`\n\nThe `queries` prop was added to allow for multiple media queries to be matched without excessive nesting or other\nworkarounds. The `query` prop was retained out of recognition that a single query covers many use cases, and there\nis already a lot of usage that would be a pain to migrate.\n\nThe salient points:\n\n* **You cannot use them together**: if you do, the component will throw an error. This is to avoid confusion around\nprecedence.\n* **The render methods differ slightly**: for the `queries` prop, the `render` and child JSX methods will render if\n**at least one** of the given queries is matched. The `query` prop renders if the given query matches.\n\n\n## `queries`\n\nIn addition to passing a valid media query string, the `queries`\nprop will also accept an object of objects whose forms are similar to\n[React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html)\nin e.g. `\u003cdiv style\u003e`. These objects are converted to CSS\nmedia queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).\n\n```jsx\nimport React from 'react';\nimport Media from 'react-media';\n\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003ch1\u003eThese two Media components are equivalent\u003c/h1\u003e\n\n        \u003cMedia queries={{ small: { maxWidth: 599 } }}\u003e\n          {matches =\u003e\n            matches.small ? (\n              \u003cp\u003eThe document is less than 600px wide.\u003c/p\u003e\n            ) : (\n              \u003cp\u003eThe document is at least 600px wide.\u003c/p\u003e\n            )\n          }\n        \u003c/Media\u003e\n\n        \u003cMedia queries={{ small: \"(max-width: 599px)\" }}\u003e\n          {matches =\u003e\n            matches.small ? (\n              \u003cp\u003eThe document is less than 600px wide.\u003c/p\u003e\n            ) : (\n              \u003cp\u003eThe document is at least 600px wide.\u003c/p\u003e\n            )\n          }\n        \u003c/Media\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\nKeys of media query objects are camel-cased and numeric values automatically get the `px` suffix. See the [json2mq docs](https://github.com/akiran/json2mq/blob/master/README.md#usage) for more examples of queries you can construct using objects.\n\n### Render props\n\nThere are three props which allow you to render your content. They each serve a subtly different purpose.\n\n|prop|description|example|\n|---|---|---|\n|render|Only invoked when **at least one** of the queries matches. This is a nice shorthand if you only want to render something for a matching query.|`\u003cMedia queries={{ foo: ... }} render={() =\u003e \u003cp\u003eI matched!\u003c/p\u003e} /\u003e`|\n|children (function)|Receives an object of booleans whose keys are the same as the `queries` prop, indicating whether each media query matched. Use this prop if you need to render different output for each of specified queries.|`\u003cMedia queries={{ foo: ... }}\u003e{matches =\u003e matches.foo ? \u003cp\u003eI matched!\u003c/p\u003e : \u003cp\u003eI didn't match\u003c/p\u003e}\u003c/Media\u003e`|\n|children (react element)|If you render a regular React element within `\u003cMedia\u003e`, it will render that element when **at least one** of the queries matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the queries match or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`\u003cMedia queries={{ ... }}\u003e\u003cp\u003eI matched!\u003c/p\u003e\u003c/Media\u003e`|\n\n## `query`\n\nIn addition to passing a valid media query string, the `query` prop will also accept an object, similar to [React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html) in e.g. `\u003cdiv style\u003e`. These objects are converted to CSS media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).\n\n```jsx\nimport React from 'react';\nimport Media from 'react-media';\n\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003ch1\u003eThese two Media components are equivalent\u003c/h1\u003e\n\n        \u003cMedia query={{ maxWidth: 599 }}\u003e\n          {matches =\u003e\n            matches ? (\n              \u003cp\u003eThe document is less than 600px wide.\u003c/p\u003e\n            ) : (\n              \u003cp\u003eThe document is at least 600px wide.\u003c/p\u003e\n            )\n          }\n        \u003c/Media\u003e\n\n        \u003cMedia query=\"(max-width: 599px)\"\u003e\n          {matches =\u003e\n            matches ? (\n              \u003cp\u003eThe document is less than 600px wide.\u003c/p\u003e\n            ) : (\n              \u003cp\u003eThe document is at least 600px wide.\u003c/p\u003e\n            )\n          }\n        \u003c/Media\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\nKeys of media query objects are camel-cased and numeric values automatically get the `px` suffix. See the [json2mq docs](https://github.com/akiran/json2mq/blob/master/README.md#usage) for more examples of queries you can construct using objects.\n\n### Render props\n\nThere are three props which allow you to render your content. They each serve a subtly different purpose.\n\n|prop|description|example|\n|---|---|---|\n|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`\u003cMedia query=\"...\" render={() =\u003e \u003cp\u003eI matched!\u003c/p\u003e} /\u003e`|\n|children (function)|Receives a single boolean element, indicating whether the media query matched. Use this prop if you need to render something when the query doesn't match.|`\u003cMedia query=\"...\"\u003e{matches =\u003e matches ? \u003cp\u003eI matched!\u003c/p\u003e : \u003cp\u003eI didn't match\u003c/p\u003e}\u003c/Media\u003e`|\n|children (react element)|If you render a regular React element within `\u003cMedia\u003e`, it will render that element when the query matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the query matches or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`\u003cMedia query=\"...\"\u003e\u003cp\u003eI matched!\u003c/p\u003e\u003c/Media\u003e`|\n\n## `onChange`\n\nYou can specify an optional `onChange` prop, which is a callback function that will be invoked when the status of the media queries changes. This can be useful for triggering side effects, independent of the render lifecycle.\n\n```jsx\nimport React from 'react';\nimport Media from 'react-media';\n\nclass App extends React.Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cMedia\n          query={{ small: \"(max-width: 599px)\" }}\n          onChange={matches =\u003e\n            matches.small\n              ? alert('The document is less than 600px wide.')\n              : alert('The document is at least 600px wide.')\n          }\n        /\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n### Server-side rendering (SSR)\n\nIf you render a `\u003cMedia\u003e` component on the server, it will match by default. You can override the default behavior by setting the `defaultMatches` prop.\n\nWhen rendering on the server you can use the `defaultMatches` prop to set the initial state on the server to match whatever you think it will be on the client. You can detect the user's device [by analyzing the user-agent string](https://github.com/ReactTraining/react-media/pull/50#issuecomment-415700905) from the HTTP request in your server-side rendering code.\n\n```js\ninitialState = {\n  device: 'mobile' // add your own guessing logic here, based on user-agent for example\n};\n\n\u003cdiv\u003e\n  \u003cMedia\n    queries={{ medium: \"(max-width: 500px)\" }}\n    defaultMatches={{ medium: state.device === 'mobile' }}\n    render={() =\u003e \u003cText\u003eRender me below medium breakpoint.\u003c/Text\u003e}\n  /\u003e\n\n  \u003cMedia\n    queries={{ medium: \"(min-width: 501px)\" }}\n    defaultMatches={{ medium: state.device === 'desktop' }}\n    render={() =\u003e \u003cText\u003eRender me above medium breakpoint.\u003c/Text\u003e}\n  /\u003e\n\u003c/div\u003e;\n```\n\n## `targetWindow`\n\nAn optional `targetWindow` prop can be specified if you want the `queries` to be evaluated against a different window object than the one the code is running in. This can be useful if you are rendering part of your component tree to an iframe or [a popup window](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202). See [this PR thread](https://github.com/ReactTraining/react-media/pull/78) for context.\n\n## About\n\n`react-media` is developed and maintained by [React Training](https://reacttraining.com). If you're interested in learning more about what React can do for your company, please [get in touch](mailto:hello@reacttraining.com)!\n","funding_links":[],"categories":["JavaScript","Utilities","Uncategorized","Javascript","⚛️ React"],"sub_categories":["Miscellaneous","Uncategorized","React UI","React-specific libs:"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FReactTraining%2Freact-media","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FReactTraining%2Freact-media","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FReactTraining%2Freact-media/lists"}