Responsive style values for css-in-js.
import { css } from 'emotion' import facepaint from 'facepaint'const mq = facepaint([ '@media(min-width: 420px)', '@media(min-width: 920px)', '@media(min-width: 1120px)' ])
const myClassName = css(mq({ color: ['red', 'green', 'blue', 'darkorchid'], }))
npm i facepaint -S
or
yarn add facepaint
function
facepaint(selectors: Array) : DynamicStyleFunction
Arguments * breakpoints
javascript const mq = facepaint([ '@media(min-width: 420px)', '@media(min-width: 920px)', '@media(min-width: 1120px)' ])
options
javascript const mq = facepaint( [...], { literal: true|false, overlap: true|false } )
boolean(Default:
false) - output should match arguments given to
facepaintexactly
By default, the first value in a value array is applied without a media query or selector and the rest of the values are applied as children of media queries or selectors. When
literalis set to
truethe values given to a specific css property mapped 1:1 with the arguments provided to
facepaint.
Given the following:
const mq = facepaint([ '@media(min-width: 420px)' '@media(min-width: 920px)' ], { literal: true })const expandedStyles = mq({ color: ['red', 'green'] })
The output of
expandedStyleswill be:
{ '@media(min-width: 420px)': { color: 'red' }, '@media(min-width: 920px)': { color: 'green' } }
The output is missing any styles on the base style object because the values are mapped to the arguments supplied to
facepaintliterally. - overlap
boolean(Default:
false) - overlap values that occur in multiple media queries or slots
Given the following:
const mq = facepaint([ '@media(min-width: 420px)' ], { overlap: true })const expandedStyles = mq({ color: ['red', 'red'] })
The value of
expandedStyleswould not contain any media query breakpoints. This is an optimization to remove bytes from the final code.
{ color: 'red' }
vs.
{ color: 'red', '@media(min-width: 420px)': { color: 'red' } }
The downside of enabling this option is that when attempting to overwrite the value of
colorin another style definition the expected media query will be missing.
const style1 = css(mq({ color: ['red', 'red'] })) const style2 = css({ color: 'blue' }) const composedStyles = css(style1, style2)
style1's output will NOT contain the media query and value for red at
420pxdue to the
overlap: trueoptimization.
The developer that created
composedStylesmight expect the following output.
{ color: 'blue', '@media(min-width: 420px)': { color: 'red' } }
Due to our
overlap: trueoptimization however, the final output will be the following.
{ color: 'blue' }
Returns
facepaintreturns a function that can be exported and used throughout your app to dynamically style based on your provided selectors.
undefined, and
nullvalues are ignored.
import { css } from 'emotion' import facepaint from 'facepaint'const mq = facepaint([ '@media(min-width: 420px)', '@media(min-width: 920px)', '@media(min-width: 1120px)' ])
const myClassName = css(mq({ backgroundColor: 'hotpink', textAlign: 'center', width: ['25%', '50%', '75%', '100%'], '& .foo': { color: ['red', 'green', 'blue', 'darkorchid'], '& img': { height: [10, 15, 20, 25] } } }))
Note that the first value is considered a default value and is not a child of a media query at-rule.
The following css is generated.
.css-rbuh8g { background-color: hotpink; text-align: center; width: 25%; }@media (min-width:420px) { .css-rbuh8g { width: 50%; } }
@media (min-width:920px) { .css-rbuh8g { width: 75%; } }
@media (min-width:1120px) { .css-rbuh8g { width: 100%; } }
.css-rbuh8g .foo { color: red; }
@media (min-width:420px) { .css-rbuh8g .foo { color: green; } }
@media (min-width:920px) { .css-rbuh8g .foo { color: blue; } }
@media (min-width:1120px) { .css-rbuh8g .foo { color: darkorchid; } }
.css-rbuh8g .foo img { height: 10px; }
@media (min-width:420px) { .css-rbuh8g .foo img { height: 15px; } }
@media (min-width:920px) { .css-rbuh8g .foo img { height: 20px; } }
@media (min-width:1120px) { .css-rbuh8g .foo img { height: 25px; } }
import styled from 'styled-components' import facepaint from 'facepaint'const mq = facepaint([ '@media(min-width: 420px)', '@media(min-width: 920px)', '@media(min-width: 1120px)' ])
const Div = styled('div')
${mq({ backgroundColor: 'hotpink', textAlign: 'center', width: ['25%', '50%', '75%', '100%'], '& .foo': { color: ['red', 'green', 'blue', 'papayawhip'], '& img': { height: ['10px', '15px', '20px', '25px'] } } })};
The following css is generated.
.c0 { background-color: hotpink; text-align: center; width: 25%; }.c0 .foo { color: red; }
.c0 .foo img { height: 10px; }
@media (min-width:420px) { .c0 { width: 50%; } }
@media (min-width:920px) { .c0 { width: 75%; } }
@media (min-width:1120px) { .c0 { width: 100%; } }
@media (min-width:420px) { .c0 .foo { color: green; } }
@media (min-width:920px) { .c0 .foo { color: blue; } }
@media (min-width:1120px) { .c0 .foo { color: papayawhip; } }
@media (min-width:420px) { .c0 .foo img { height: 15px; } }
@media (min-width:920px) { .c0 .foo img { height: 20px; } }
@media (min-width:1120px) { .c0 .foo img { height: 25px; } }
import { css } from 'emotion' import facepaint from 'facepaint'const pseudo = facepaint([':hover', ':focus', ':active'])
const myClassName = css( pseudo({ backgroundColor: 'hotpink', textAlign: 'center', width: ['25%', '50%', '75%', '100%'], '& .foo': { color: ['red', 'green', 'blue', 'darkorchid'], '& img': { height: [10, 15, 20, 25] } } }) )
.css-1guvnfu { background-color: hotpink; text-align: center; width: 25%; }.css-1guvnfu:hover { width: 50%; }
.css-1guvnfu:focus { width: 75%; }
.css-1guvnfu:active { width: 100%; }
.css-1guvnfu .foo { color: red; }
.css-1guvnfu .foo:hover { color: green; }
.css-1guvnfu .foo:focus { color: blue; }
.css-1guvnfu .foo:active { color: darkorchid; }
.css-1guvnfu .foo img { height: 10px; }
.css-1guvnfu .foo img:hover { height: 15px; }
.css-1guvnfu .foo img:focus { height: 20px; }
.css-1guvnfu .foo img:active { height: 25px; }