Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ReactTraining/react-media
CSS media queries for React
https://github.com/ReactTraining/react-media
Last synced: 3 months ago
JSON representation
CSS media queries for React
- Host: GitHub
- URL: https://github.com/ReactTraining/react-media
- Owner: ReactTraining
- License: mit
- Created: 2016-08-03T04:25:43.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2020-07-15T09:45:27.000Z (over 4 years ago)
- Last Synced: 2024-05-16T01:02:22.901Z (8 months ago)
- Language: JavaScript
- Homepage:
- Size: 853 KB
- Stars: 2,444
- Watchers: 24
- Forks: 117
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGES.md
- License: LICENSE
Awesome Lists containing this project
- awesome-react-components-all - react-media
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-list - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- fucking-awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
- awesome-react-components - react-media - A CSS media query component for React. (Utilities / Miscellaneous)
README
# react-media [![Travis][build-badge]][build] [![npm package][npm-badge]][npm]
[build-badge]: https://img.shields.io/travis/ReactTraining/react-media/master.svg?style=flat-square
[build]: https://travis-ci.org/ReactTraining/react-media
[npm-badge]: https://img.shields.io/npm/v/react-media.svg?style=flat-square
[npm]: https://www.npmjs.org/package/react-media[`react-media`](https://www.npmjs.com/package/react-media) is a CSS media query component for React.
A `` 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.
## Installation
Using npm:
$ npm install --save react-media
Then, use as you would anything else:
```js
// using ES modules
import Media from 'react-media';// using CommonJS modules
var Media = require('react-media');
```The UMD build is also available on [unpkg](https://unpkg.com):
```html
```
You can find the library on `window.ReactMedia`.
## Hooks are coming soon!
Hooks are available in 2.X branch.
Install `react-media@next` to get it.
`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).
Simple usage with multiple queries:
```tsx
import { useMedia } from 'react-media';const GLOBAL_MEDIA_QUERIES = {
small: "(max-width: 599px)",
medium: "(min-width: 600px) and (max-width: 1199px)",
large: "(min-width: 1200px)"
};
const matches = useMedia({ queries: GLOBAL_MEDIA_QUERIES });const marginBottom = matches.large ? 0 : 10;
```With single query :
```tsx
import { useMedia } from 'react-media';const isSmallScreen = useMedia({ query: "(max-width: 599px)" });
```
## Basic usage
### queries
Render a `` component with a `queries` prop whose value is an object,
where each value is a valid
[CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries).
The `children` prop should be a function whose argument will be an object with the
same keys as your `queries` object, and whose values are booleans indicating whether
each query matches.```jsx
import React, { Fragment } from 'react';
import Media from 'react-media';class App extends React.Component {
render() {
return (
{matches => (
{matches.small &&I am small!
}
{matches.medium &&I am medium!
}
{matches.large &&I am large!
}
)}
);
}
}
```### query
Alternatively, if you only need to match against a single media query, the `query` prop provides a less-verbose approach.
More documentation about the difference between `query` and `queries` can be found below.```jsx
import React, { Fragment } from 'react';
import Media from 'react-media';class App extends React.Component {
render() {
return (
(
I am small!
)}
/>
);
}
}
```## `query` vs `queries`
The `queries` prop was added to allow for multiple media queries to be matched without excessive nesting or other
workarounds. The `query` prop was retained out of recognition that a single query covers many use cases, and there
is already a lot of usage that would be a pain to migrate.The salient points:
* **You cannot use them together**: if you do, the component will throw an error. This is to avoid confusion around
precedence.
* **The render methods differ slightly**: for the `queries` prop, the `render` and child JSX methods will render if
**at least one** of the given queries is matched. The `query` prop renders if the given query matches.## `queries`
In addition to passing a valid media query string, the `queries`
prop will also accept an object of objects whose forms are similar to
[React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html)
in e.g. ``. These objects are converted to CSS
media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).```jsx
import React from 'react';
import Media from 'react-media';class App extends React.Component {
render() {
return (
These two Media components are equivalent
{matches =>
matches.small ? (
The document is less than 600px wide.
) : (
The document is at least 600px wide.
)
}
{matches =>
matches.small ? (
The document is less than 600px wide.
) : (
The document is at least 600px wide.
)
}
);
}
}
```Keys 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.
### Render props
There are three props which allow you to render your content. They each serve a subtly different purpose.
|prop|description|example|
|---|---|---|
|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.|`I matched!
} />`|
|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.|`{matches => matches.foo ?I matched!
:I didn't match
}`|
|children (react element)|If you render a regular React element within ``, 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)).|`I matched!
`|## `query`
In 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. `
`. These objects are converted to CSS media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).```jsx
import React from 'react';
import Media from 'react-media';class App extends React.Component {
render() {
return (
These two Media components are equivalent
{matches =>
matches ? (
The document is less than 600px wide.
) : (
The document is at least 600px wide.
)
}
{matches =>
matches ? (
The document is less than 600px wide.
) : (
The document is at least 600px wide.
)
}
);
}
}
```Keys 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.
### Render props
There are three props which allow you to render your content. They each serve a subtly different purpose.
|prop|description|example|
|---|---|---|
|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`I matched!
} />`|
|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.|`{matches => matches ?I matched!
:I didn't match
}`|
|children (react element)|If you render a regular React element within ``, 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)).|`I matched!
`|## `onChange`
You 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.
```jsx
import React from 'react';
import Media from 'react-media';class App extends React.Component {
render() {
return (
matches.small
? alert('The document is less than 600px wide.')
: alert('The document is at least 600px wide.')
}
/>
);
}
}
```### Server-side rendering (SSR)
If you render a `` component on the server, it will match by default. You can override the default behavior by setting the `defaultMatches` prop.
When 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.
```js
initialState = {
device: 'mobile' // add your own guessing logic here, based on user-agent for example
};;
Render me below medium breakpoint.}
/>Render me above medium breakpoint.}
/>
```## `targetWindow`
An 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.
## About
`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:[email protected])!