If you’ve ever done web development, or worked with web developers, you’ve probably heard that CSS is the bane of our existance. To the contrary, I’ve actually begun to really enjoy using CSS, it just took a lot of figuring my way around things.
This article covers some of the things that have helped me to make CSS not just tolerable, but even – dare I say it – enjoyable to use.
I include the following in every website I develop, and I’ve never had problems with it.
By default, browsers use
content-box, this rule sets the
box-sizing mode to
border-box for all elements and pseudo-elements (
:after) on every part of the website. With
box-sizing: content-box, the dimensions of an element can grow to accomodate padding, whereas
border-box retains a fixed height and width with padding being “inset” within the element.
The best way to explain how the two differ is with an image.
If you’re using third-party plugins, scripts, etc. this may cause their layout to break, but it can be overridden on a case-by-case basis as necessary by applying
box-sizing: content-box to the problematic element’s respective CSS selector.
Use a CSS pre-processor
Currently, the two largest CSS pre-processors are SCSS and LESS. Of the two, I would personally recommend SCSS, as LESS has some weird quirks like
calc() not always working as expected because LESS performs the math when processing your stylesheets. So
calc(100vw - 20px) in LESS is delivered as
calc(80px) to the browser. Other than that, they have essentially identical feature-sets.
Why use a pre-processor? They make CSS a lot simpler, and therefore faster to both write and read.
You can take code like this:
And rewrite it like this instead:
With vanilla CSS, you’re not able to nest selectors. SCSS and LESS allow you to do this and a lot more, and they provide no performance hit for the user. CSS written with a pre-processor are “processed”, or compiled, down into vanilla CSS by the server, and that CSS is sent to the client for parsing.
Besides nesting, SCSS also includes variables, functions, mixins, and color modifiers.
Variables are represented by a
$, and can be used anywhere in a stylesheet after being defined.
For more complex websites with more than one stylesheet, you can use
@include to include variables from a distinct
Also note that there’s a difference between “Sass” and “SCSS”. “Sass” doesn’t include any brackets or semicolons, it looks like this:
Personally, I prefer SCSS because it’s closer to vanilla CSS, so you’ll be able to more easily follow CSS tutorials, better understand open source examples, and be able to write vanilla CSS or use other pre-processors should you ever need to. I also personally find SCSS easier to read, with an easily understood, well-defined visual hierarchy.
More information about using SCSS and its features is available in the SCSS documentation.
Avoid using float
I’m sure others will disagree with me on this, but I have tried to avoid using
float in almost all my projects. Those that I have used
float in have had their fair share of problems because of it. Perhaps my problems stem from ignorance, in which case I’d love to be told how to correctly use floats.
When writing stylesheets I’d prefer to write once and have it work everywhere. Of course, that isn’t usually a reasonable expectation. When using flexbox for layout, it’s at least made relatively simple, with only a handful of properties to modify if you’ve set things up correctly. When using
display: flex, the
float property will no longer work for elements within a flexbox container.
With flexbox, modifying a list of “cards” that fill the full width of the page on mobile to become listed horizontally and overflow into more rows as screen size increases is as easy as:
No need to change anything between platforms for this to work, it just does. If your layout requires using a lot of
float, using flexbox becomes significantly more difficult.
A common reason to use
float is to align content to the right side of the page. However, this brings its own complications.
Let’s say you have a list of navigation elements:
If you apply the following CSS, the expectation would be that Profile is the right-most element, because it’s listed last in the HTML, correct?
The problem is that
float actually places “Messages” as the right-most element, then “Notifications” and “Profile” are placed to the left of “Messages”. You could fix this by applying
float: right to the
header-right class instead of the list items themselves, but what if you wanted to add a search box to the inside of the right side, certainly it wouldn’t go inside the
header-right element? It isn’t a list item like the other navigational elements. So you’d need to place it outside of the unordered list, and apply
float: right to it as well. However, it would have to go after the
header-right element if you wanted to place it on the inner side of the right-aligned navigation elements.
The point I’m trying to make is that the
float property tends to cause unnecessary complexity and unexpected results. As with all things, there are exceptions to these rules. Float can be very useful in articles if you’re trying to get text to flow around a picture, for example. That said, I believe that – as a means of aligning items in a layout (i.e. a navigation bar, header, etc.) – there are many means of achieving this which simply work better.
Understand selector specificity
I won’t cover this myself, as others have covered it better than I can, but Shay Howe’s getting to know CSS guide is great for this. This is an incredibly important concept to understand.
Always avoid using
On the topic of selector specificity,
!important is a common way of hacking around the specificity hierarchy for newer web designers and developers. I would advise strongly against this practice, as it can become a nightmare when misused.
The key thing to understand with regards to
!important is that it breaks the delicate specificity system. It overrides all style rules regardless of their specificity. The only rules capable of overriding an
!important declaration are in-line styles with
!important declarations themselves.
Except in the cases of
!important and in-line styles, there will always be a way to override another selector’s properties.
!important, especially when a site becomes larger, with hundreds or thousands of different CSS classes and IDs, using
!important will only cause headaches down the road.
I want to note that I’m not saying CSS is infallible and some great style language. It should have sensible defaults, but sometimes it doesn’t – usually for backwards compatibility reasons. Ideally it wouldn’t require experience with every CSS property to throw together a relatively simple website, but I’d challenge you to develop a stylesheet language that works in as many use-cases as CSS does, as well as it does.
If you want to learn more about web development, I’d definitely recommend checking out these links:
- The Codrops CSS Reference - Easily the most useful CSS reference I’ve found. Goes in-depth on every CSS property I know of.
- Learn to Code HTML & CSS - A great introduction to web development, especially HTML and CSS.