I have a static Jekyll website.

The website is constructed once, on my computer, and then sent to the server in the form of plain HTML, image, and CSS files, to be served by a regular HTTP server.

This construction process involves a template engine that has to glue various components together.

For example, this is the template for my posts and pages (the only other template I have is for the main page, which shares quite a lot with this one):

<!DOCTYPE html>
        {% include head.html %}
        <link rel="stylesheet" href="/css/main.css">
        {% if page.title == "Tautological Cascade" %}
            <title>Tautological Cascade</title>
        {% else %}
            <title>Tautological Cascade: {{ page.title }}</title>
        {% endif %}

        <div class="site" >
            {% include header.html %}
            {{ content }}
            {% include footer.html %}

The most important part to notice here is the body section. It basically sandwiches a processed markdown file between two HTML files.

Currently, I only have one, main CSS file, which is used by ALL pages.

I find this approach a bit unpractical. Everything is defined in there, and it's getting messy. Couple that with my general ignorance of anything but the basic CSS, and you get something close to a nightmare.

My idea is this: inline CSS for all of these parts that I glue together.

So header.html would have its CSS in its file, footer.html would have its CSS, and the file that describes the content int its own.

Is this the correct solution to my problem? Is there something wrong with this approach?

  • 2
    My gut instinct is:- if your intention is to mix content and markup then it's definitely the opposite of the intention of CSS and you're doing something wrong. – James Snell Oct 14 '13 at 20:54
  • Scoped styles that only apply to a subtree of the DOM are in the HTML 5 spec, but it's sadly not available aside from FF. Ergo it doesn't really matter if you divide your CSS. – amon Oct 14 '13 at 21:07

You have the right problem identified, but there's a better solution.

You're allowed to include as many CSS files as you need in your <head> tag. So all you need to do is add an extra bit of logic up there to grab the appropriate CSS for a given page.

    {% include head.html %}
    <link rel="stylesheet" href="/css/main.css">
    {% if page.css != "" %}
        <link rel="stylesheet" href="/css/{%page.css%}">
    {% endif %}
    {% if page.title == "Tautological Cascade" %}
        <title>Tautological Cascade</title>
    {% else %}
        <title>Tautological Cascade: {{ page.title }}</title>
    {% endif %}

Then each page can define any special CSS it needs, separately from everything else. Just don't go too far in this direction, to the point that you're duplicating your styles between pages' specific .css files.

  • If I made any mistakes with the syntax, feel free to correct them. I don't actually use Jekyll, so I can't be sure that I added that right. It should be clear what I intended, though. – Bobson Oct 14 '13 at 21:32
  • great solution. – sova Feb 24 '15 at 19:28

Inlining CSS is a necessary evil for HTML-formatted e-mails because of poor client support for stylesheets, but for web pages it's preferable to find an approach which structures your CSS but keeps it separate from the HTML. This allows browsers to cache it separately.

There are three main approaches.

  1. Link to multiple stylesheets from your <head>, as mentioned by Bobson.
  2. Split your stylesheets into self-contained sections and link them together with @import.
  3. Use a CSS preprocessor. (Since you're using a Ruby tool to build your site, you'd probably want to use SASS. This allows you to work with a much simpler source file, because it factors out a lot of the redundancy that CSS has.

These approaches can also be combined.

  • +1 for SASS. Think this is what CSS should have been all along – razethestray Feb 24 '15 at 20:55

The problem with that approach is that either you duplicate most of the same styles in footer.css and header.css or you'll have to include a common.css stylesheet in both the footer and the header, which most likely would still contain the bulk of the stylings.

The approach I often take is to have a style sheet called cbc.css strictly for guaranteeing same styles across multiple browsers. It is an ugly bit of styling which usually involves setting the padding to 0 and things of that sort. It also contains any browser-specific stylings in order to start off on the same page.

All theme-related stylings go in common.css. It should not refer to any ids specifically, and, if I can help it, it should not refer to classes either (if you find yourself using classes as ids, it doesn't belong here). The idea is that with cbc.css, most of your styles should already be set. Save for structure and things specific to the layout of the page, it should already look like the final product.

Then, each included page has stylings for only that page or any page it includes within it, usually referred by id or by class if you use it in more than one spot (but not outside of that page, otherwise it belongs in common.css).

When I do it like this, common.css is fairly clean. I won't say it is small, but it is uncluttered and easy to maintain, which is the idea. You know that if you want to change a style that would have an impact on everything, you change common.css. If you want to change the structure of that particular page, you look for <page name>.css.

I hope that helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.