breakpoint-helper
v2.0.4
Published
Small helper library to work with layout breakpoints in Javascript.
Downloads
2,752
Maintainers
Readme
breakpoint-helper
Small helper library (~1.1 kB) to work with layout breakpoints1 in Javascript.
Demo
View a demo here.
Core functionality
- Easily check if a breakpoint is active referencing it by name instead of value.
- Listen to breakpoint changes and add/remove functionality accordingly.
- Works with
px
andem
breakpoints. - Supports
min-width
andmax-width
. - Define your own breakpoint names and values.
- Share CSS breakpoints with Javascript so they only need to be maintained in one place (optional).
Introduction
In CSS it is common practice to give layout breakpoints, used in width-based media queries, names, such as 'mobile'
, 'tablet'
, 'desktop'
or 'sm'
, 'md'
, 'lg'
, to be able to easily reference them instead of having to remember exact values.
Often times the the CSS breakpoints apply styling changes that need to be mirrored in Javascript, e.g. display cards in a slider on small screens (with Javascript) and as a grid on larger screens (without Javascript).
breakpoint-helper is a thin wrapper around window.matchMedia
that aims to make working with layout breakpoints in Javascript more convenient by allowing to reference the breakpoints by name instead of by value ('sm'
vs. 765px
) and providing a convenient API to set and remove event listeners on media queries.
Installation
Install via npm or yarn:
npm install --save breakpoint-helper
# or
yarn add breakpoint-helper
Usage
The breakpoint-helper exports a factory function to create a breakpoint-helper instance. The factory function expects to receive the breakpoints it should work with. There are different ways to provide the breakpoints, the best choice depends on the specific project setup.
NOTE: All initialization options expect the breakpoints to be ordered from small to large.
Initialize with Javascript object
The breakpoints can defined in an object where the object keys represent the breakpoint names and the values the screen widths. The values should be of type string
and include a CSS unit, both px
and em
are supported.
import breakpointHelper from 'breakpoint-helper';
const bph = breakpointHelper({
xs: '416px',
sm: '600px',
md: '768px',
lg: '1024px',
xl: '1280px',
xxl: '1520px',
});
export default bph;
Initialize using CSS custom properties
Declare custom properties on the :root
selector using the prefix --bph-
:
:root {
--bph-xs: 416px;
--bph-sm: 600px;
--bph-md: 768px;
--bph-lg: 1024px;
--bph-xl: 1280px;
--bph-xxl: 1520px;
}
Then initialize breakpoint-helper passing the string 'custom'
as an argument:
// src/utils/bph.js
import breakpointHelper from 'breakpoint-helper';
const bph = breakpointHelper('custom');
export default bph;
Initialize with Sass map (share CSS breakpoints with Javascript)
Breakpoint-helper provides a sass mixin that allows the use of a Sass map to define the breakpoints. To use this method use the mixin in your Sass code by passing it the breakpoints as argument:
// Import the mixin, path may vary depending on implementation
@import './node_modules/breakpoint-helper/src/breakpoint-helper';
// Define a map of breakpoints
$bps: (
'xs': 416px,
'sm': 600px,
'md': 768px,
'lg': 1024px,
'xl': 1280px,
'xxl': 1520px,
);
// Use the mixin
@include breakpoint-helper($bps);
Then initialize breakpoint-helper with the string 'meta'
as argument:
// src/utils/bph.js
import breakpointHelper from 'breakpoint-helper';
const bph = breakpointHelper('meta');
export default bph;
What is happening here?
The Sass mixin will create a ruleset for the class .breakpoint-helper
with a single font-family
declaration, the font-family
value will be a serialized string of the breakpoint map:
.breakpoint-helper {
font-family: 'xs=416px&sm=600px&md=768px&lg=1024px&xl=1280px&xxl=1520px';
}
When breakpoint-helper gets initialized it will create a <meta>
element in the document's <head>
tag with the class breakpoint-helper
, read the font-famliy
CSS value and deserialize it.
NOTE: This method does not require the use of Sass or the mixin per se. All that is required is the class
.breakpoint-helper
with the serialized breakpoints asfont-family
value.
Typescript
As of v2.0.0
The library is written in Typescript and types definitions are available.
Usage with React
To use breakpoint-helper in React, setup an instance using any of the methods above and use it within a useEffect
hook. You can then use a useState
hook to use it inside your component's render function.
import { useEffect, useState } from 'react';
import { listen } from './src/utils/bph';
const MyComponent = (props) => {
const [isMatching, setIsMatching] = useState(true); // Set a default value in case you are using SSR
useEffect(() => {
const listener = listen('sm', ({ matches }) => {
setIsMatching(matches);
});
return () => listener.off(); // Remove the event listener on component unmount
}, []);
return isMatching ? (
<div className="is-matching">Matching the "sm" breakpoint.</div>
) : (
<div className="not-matching">Not matching the "sm" breakpoint.</div>
);
};
Methods
Each breakpoint-helper instance returns methods to work with the breakpoints.
In larger projects it is convenient to create a reusable breakpoint-helper instance module and export the returned methods for easier usage.
import breakpointHelper from 'breakpoint-helper';
// Could be any other of the initialization methods
const instance = breakpointHelper({
xs: '416px',
sm: '600px',
md: '768px',
lg: '1024px',
xl: '1280px',
xxl: '1520px',
});
export const {
getBreakpoints,
getMediaQuery,
isMatching,
listen,
listenAll,
} = instance; // Destructure methods and export for conveninece
export default instance;
NOTE: The following code examples assume the use of the instance above.
getBreakpoints()
Get all breakpoints as an object. Useful for debugging or passing breakpoint values to other libraries.
Returns
Object
: Object containing all instance breakpoints.
Example
import { getBreakpoints } from './src/utils/bph';
const breakpoints = getBreakpoints();
console.log(breakpoints);
// {
// xs: '416px',
// sm: '600px',
// md: '768px',
// lg: '1024px',
// xl: '1280px',
// xxl: '1520px',
// }
getMediaQuery(name, [useMax=false])
Get a min-width
, max-width
or min-width and max-width
media query by breakpoint name.
Arguments
name
{string|Array}
: Breakpoint name or array of two breakpoint names.2[useMax=false]
{boolean}
: Usemax-width
instead ofmin-width
3.
Returns
{string}
: Media query string.
Example
import { getMediaquery } from './src/utils/bph';
const mq = getMediaquery('md');
console.log(mq);
// '(min-width: 768px)'
const mqMax = getMediaquery('md', true);
console.log(mqMax);
// '(max-width: 767px)'
const mqMinMax = getMediaquery(['md', 'lg']);
console.log(mqMax);
// '(min-width: 768px) and (max-width: 1023px)'
isMatching(name, [useMax=false])
Check if a breakpoint or breakpoint range is currently matching.
Arguments
name
{string|Array}
: Breakpoint name or array of two breakpoint names.2[useMax=false]
{boolean}
: Usemax-width
instead ofmin-width
3.
Returns
{boolean}
: Whether the breakpoint or breakpoint range is matching or not.
Example
import { isMatching } from './src/utils/bph';
if (isMatching('md')) {
// Do something
} else {
// Do something else
}
if (isMatching(['md', 'lg'])) {
// Screen width is between 'md' and 'lg'
}
listen(options, callback)
Listen to a breakpoint or breakpoint range change and execute a callback function. The callback function will receive a MediaQueryList
object as parameter that can be used to check wether the breakpoint media query is matching or not. The callback function is called once on listener creation, it is possible to opt out of this behavior via options.
Arguments
options
{Object|string|Array}
Configuration Object, breakpoint name or array of two breakpoint names.options.name
{string}
: Breakpoint name or array of two breakpoint names.2[options.useMax=false]
{boolean}
: Usemax-width
instead ofmin-width
3.[options.immediate=true]
{boolean}
: Execute callback function on listener creation.callback
{Function}
: Callback function, receives aMediaQueryList
as parameter.
Returns
{Object}
: Object containing theon
andoff
listener methods.
Example
import { listen } from './src/utils/bph';
// Destructure the `MediaQueryList.matches` property
const callback = ({ matches }) => {
if (matches) {
// Do somthing
} else {
// Do somthing else
}
};
const listener = listen('md', callback);
// Remove the event listener
listener.off();
// Activate it again
listener.on();
Using an options object instead of a breakpoint name:
import { listen } from './src/utils/bph';
const listener = listen(
{
name: 'md',
useMax: true,
immediate: false,
},
callback
);
const callback = ({ matches }) => {
// ...
};
listenAll(callback, [options])
Listen to all breakpoints matching or un-matching and execute a callback function. The callback function will receive an array of the matching breakpoint names in reverse order as a parameter. That means the largest breakpoint name (or smallest when using options.useMax
) comes first in the array. The array will be empty if no breakpoints are matching.
Arguments
callback
{Function}
: Callback function, receives an array of breakpoint names as parameter.[options]
{Object}
: Configuration Object.[options.listenTo]
{Array}
: Array of breakpoint names. All are used by default.[options.useMax=false]
{boolean}
: Usemax-width
instead ofmin-width
3.[options.immediate=true]
{boolean}
: Execute callback function on listener creation.
Returns
{Object}
: Object containing theon
andoff
listener methods.
Example
import { listenAll } from './src/utils/bph';
const listener = listenAll(callback);
const callback = (bps) => {
// Get the first breakpoint in the `bps` array.
const match = bps[0];
// If the largest matching breakpoint is 'lg', it will
// be the first in the array `['lg', 'md', 'sm', 'xs',]`.
switch (match) {
case 'lg':
// Do something if the breakpoint is 'lg'
break;
case 'md':
// Do something if the breakpoint is 'md'
break;
case 'sm':
// Do something if the breakpoint is 'sm'
break;
default:
// Do something if another breakpoint is matching or none is
break;
}
};
// Remove the event listener
listener.off();
// Activate it again
listener.on();
Limit the breakpoints by passing using options.listenTo
:
import { listenAll } from './src/utils/bph';
const listener = listenAll(callback, {
// Only listen to the breakpoints 'xl', 'lg' and 'sm'.
listenTo: ['xl', 'lg', 'sm'],
// Use `max-width` media queries instead of `min-width`
useMax: true,
});
const callback = (bps) => {
// ...
};
Size & compatibility
Depending on the bundle the library is about 1.1 kB when gziped.
The library is compatible with modern browsers and should also work with IE11 (not tested).
Roadmap
- Codepen or Codesandbox examples.
- Create React hook.
- Add testing.
Motivation
I kept needing something like this and was copying the same script from project to project, so I decided to open-source it. On one hand it might help somebody that has the same need as I do and on the other it allows me to install just as another dependency.
Credits
The initialization via metatag and the serialized font-family
value is taken from Zurb's Foundation.
Notes
1) Browser window widths at which styles/functionality changes to adapt for wider/narrower screens.
2) The useMax
argument will be ignored when name
is an array.
3) When using useMax
breakpoint-helper will subtract 1px
from the breakpoint value to prevent overlap. If the breakpoint value is defined in em
s 0.0635em
is subtracted (the equivalent of 1px
in em
using a 16px
base).