Photo by KOBU Agency on Unsplash
We have build DeckDeckGo in a relatively fragmented way š . There is our web editor, which can be used to create and showcase slides and which can also be automatically synchronized with our remote control. There is also a developer kit, which supports HTML or markdown and there is even another version of it, we only used to deploy online your presentations as Progressive Web Apps.
All these multiple applications and kits have in common the fact that they share the exact same core and features, regardless of their technologies, thanks to Web Components made with Stencil.
These do also have to share the same layout capabilities. For example, if we define a 32px root font size in full screen mode, it should be applied anywhere and therefore, should be spread easily and consistently across our eco system.
Thatās why we had to create our own custom CSS library and why I am sharing with you, how you can also bundle such a utility for your own projects.
Credits
This solution is the one implemented by the CSS framework Bulma. No need to reinvent the wheel when it is already wonderfully solved. Thank you Bulma for being open source š.
Getting Started
To initialize our library, we create a new folder, for example bundle-css
, and are describing it with a new package.json
file. It should contain the name of the library, its version, which is the main file, in our case an (upcoming) sass
entry file, the author and a license. Of course, you can add more details, but these give us a quick basis.
{
"name": "bundle-css",
"version": "1.0.0",
"main": "index.scss",
"author": "David",
"license": "MIT"
}
In a new folder src
we create our style sheet file index.scss
. As I was mentioning the fullscreen
mode in my introduction, we can for example add a full screen specific style to our file to apply a blue background to the children paragraphs of a āmainā element.
:fullscreen #main {
p {
background: #3880ff;
}
}
Clean output
We might probably want to ensure that every time we build our lib, the outcome does not contain any previous style we would have deleted previously.
Thatās why we firstly add rimraf to our project to delete the output folder at begin of each build.
npm i rimraf -D
Note that all dependencies we are adding to our project have to be added as development dependencies because none of these are part of the output.
Once rimraf installed, we can initiate our build
by editing the scripts
in package.json
.
"scripts": {
"build": "rimraf css"
}
I selected css
for the name of the output folder which will contains the CSS output. You can use another name, what does matter, is adding it to the file package.json
in order to include it in the final bundle you might later install in your app or publish to npm.
"files": [
"css"
]
At this point, altogether, our package.json
should contains the following:
{
"name": "bundle-css",
"version": "1.0.0",
"main": "index.scss",
"scripts": {
"build": "rimraf css"
},
"files": ["css"],
"author": "David",
"license": "MIT",
"devDependencies": {
"rimraf": "^3.0.2"
}
}
SASS
We are using the SASS extension to edit the styles. Therefore, we have to compile it to CSS. For such purpose, we are using the node-sass compiler.
npm i node-sass -D
We enhance our package.json
with a new script, which should take care of compiling to CSS, and we are chaining it with our main build
script.
"scripts": {
"build": "rimraf css && npm run build-sass",
"build-sass": "node-sass --output-style expanded src/index.scss ./css/index.css"
}
We provide the input file and specify the output as compilation parameters. We are also using the option expanded
to determine the output format of the CSS. It makes it readable and, as we are about to minify it at a later stage of the pipeline, we do not have yet to spare the size of the newlines.
If we give a try to our build script by running npm run build
, we should discover an output file /css/index.css
which has been converted from SASS
to CSS
.
:fullscreen #main p {
background: #3880ff;
}
Autoprefixing
In order to support older browser and Safari, it is worth to prefix the selector :fullscreen
. This can also be the case for other selectors. To parse automatically CSS and add vendor prefixes to CSS rules, using values from Can I Use, we are using autoprefixer.
npm i autoprefixer postcss-cli -D
We are now, again, adding a new build script to our package.json
and are chaining this step after the two we have already declared because our goal is to prefix the values once the CSS has been created.
"scripts": {
"build": "rimraf css && npm run build-sass && npm run build-autoprefix",
...
"build-autoprefix": "postcss --use autoprefixer --map --output ./css/index.css ./css/index.css"
}
With this new command, we are overwriting the CSS file with the new values, and are generating a map
file which can be useful for debugging purpose.
If we run our build pipeline npm run build
, the output css
folder should now contain a map
file and our index.css
output which should have been prefixed as following:
:-webkit-full-screen #main p {
background: #3880ff;
}
:-ms-fullscreen #main p {
background: #3880ff;
}
:fullscreen #main p {
background: #3880ff;
}
/*# sourceMappingURL=index.css.map */
Optimization
Less is always better, thatās why we are in addition optimizing our CSS library with the help of clean-css.
npm i clean-css-cli -D
By adding a last script to our chain, we are able to create a minified version of our CSS file.
"scripts": {
"build": "rimraf css && npm run build-sass && npm run build-autoprefix && npm run build-cleancss",
...
"build-cleancss": "cleancss -o ./css/index.min.css ./css/index.css"
}
If we run one last time npm run build
we should now discover the minified version of our input CSS in the output folder css
.
:-webkit-full-screen #main p {
background: #3880ff;
}
:-ms-fullscreen #main p {
background: #3880ff;
}
:fullscreen #main p {
background: #3880ff;
}
Altogether
Summarized, hereās the package.json
which contains all dependencies and build steps to create our own custom CSS library.
{
"name": "bundle-css",
"version": "1.0.0",
"main": "index.scss",
"scripts": {
"build": "rimraf css && npm run build-sass && npm run build-autoprefix && npm run build-cleancss",
"build-sass": "node-sass --output-style expanded src/index.scss ./css/index.css",
"build-autoprefix": "postcss --use autoprefixer --map --output ./css/index.css ./css/index.css",
"build-cleancss": "cleancss -o ./css/index.min.css ./css/index.css"
},
"files": ["css"],
"author": "David",
"license": "MIT",
"devDependencies": {
"autoprefixer": "^9.8.4",
"clean-css-cli": "^4.3.0",
"node-sass": "^4.14.1",
"postcss-cli": "^7.1.1",
"rimraf": "^3.0.2"
}
}
Summary
Thanks to many open source projects it is possible to create quickly and easily a library for our custom CSS, thatās amazing.
Give a try to DeckDeckGo for your next talk and if you are up to contribute with some improvements to our common deck styles build following above steeps, your help is more than welcomed š.
To infinity and beyond!
David