Search code examples
javascriptcsscss-frameworks

Generating CSS stylesheet using JS


I was recently attempting to build an extremely minimalistic, lightweight css framework (something like Pure CSS).

On inspecting my code, one of my friends suggested that I generate my CSS using Javascript, primarily for the significant decrease in file size. The file size would decrease in the following two cases:

  1. The columns classes look something like col-x-12, and JS would be able to calculate the widths and write the column classes using much less code.

  2. I would be able to map CSS attributes in JS (bg for background, for example), thus also reducing file size.

The generated CSS could directly be inserted into the head or added to the CSSStyleSheet.

Apart from the little overhead caused by running the JS, what other problems may this approach cause?


Solution

  • This sounds like a bad idea, for several reasons.

    It's possible that this would result in a smaller file size sent to the user. If file size is your primary concern - maybe you're transmitting over an expensive satellite uplink - then perhaps you'd need to generate your CSS via your JavaScript. But if not, you're going to struggle against several drawbacks for no reason:

    1. Users without JavaScript will get a completely unstyled page. That might be OK, especially if the text is the most important element of your page. But it would be better to follow the principles of progressive enhancement and let anyone using a browser with CSS support get a styled page.
    2. Your styling will be much more fragile. If you ship buggy or invalid JavaScript, your site will be completely unstyled. If your JavaScript contains browser-specific bugs, it will be completely unstyled for those users. If your JavaScript gets blocked by a browser add-on or corporate firewall, your site will be completely unstyled.
    3. Developers have to learn your custom CSS language. Rather than using standard CSS everywhere, your developers have to learn your own proprietary dialect. You can't hire outside experts without giving them time to learn your system.
    4. Developers have to think through an extra abstraction. When your developers write some CSS that doesn't work as intended, they're no longer thinking "How is this CSS being applied?". They have to think "What CSS is being generated from my shorthand? And how is that CSS being applied?". This makes your styling harder to understand and debug, and makes problems take longer to solve.
    5. Debugging CSS problems becomes trickier. If your code is in a normal CSS file, then the browser's debug tools can show you the file name and line number of any CSS rules you're trying to debug. This isn't the case if you're generating your CSS from JavaScript. You might be able to use CSS source maps to overcome this - but now your JS tool has to support generating source maps, too.
    6. You have an extra maintenance burden. Not only must you maintain your CSS, but you must also maintain your tool.
    7. You might not increase perceived load times. Even if you're sending fewer bytes to the browser, your page may be slower (or feel slower). You have two options for when your JavaScript runs:

      • When document.ready fires. This has the drawback that your page will display in an unstyled way before your JavaScript finishes running and the browser finishes redrawing the page with your newly-added style rules.
      • As soon as your <script> tag evaluates in your document's <head>. This avoids displaying the unstyled content, but now the browser has to do a lot of work:

        1. Parse your custom style rules and generate CSS from it.
        2. Generate a DOM element for your styles, and insert it into the page.
        3. Parse those new CSS rules.

        All of these steps have to run before the browser continues loading the page. This means a user will have to wait a little longer before the page is visible.

    8. You don't get caching for free. Your page has to do all that work on each page load - or you have to write your JavaScript in a way that it caches the generated CSS and reuses it if present. If your styling is in a normal CSS file, then the browser will handle caching for you.
    9. It's not cost effective. Computer time is cheap; programmer time is expensive. All the problems above will eat more time in terms of development, maintenance, training, documentation, and testing than they will ever save in page load times.

    So what should you do instead?

    • Make sure your assets are sent gzipped. JavaScript and CSS are just text. As a result, they compress well.
    • Combine and minify your assets. If you have 10 CSS files in your project the browser has to make 10 separate requests for them. Combining those files into one file means the browser only has to make one request. Minification strips out things that humans need but computers don't - comments, spaces, newlines, and descriptive variable names. Google has some tool recommendations for your CSS and JavaScript.
    • Remove unnecessary code. There are tools like UnCSS to help you find unused CSS rules; it's a harder problem in JavaScript, but you may be able to use a code coverage tool to help you.
    • Make sure your assets are cached correctly. Your JS and CSS files don't change regularly, so visitors to your website should only have to retrieve them once. Their browser will cache the files, and reuse them on their next page view.
    • Use a tool like SASS to generate your CSS. It won't help you with your file size, but it can help you write less code. For instance, both Neat and Foundation have grid systems that you can customise via SASS. You can write less code and easily alter your grid settings, and let SASS generate the resulting CSS for you.
    • Don't worry about it. Chances are, your current setup is good enough - or has some areas for easy improvement. If not, there's almost certainly a better use of your time. Maybe it's technical, like adding a new feature or fixing a bug. Maybe it's business-related, like talking to a potential client or tweaking some marketing copy. There's something that will have a far bigger payoff for your project than building this tool.