react-only
react-only
is inspired by the .visible
classes from bootstrap 4 (or .hidden
classes from bootstrap 3): only display a certain content for a precise screen size.
It allows you to display component only for particular screen sizes.
If you need a responsive layout and adaptive components, react-only
is here for you!
How to use
<Only>
Hooks
<Match>
<BreakpointsProvider>
- CSS in JS
- Comparison to other libraries
matchMedia
polyfill- FAQ
<Only>
Default breakpoints
react-only
is based on the classic bootstrap breakpoints: xs
, sm
, md
, lg
and xl
.
;; const App = <ReactFragment> <Only on="xs">Only visible for extra small </Only> <Only on="sm">Only visible for small </Only> <Only on="md">Only visible for medium </Only> <Only on="lg">Only visible for large </Only> <Only on="xl">Only visible for extra large </Only> <Only on="sm xl">Only visible for small AND extra large devices</Only> </ReactFragment>;
By default, the breakpoints are:
Breakpoint | From | To |
---|---|---|
xs | 0px | 575px |
sm | 576px | 767px |
md | 768px | 991px |
lg | 992px | 1199px |
xl | 1200px | Infinity |
Up
and Down
Additional In addition to the regular breakpoints, you have another api defined {breakpoint}Up
and {breakpoint}Down
:
;; const App = <ReactFragment> <Only on="smUp">Visible on every device bigger or equal than "small"</Only> <Only on="mdDown">Visible on every device smaller or equal than "medium"</Only> </ReactFragment>;
Match Media Queries
For more advanced media queries, the prop matchMedia
can be set to any regular query supported by window.matchMedia.
;; const App = <Only matchMedia="(min-device-width: 500px) and (orientation: landscape)"> Visible on every device bigger than "500px" and in landscape mode </Only>;
More infos about CSS media queries
Note: If you use breakpoints AND matchMedia, the component will be displayed if one of the breakpoints is matched OR if the media query is fulfilled.
Render as component
If you want the Only
components to render as another component, you can use the as
props:
;; const App = <ul> <Only as="li" on="xs"> Only visible for extra small </Only> <Only as="li" on="sm"> Only visible for small </Only> <Only as="li" on="md"> Only visible for medium </Only> <Only as="li" on="lg"> Only visible for large </Only> <Only as="li" on="xl"> Only visible for extra large </Only> <Only as="li" on="sm xl"> Only visible for small AND extra large devices </Only> </ul>;
The as
props can take any DOM tag string (div
, ul
, li
, ...) or any React component:
;; const Custom = <ReactFragment> <h3>title</h3> <p>children</p> </ReactFragment>; const App = <ReactFragment> <Only as=Custom title="xs" on="xs"> Only visible for extra small </Only> <Only as=Custom title="sm" on="sm"> Only visible for small </Only> <Only as=Custom title="md" on="md"> Only visible for medium </Only> <Only as=Custom title="lg" on="lg"> Only visible for large </Only> <Only as=Custom title="xl" on="xl"> Only visible for extra large </Only> <Only as=Custom title="sm xl" on="sm xl"> Only visible for small AND extra large devices </Only> </ReactFragment>;
Note that any props except for matchMedia
, as
and on
will be forwarded to the as
props.
Strict mode
When strict
is set in the props, the margins are offset by 1 px:
;; const App = <ReactFragment> <Only on="xs">Only visible for range: 576px 768px</Only> <Only on="xs" strict> Only visible for range: 577px 767px </Only> </ReactFragment>;
Hooks
useOnly()
useOnly
is a hook that detects if the given breakpoint matches the current viewport.
;; const App = { const matchXl = ; const matchMdDown = ; const matchMdStrict = ; return <ul> matchXl && <li>Visible on every "large" device</li> matchMdDown && <li>Visible on every device smaller or equal than "medium"</li> matchMdStrict && <li>Visible on every strict "medium" device</li> </ul> ;};
useQuery()
useQuery
is a hook that detects if the given media query matches the current viewport.
;; const App = { const matchMediaQuery = ; return <ul>matchMediaQuery && <li>Visible max-width:576px</li></ul>;};
<Match>
only
and matchMedia
props
The Match
will look into every props of its children (and event nested children) to detect only
, matchMedia
and strict
props. If one of those is found, it will wrap this component inside a Only
component will match only
with on
and matchMedia
and strict
to theirself.
;; const App = <Match> <div only="xs">xs</div> <div only="sm">sm</div> <div only="md">md</div> <div only="lg" strict> strict lg </div> <div only="xl">xl</div> <div> <div> <div> <div only="smDown">nested smDown</div> </div> </div> </div> <div matchMedia="(min-width:768px) and (max-width:992px),(max-width:576px)"> "(min-width:768px) and (max-width:992px),(max-width:576px)" </div> </Match>;
Use a custom component in Match
You can also render the Match
component as another one:
;; const App = <Match as="ul"> <li only="xs">xs</li> <li only="sm">sm</li> <li only="md">md</li> <li only="lg">lg</li> <li only="xl">xl</li> </Match>;
TypeScript support
This library is fully written in TypeScript.
⚠️ But there is currently no full TypeScript support for the Match
component when it is used with DOM elements.
For now you can only use Match
with custom components as children:
;; // MatchChildProps includes the props `only` and `matchMedia` ; ;
<BreakpointsProvider>
BreakpointsProvider
defines the values of every breakpoints.
Use it to inject or modify the breakpoints (only use one BreakpointsProvider
per build).
Add more breakpoints
;; const App = <BreakpointsProvider additionalBreakpoints= customBrkPts: 263 863 > <Only on="customBrkPts">Visible on every device from "263px" to "863px"</Only> <Only on="customBrkPtsUp">Visible on every device bigger than "263px"</Only> <Only on="customBrkPtsDown">Visible on every device smaller than "863px"</Only> </BreakpointsProvider>;
Change default breakpoints
;; const App = <BreakpointsProvider breakpoints= sm: 263 863 > <Only on="sm">Visible on every device from "263px" to "863px"</Only> <Only on="smUp">Visible on every device bigger than "263px"</Only> <Only on="smDown">Visible on every device smaller than "863px"</Only> </BreakpointsProvider>;
Warning: This overrides completely the default breakpoints, in this example, the other breakpoints xs
, md
, lg
and xl
are no longer defined!
Units
You can specify which unit is going to be used for the breakpoint by specifying in the 3rd option a "unit" key.
By default, the unit is "px".
;; const App = <BreakpointsProvider additionalBreakpoints= pxPoint: 263 863 unit: "px" emPoint: 20 40 unit: "em" > <Only on="pxPoint">Visible on every device from "263px" to "863px"</Only> <Only on="emPoint">Visible on every device from "20em" to "40em"</Only> </BreakpointsProvider>;
Direction
You can specify which direction is used for the media queries (height or width).
By default, "width" is the chosen direction.
;; const App = <BreakpointsProvider breakpoints= xBreakpoint: 300 500 direction: "width" yBreakpoint: 200 400 direction: "height" > <Only on="xBreakpoint">Visible on every device from "300px" to "500px" wide</Only> <Only on="yBreakpoint">Visible on every device from "200px" to "400px" tall</Only> </BreakpointsProvider>;
Every CSS units are supported.
The default unit is px
.
CSS in JS
react-only
includes 2 utility functions toJSON
and toCSS
so that you can re-use react-only
breakpoints as media queries for css-in-js
libraries.
toJSON
Example with styletron
:
import React from "react";import toJSON as createToJSON BreakpointsContext from "react-only";import styled from "styletron-react"; const styles = mdDown: color: "red" ":hover": color: "blue" lgUp: color: "green" ; const Panel = ; const App = const breakpoints = React; const toJSON = ; // toJSON(styles) returns: // { // "@media (max-width:991px)": { // "color": "red", // ":hover": { // "color": "blue" // } // }, // "@media (min-width:992px)": { // "color": "green" // } // } return <Panel $=>content</Panel>;;
toCSS
Example with emotion
:
import React from "react";import toCSS as createToCSS BreakpointsContext from "react-only";import css from "emotion"; const styles = mdDown: color: "red" ":hover": color: "blue" lgUp: color: "green" ; const App = const breakpoints = React; const toCSS = ; // toCSS(styles) returns: // `@media (max-width:991px) { // color: red; // :hover { // color: blue; // } // } // @media (min-width:992px) { // color: green; // }` return <div =>content</div>;;
Comparison to other libraries
Lib | Breakpoints | Custom breakpoints | Media query | matchMedia listener' |
hooks | SSR support |
---|---|---|---|---|---|---|
react-only | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
react-responsive | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
react-breakpoints | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
react-responsive-breakpoints | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
': matchMedia
listener event means that the library is built around matchMedia.addListener(callback)
and not window.addEventListener('resize', callback)
(which is faster because the callback is only triggered when the media query's state changes and not at every resize).
matchMedia
polyfill
Browser
If you are on want to use matchMedia on browser that don’t support it, I’d recommend you to use matchmedia-polyfill
.
Node
If you want to mock matchMedia
on Node to execute tests for instance, you can use mock-match-media
.
And if you need an example with Jest
, @testing-library/react
, React
and react-only
, you can take a look at these tests.
FAQ
For other questions, please take a look at our FAQ document.