Objects based styles syntax for declaring Style Sheets
September 18, 2021 ยท View on GitHub
JSS is designed to stay as close as possible to the CSS syntax. However, there are some exceptions. JSS uses a plugin-based architecture, so plugins add some of the syntaxes from the core package and others by optional plugins, which you can setup.
Basic syntax
const styles = {
button: {
color: 'red',
'font-size': '12px'
}
}
Compiles to:
.button-0 {
color: red;
font-size: 12px;
}
Media Queries
const styles = {
button: {
width: 100
},
'@media (min-width: 1024px)': {
button: {
width: 200
}
}
}
ES6 with constants in prop names
const minWidth = 1024
const styles = {
button: {
width: 100
},
[`@media (min-width: ${minWidth}px)`]: {
button: {
width: 200
}
}
}
Compiles to:
.button-0 {
width: 100px;
}
@media (min-width: 1024px) : {
.button-0 {
width: 200px;
}
}
Keyframes Animation
Keyframes name will use the same id generator function as the class names. Animation name gets scoped by default. To access it within the same style sheet, you can use $ref syntax as a value of animationName or animation property.
Additionally, you can access generated name through sheet.keyframes.{name} map.
To generate a global animation name, you can use @global rule.
const styles = {
'@keyframes slideRight': {
from: {opacity: 0},
to: {opacity: 1}
},
container: {
animationName: '$slideRight'
}
}
Compiles to:
@keyframes keyframes-slideRight-0 {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.container-1 {
animation-name: keyframes-slideRight-0;
}
Fallbacks
const styles = {
container: {
background: 'linear-gradient(to right, red 0%, green 100%)',
fallbacks: {
background: 'red'
}
}
}
Or if you need multiple fallbacks for the same property name:
const styles = {
container: {
display: 'flex',
fallbacks: [{display: 'box'}, {display: 'flex-box'}]
}
}
Compiles to:
.container-0 {
background: red;
background: linear-gradient(to right, red 0%, green 100%);
}
Font Face
const styles = {
'@font-face': {
fontFamily: 'MyWebFont',
src: 'url(webfont.eot)'
}
}
Compiles to:
@font-face {
font-family: 'MyWebFont';
src: url('webfont.eot');
}
// Multiple font faces.
const styles = {
'@font-face': [
{
fontFamily: 'MyWebFont',
src: 'url(webfont.eot)'
},
{
fontFamily: 'MySecondFont',
src: 'url(webfont2.eot)'
}
]
}
Compiles to:
@font-face {
font-family: 'MyWebFont';
src: url('webfont.eot');
}
@font-face {
font-family: 'MySecondFont';
src: url('webfont2.eot');
}
// Font-Face with src fallbacks.
const styles = {
'@font-face': {
fontFamily: 'MyWebFont',
src: 'url(webfont.eot)',
fallbacks: [
{src: 'url(webfont.eot?#iefix) format(embedded-opentype)'},
{src: 'url(webfont.woff2) format(woff2)'}
]
}
}
Compiles to:
@font-face {
font-family: 'MyWebFont';
src: url('webfont.eot');
src: url(webfont.eot?#iefix) format(embedded-opentype);
src: url(webfont.woff2) format(woff2);
}
Basic at rules
const styles = {
'@charset': '"utf-8"',
'@import': 'url(http://mysite.com/custom.css)',
'@namespace': 'url(http://mysite.com/xhtml)'
}
Compiles to:
@charset "utf-8";
@import url(http://mysite.com/custom.css);
@namespace url(http://mysite.com/xhtml);
Alternative syntax for space and comma separated values
To describe space or comma separated CSS values in a JavaScript way, we introduced an array based syntax.
There are some advantages to using this syntax:
- Plugin
jss-plugin-default-unitis able to set default unit effectively for numeric values. - You can use variables inside of a value declaration without string templates or concatenations.
Comma separated values
const styles = {
button: {
// Comma separated value with regular CSS strings inside.
background: ['url(image1.png)', 'url(image2.png)']
}
}
Compiles to:
.button-0 {
background: url(image1.png), url(image2.png);
}
const styles = {
button: {
// Comma separated value with space separated values inside.
background: [
// Numbers can become default unit automatically.
['url(image1.png)', 'no-repeat', 'top'],
['url(image1.png)', 'no-repeat', 'right']
]
}
}
Compiles to:
.button-0 {
background: url(image1.png) no-repeat top, url(image1.png) no-repeat right;
}
Space separated values
const styles = {
button: {
// Space separated value.
margin: [[5, 10]]
}
}
Compiles to:
.button-0 {
margin: 5px 10px;
}
Modifier "!important"
const styles = {
button: {
color: [['red'], '!important'],
margin: [[5, 10], '!important']
}
}
Compiles to:
.button-0 {
color: red !important;
margin: 5px 10px !important;
}
Property "content"
When assigning a string to the content property, it requires double or single quotes in CSS. Therefore you also have to provide the quotes within the value string for content to match how it will get represented in CSS.
const styles = {
button: {
'&:after': {
content: '"JSS"'
}
}
}
Compiles to:
.button-0:after {
content: 'JSS';
}
Working with colors
You can use any color conversion tool, e.g. this one.
import color from 'color'
const styles = {
button: {
color: color('blue').darken(0.3).hex()
}
}
Compiles to:
.button-0 {
color: '#0000B3';
}
Typed CSSOM
JSS supports Typed CSSOM (Houdini) values. You can learn more about them here and track the standardization progress here. Also, make sure you use a polyfill for browsers without support. It will make the most sense when used together with function values and observables for frequent updates.
const styles = {
button: {
margin: CSS.px(10)
}
}
Here is an example that makes use of typed values API to update a value and avoid CSS parsing.