@xhtm/css
v0.1.2
Published
lightweight css-in-js solution for xhtm applications
Downloads
4
Readme
css
lightweight css-in-js solution for xhtm applications
Features
- lightweight solution suitable for slow 3G connections
- framework independent use it with or without a framework
- optimal css output style encapsulation, deduplication, dead code elimination
- css features Media Queries (@media (orientation: portrait)), Pseudo-element and Pseudo-classes (::before, :hover, :last-child), Nested child styles (> h1, > +)
Usage
import { css, keyframes } from '@xhtm/css';
/** Basic Properties */
const border = css({ border: '1px solid red' }); // const border = 'a'
/** Style Deduplication and Reuse */
const duplicate = css({ border: '1px solid red' }); // const duplicate = 'a'
/** Skip null styles */
const nulls = css({ background: null }); // const nulls = ''
/** Pseudo Classes */
const hover = css({
fontSize: '48px',
color: 'tomato',
':hover': { color: 'black' },
}); // const hover = 'b c d'
/** Pseudo Elements */
const before = css({ '::before': { content: '" * "' } }); // const before = 'e'
/** Media Queries */
const media = css({
'@media only screen and (min-width: 500px)': { color: 'red' },
}); // const media = 'f'
/** Media Queries with Nested Pseudo Classes */
const mediaNested = css({
'@media only screen and (min-width: 500px)': {
color: 'red',
backgroundColor: 'yellow',
':hover': { backgroundColor: 'papayawhip' },
},
}); // const mediaNested = 'f g h'
/** Other at Rules */
const supports = css({
'@supports (display: flex)': {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
}); // const supports = 'i j k'
/** Complex Nested Rules */
const supportMedia = css({
'@supports (display: flex)': {
'@media only screen and (min-width: 500px)': {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
':hover': { backgroundColor: 'red' },
},
},
}); // const supportMedia = 'l m n o'
/** Animation using `keyframes` */
const animation = keyframes({
from: { backgroundColor: 'red' },
to: { backgroundColor: 'yellow' },
}); // const animation = 'p'
const box = css({
width: '100px',
height: '100px',
animation: `${animation} 1s linear infinite alternate`,
}); // const box = 'q r s'
Motivations
- The idea of css-in-js (or virtual CSS) can have tremendous impact on CSS size shipped over the wire.
- Many css-in-js solutions that exist today focus too much on specific frameworks, which increases the compatibility problem with modern web components standards. This solution tries to elevates the problem by being compatible.
Tradeoffs
- Being framework independent, we do not support component API like Styled Components. This can lead to some inconviniences when implementing a framework specific abstraction like a shared component library. This however is intentional. The styled API IMO makes it hard to tree shake userland code and also increases the footprint of this library. And, more often than not, the resultant code often leads to un-necessary DOM nodes being created to ensure proper style encapsulation.
Enhancements/Roadmap
- [ ] CSS Autoprefixing Support with minimal footprint.
- [ ] Typescript Support and autocompletion for CSS properties.
- [ ] I want to explore what static extraction for CSS might look like. With atomic CSS approach being followed here, a complimentory babel plugin can save a lot on shipped CSS file size
Acknowledgement
@xhtm/css
is heavily inspired by cxs and picostyle
Contributing
Scaffolded using tslib-cli
.
Run yarn
or npm install
in root folder to setup your project.
Available Commands:
yarn build # builds the package
yarn test # run tests for the package
yarn coverage # run tests and generate coverage reports
yarn pub # publish to NPM
yarn format # prettier format
yarn lint # lint pkg files
yarn setup # clean setup