The (highly biased) case against CSS preprocessors

Everybody who’s anybody is using CSS preprocessors!

Or so it feels. I’m an old-school vanilla CSS curmudgeon, and the more I’ve dipped my toes into working with CSS preprocessors (specifically, SCSS with Compass), the less I like them.

As I see it, there are three main problems with vanilla CSS:

No variables. Honestly this is probably the only problem I really have with CSS. I’d like to be able to set variables for things like colors that I use throughout a site. To a lesser extent, I see the benefit of “mixins” — reusable chunks of CSS.

Redundant code. It really depends on how you conceptualize your CSS structures, but it is very easy to fall into a habit of writing the same CSS code over and over again, resulting in bloated, hard to maintain files. While I am guilty of this just like anyone else, I find that if you format your CSS code properly you can combine properties efficiently to avoid redundancy without needing any external solutions.

Lack of programmatic logic. Here I’m thinking about things like conditional statements, and also math operations. This is probably as much of a strength as a weakness. CSS is a stylesheet, not a program. It’s a set of rules to be applied to formatting a document. There’s nothing programmatic about it. But still, as CSS selectors become more complicated and convoluted, it is clear that in some cases light programming logic would be helpful.

The real question is, do CSS preprocessors actually solve these problems? Or, more specifically, do they solve them without introducing new problems that are at least as bad as the ones they’re trying to fix?

For me the answer has been, and continues to be, no, they don’t. But I’m trying to get a more tangible explanation for why that is, rather than the simple gut feeling that’s been driving me away from using them up to this point.

What are other people saying?

My first stop in trying to answer this question of why I dislike CSS preprocessors was Google. I wanted to see what other people were saying, pro and con. Here are some interesting blog posts I found, going back a few years to the early (or at least earlier) days of CSS preprocessors:

The problem with CSS pre-processors
This article by Miller Medeiros was the first one I came across a few months ago when I initially pondered this question, and at the time it was all I needed to satisfy myself that I was not crazy for wanting to avoid CSS preprocessors.

So, assuming preprocessors do solve the problems with vanilla CSS, what are the problems they introduce? And how bad are they, really?

I need to get specific to my own situation for a minute here. I have a former coworker who is a firm believer in SCSS, and now that he’s gone, I’m left to maintain and extend the code he was writing. This experience casts my aversion to CSS preprocessors into stark relief.

Maintenance can be a challenge

The most obvious issue with using a preprocessor is that the output CSS is not exactly easy to hand edit, and worse, you shouldn’t hand edit it, because your changes don’t end up back in the original SCSS (or whatever format you’re using) files. If someone else goes back in later and edits the original SCSS and generates new CSS, your changes will get lost.

But let’s set that matter aside for a minute. In a broader sense, one of the key challenges for any web developer is to build code that is easy to maintain. Not just for you to maintain, but for whoever comes after you to maintain. Face it, you’re not going to be working on this project forever. At some point, someone else is either going to need to take it over, or throw away what you did and start fresh.

If you’ve ever jumped into an existing project midstream, or been handed the task of maintaining something someone else built — especially if it’s something built by someone who is no longer around to answer your questions — you know that it’s rarely an ideal situation. Even if the previous developer left copious documentation, it can take hours of picking apart their code to really get a firm understanding of how it all works. This is true with plain CSS too, but at least with plain CSS it’s a lot less work to track down a particular piece of troublesome code.

It’s non-standard

What happens when certain features of your favorite preprocessor get rolled into a future version of vanilla CSS? What happens if similar (but incompatible) features of a different preprocessor become the standard? In short, what if everything you’re doing right now becomes obsolete? How long are you going to hang on to doing things your old way with your no-longer-relevant preprocessor, before you have to scrap it and start over, or at least rewrite big chunks of your code to fit the new way everyone is doing things?

Call me a curmudgeon, but having been a professional web developer for over 18 years I’ve seen a lot of technologies and design trends come and go. I’ve always been skeptical of anything non-standard. I never used VBScript or ActiveX, I never embraced Flash, and in general I’ve done everything I could to both champion and adhere to open standards as much as possible throughout my career.

Suffice to say, resisting CSS preprocessors is just in my blood. They just don’t feel right to me. I’d rather do without features I want, if they’re not part of the standard, than resort to a non-standard workaround to make them happen… especially if it looks like there’s a reasonable chance they’ll be added to the standard at some point in the not-too-distant future.

Please, web font vendors, learn how to use CSS @font-face properly!

This has been bugging me for years and I can’t believe it’s still happening.

Being able to use custom fonts has been a huge boon to web design. And font hosting services like Typekit (sorry, I will never call it Adobe Fonts) and Google Fonts make using custom fonts easy.

But sometimes you still buy a font license that involves hosting the font files directly on your own server, and that’s where things get absolutely maddening because, for some reason, someone early on grossly misinterpreted how to use @font-face and that error has been perpetuated by countless unthinking others.

(Yes, I’m being harsh. But this is really not that complicated. And getting it right makes writing your CSS and HTML so much easier.)

Here’s an example of some font-specifying CSS you might receive from a font vendor:

@font-face {
    font-family: 'Font-Name-Regular';
    src: url('Font-Name/Font-Name-Regular.woff2') format('woff2'),
         url('Font-Name/Font-Name-Regular.woff') format('woff');
    font-weight: normal;
    }
.Font-Name-Regular {
    font-family: 'Font-Name-Regular';
    }

@font-face {
    font-family: 'Font-Name-Regular';
    src: url('Font-Name/Font-Name-Regular-Italic.woff2') format('woff2'),
         url('Font-Name/Font-Name-Regular-Italic.woff') format('woff');
    font-weight: normal;
    font-style: italic;
    }
.Font-Name-Regular-Italic {
    font-family: 'Font-Name-Regular';
    font-style: italic;
    }

@font-face {
    font-family: 'Font-Name-Bold';
    src: url('Font-Name/Font-Name-Bold.woff2') format('woff2'),
         url('Font-Name/Font-Name-Bold.woff') format('woff');
    font-weight: normal;
    }
.Font-Name-Bold {
    font-family: 'Font-Name-Bold';
    }

@font-face {
    font-family: 'Font-Name-Bold';
    src: url('Font-Name/Font-Name-Bold-Italic.woff2') format('woff2'),
         url('Font-Name/Font-Name-Bold-Italic.woff') format('woff');
    font-weight: normal;
    font-style: italic;
    }
.Font-Name-Bold-Italic {
    font-family: 'Font-Name-Bold';
    font-style: italic;
    }

This is, in fact, the exact code I just received yesterday from a font vendor when I purchased a license, with the actual font name removed to protect the guilty innocent.

What’s so bad about this, you might ask? Aside from the conventions I dislike of indenting the closing } and using 4 spaces instead of tabs, there are two glaring problems with this:

  1. Because the font-family name defined for each weight and style is different, when you go to use this font, you need to specify the font-family every time you want to use bold or italics in your HTML, or at least use the custom CSS classes defined here. No! No no no! You should not have to apply a class to get bold or italics to render properly. The <strong> and <em> tags should do that on their own!
  2. Don’t f***ing define a bold font with font-weight: normal;! If you don’t realize from this, alone, that something is wrong with your approach, stop coding right now.

So, how should this be done, you ask?

Well, it’s simple. Each @font-face declaration has four properties. One is src: which tells the browser where to find the correct font file(s) for this face. The other three properties work together to define the context in which this particular src should be used: any time this combination of font-family, font-weight and font-style come together.

You can use the same font-family in different @font-face declarations as long as font-weight and font-style are different. In fact, you’re supposed to! That’s the way it’s designed to work!!!

When you do this properly, you don’t need any custom CSS classes. Try this on for size:

@font-face {
    font-family: 'Font-Name';
    src: url('Font-Name/Font-Name-Regular.woff2') format('woff2'),
         url('Font-Name/Font-Name-Regular.woff') format('woff');
    font-weight: normal;
}

@font-face {
    font-family: 'Font-Name';
    src: url('Font-Name/Font-Name-Regular-Italic.woff2') format('woff2'),
         url('Font-Name/Font-Name-Regular-Italic.woff') format('woff');
    font-weight: normal;
    font-style: italic;
}

@font-face {
    font-family: 'Font-Name';
    src: url('Font-Name/Font-Name-Bold.woff2') format('woff2'),
         url('Font-Name/Font-Name-Bold.woff') format('woff');
    font-weight: bold;
}

@font-face {
    font-family: 'Font-Name';
    src: url('Font-Name/Font-Name-Bold-Italic.woff2') format('woff2'),
         url('Font-Name/Font-Name-Bold-Italic.woff') format('woff');
    font-weight: bold;
    font-style: italic;
}

Aside from the fact that this eliminates 1/3 of the lines of code, it also will make your HTML much cleaner and more properly separates content from styling.

Here’s an example of some HTML you might have to write using the first approach:

<p class="Font-Name-Regular">This is some regular text, which also
includes a bit of <em class="Font-Name-Regular-Italic">italics</em>
and even a dash of <strong class="Font-Name-Bold">bold</strong>.</p>

Now, granted, my version does require you to define the font-family for your <p> tags in your CSS file. But guess what… you’re supposed to do that! Put this in your CSS:

p { font-family: 'Font-Name'; }

With that in place, the proper HTML for the same appearance becomes this:

<p>This is some regular text, which also
includes a bit of <em>italics</em>
and even a dash of <strong>bold</strong>.</p>

So, again… when thinking about @font-face, just remember these two simple things:

  1. All @font-face declarations for the same font family should have the same font-family. (Seems kind of obvious when I put it that way, doesn’t it?)
  2. The value for font-weight should be the actual weight of the font. Only the “regular” weight should have font-weight: normal; or font-weight: 400;. If you’re using font-weight: normal; on a bold font, you’ve done something wrong.

This change makes for cleaner code, easier maintenance, and proper separation of content from design.

Addendum

Shortly after I posted this, I went back and looked at the unnamed font vendor’s sample page, because I knew it referenced “the @font-face standard since 2017”. I could not believe that this approach was actually a “standard,” so I tracked down the source, an article Bram Stein published on A List Apart in 2017 called Using Webfonts.

Guess what… Bram Stein’s examples do it the right way!

I do know one place where I’ve consistently seen this wrong way I’m railing against… it’s the code generated on FontSquirrel (no link, on principle) whenever you download a font. Other “web font generator” sites like FontSquirrel probably do it to. They’re all wrong… but Bram Stein isn’t. Don’t drag him down with this bad code!

Tips on saving vector images from Adobe Illustrator for SVG web use

With Internet Explorer 8 end of life coming on January 12, all kinds of new possibilities are opening up to us web developers who can finally start making use of technologies that have had wide support in modern browsers for years, but that we were reluctant to embrace because of the need for IE8-friendly workarounds.

For me, one of those things is SVG images. In recent years, especially since Responsive Web Design (and high-resolution displays) took off, I’ve been receiving web designs more and more in Illustrator format, rather than Photoshop. It’s great to get these assets as vectors that I can scale and size as I need in my build-out of high-res, responsive websites. But until now I had still been pulling vector assets over into Photoshop and producing multiple carefully-sized versions of things like logos and custom icons.

Now, however, SVG is a viable — in fact, preferable, given its flexibility and smaller file size (plus the ability to hack the XML code right in the image files themselves) — alternative to multiple PNGs of every image.

The thing is, while I have been using Photoshop extensively for over 20 years, I’ve never really gotten the hang of Illustrator. I know just enough to go into an Illustrator file, pull out the assets I need, and try not to screw anything else up in the process. That’s what this article is for.

Over the past week I have pulled a number of vector assets out of Illustrator designs as SVGs for a couple of projects, and I’m starting to get the process down. Here’s what you need to know.

The Steps

1. Select the object you want to make into an SVG. Most of the time designers will have grouped the pieces of the object together, so just a single click on the object will select it. Make careful note of the blue outlines to be sure everything you want is selected (and maybe even more importantly, that nothing else you don’t want is). You can also click and drag to select all objects within an area, or use the Layers palette to select the elements. This can be tedious, but be sure you’ve got what you need — and only what you need — highlighted. Once it’s selected, copy it to your clipboard.

2. Create a new document in Illustrator. Default settings are fine. Once the blank document appears, paste in the copied object. It should appear centered in the document. There should be a ton of space around it. That’s good. Since we’re dealing with vector art, scale is irrelevant. You just want to make sure everything fits within the boundaries of the document. (The “artboard” if you’re familiar with Illustrator speak.) Keep the object selected (blue outline). If you deselected it, just Select All.

3. Shrink the artboard to fit the object. If you don’t do this, you’ll end up with a bunch of blank space within the defined dimensions of the image and it will be impossible to work with. Good thing it’s super easy. With the entire object selected, go to Object > Artboards > Fit to Selected Art and you’ll get a perfect container.

4. IMPORTANT! If there are transparency effects within the object, you need to flatten it now. A lot of the time you can skip this step. But if you do, you may find that parts of the design are missing in the resulting SVG. I found it’s easy to forget this; I don’t find it intuitive that this would get lost in the SVG conversion. So go to Object > Flatten Transparency… Review the settings here to ensure you’re happy with them (sorry, I don’t have a lot of guidance here), and click OK Your image should not look different. If it does, undo, and repeat with different settings in the Flatten Transparency dialog.

5. Save. There’s no “Save for Web” option for SVG. Just regular ol’ “Save As”. Be sure to set the Format menu to SVG (svg). You could try compressed, but really SVGs are pretty small anyway, and I like to keep the code editable so I can tinker with it if needed. (Changing the color fill, for instance.) Once again there are a ton of settings presented in the SVG Options dialog, but I’ve found the default settings seem to work fine. (One change I have made is to set CSS Properties to Presentation Attributes but I’m not entirely sure yet what difference it makes.)

That’s it! You should now have an SVG ready for placement using an <img> tag, or as background-image in CSS. Just note that CSS treats SVG images a bit differently than regular JPEGs and PNGs, so you may need to add a few extra properties to keep the SVGs within their container elements in your page.

Fixing background “bleed” on elements that use CSS3 border-radius property

It’s kind of funny that I never encountered this problem before… it must just be extra-noticeable because of the colors on this particular website I’m working on. Anyway, I found that the nice buttons I was creating with CSS3 border-radius were displaying an ugly “bleed” of the background dark blue color beyond the edges of the white border. No good.

before

A little googling led to Mike Harding’s solution, a simple background-clip property in the CSS. (Yet another of the preponderance of new properties in CSS3 that I’m finding it harder and harder to keep up with.) If w3schools.com is to be believed, the vendor prefix is unnecessary. Let’s just go with this:

background-clip: padding-box;

Ah, that’s better!

after