Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 10, 2022 05:57 pm GMT

Write Atomic CSS like Facebook with Stylify

Pixel perfect webdesign, atomic CSS, mangled selectors and minimalistic output? Yes !

Some time ago during a coffee break I have been digging through the Facebook CSS. I checked multiple pages, downloaded the CSS from them and got an idea on a tool that could simplify the way I write the CSS.

Laziness is a great thing. It leads people to simplify their work so in the end they have to do nothing. It also led me to create the https://stylify.dev .

When I have been digging through the Facebook code, I found the following.

Html:

CSS:

If you take a closer look, you can see, that they are using atomic CSS and they mangle selectors.

I have also found an article Rebuilding our tech stack for the new Facebook.com from Facebook itself in which they explain what have they changed for the new Facebook version. What the article also says is that they have been loading over 400 kB of compressed CSS and before switching to Atomic CSS.

From my experience, writting CSS manually is just slow and time consuming. Component frameworks are great until you start transforming every component. The Tailwind's JIT is close enough, but I don't like when I have to remember or search for the selector I want to use. I also need smaller chunks and integrate it into existing projects without increasing their size.

So the objective was clear. Create a tool that will be able to:

  • Generate CSS separately according to content
  • Mangle selectors
  • Generate CSS on demand
  • Use native CSS properties:values as selectors by default
  • Work on its own without bundlers, frameworks and post/preprocessors

Atomic CSS with Stylify

Stylify ships with the native preset in which the selectors are the same like CSS property:value. Thanks to that it is not necessary to remember or search for selectors. The Native Preset is optional and you can define your own selectors. Stylify also provides the following features (not all are listed):

  • Small chunks: it can generate CSS for each file, component, layout separately
  • No pregenerated CSS: the CSS is generated only if a component or selector is found in the content
  • Internaly combines and reuses selectors as much as possible to keep the CSS small
  • Macros: can be used to define custom selectors like m:20px for margin
  • Logical operands for screens: like && and || operands for screens combination: sm&&tolg:font-size:24px
  • Selectors mangling: from long font-weight:bold to short _ab
  • No preprocessor, postprocessor or bundler is required
  • On demand generated CSS: the CSS can be bundled on demand, for example during a request
  • Because it can generates CSS separately and doesn't bring any CSS by default, it can be easily integrated into an existing project without increasing its size globally

Write HTML. Get CSS. Mangle selectors. All automagically.

The example bellow and all its code can be found and edited on the StackBlitz.

In the example bellow there is a code for simple gallery image:

<div class="    display:inline-flex    position:relative    margin:24px    overflow:hidden    box-shadow:0__2px__8px__#000    width:300px    md:margin:48px    md:width:600px">    <img class="width:100% object-fit:cover height:auto" src="https://stylify.dev/images/blog/stylify-facebook/mountains.jpg" alt="">    <div class="        font-family:arial        font-weight:bold        font-size:18px        position:absolute        bottom:0        left:0        padding:24px        background:rgba(0,0,0,0.7)        color:#fff        md:font-size:32px    ">        Zakopan (Poland)    </div></div>

The result of the code above will look like this:



The code above would look almost the same if it would be written in pure CSS. Only the box-shadow uses the __ (two underscores) instead of a space.

Because of the maintainability and the fact that code above could be used on multiple places, it is necessary to make it more reusable. So let's define some components, macros and variables!

Cleanup and Configuration

For the example above, I am using the following initialization that can be found on the StackBlitz (It is in the index.js and it is slightly changed in order to work in that environment):

import { Compiler, nativePreset } from '@stylify/stylify';const content = '';const compiler = new Compiler(nativePreset.compiler);const compilationResult = compiler.compile(content);const css = compilationResult.generateCss();const mangledContent = compiler.rewriteSelectors(content, compilationResult);

Let's add the shadow variable first into the compiler config:

nativePreset.compiler.variables: {    shadow: '0 2px 8px #000'};

When the variable is defined, we can use it like this: box-shadow:$shadow.

The Native Preset is not required. You can define your own selectors. For example for the margin it would look like this:

nativePreset.compiler.macros['m:(\\S+?)'] = (macroMatch, cssProperties) => {    cssProperties.add('margin', macroMatch.getCapture(0));};

When the macro is defined, it can be used with custom values like m:24px and md:m:48px.

If multiple and the same selectors should be used on multiple places, it is a good practice to define a component for them in order to simplify the maintainability and readability:

nativePreset.compiler.components = {    'gallery-image__wrapper': `        display:inline-flex        position:relative        m:24px        md:m:48px        overflow:hidden        box-shadow:$shadow        width:300px        md:width:600px    `,    'gallery-image': 'width:100% object-fit:cover height:auto',    'gallery-image__label': `        font-family:arial        font-weight:bold        font-size:18px        position:absolute        bottom:0        left:0        padding:24px        background:rgba(0,0,0,0.7)        color:#fff        md:font-size:32px    `};

It is also a good practice to add the box-sizing:border-box to prevent the wtf moments somewhere in the future:

nativePreset.compiler.plainSelectors: {    '*': 'box-sizing:border-box'};

With all the enhancements above, the finall code is a way smaller:

<div class="gallery-image__wrapper">    <img class="gallery-image" src="https://stylify.dev/images/blog/stylify-facebook/mountains.jpg">    <div class="gallery-image__label">        Zakopan (Poland)    </div></div>

Minification and Optimization

Under the hood the Stylify optimizes the CSS in the following ways:

  1. The selectors and components are generated only when found in the content
  2. It tries to reuse the selectors as much as possible
  3. It transforms the long selectors like font-weight:bold into the short ones _ab12

Bellow is an image from StackBlitz with the processed and optimized output. The css (without new lines and spaces) has only 0.78kb:

Let me know what you think!

Stylify took a year of development and the first release was published a month ago.
I will be very happy for any feedback, issue or an idea! .

Stay in touch:
8machy
dev.to/machy8
medium.com/@8machy


Original Link: https://dev.to/machy8/write-atomic-css-like-facebook-with-stylify-2074

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To