CSS Best Practices – Find Yours

I have been on a best-practice research rampage lately and wanted to take a few minutes to share some of the things that I have found in regards to CSS best practices. I will show some of the research I found and some of the common themes.

CSS Best practices

In my search for making good decisions, I thought it was important to try and find what other people are doing. I have talked about ‘being part of the conversation’ before and a good start to finding what I think is right is to look at what other people feel is right. That does NOT mean I need to follow what other people do, but it can give me the basis making my own informed decisions.

What are other organizations doing in terms of CSS Best Practices?

I found four online CSS style guides and CSS best practices that seemed like really good sources to begin forming my own thoughts.

Google’s Style Guide – – Because Google.

Code Guide by @mdo This person is one of the creators of Twitter Bootstrap and current Director of Design at GitHub.

Code Guide by Harry Roberts – the guy behind @csswizardry.

Air BnB

I am sure there are others out there, but these are all legit CSS style guides from prominent entities in the tech industry.

What do these example CSS best practices teach us?

One thing I was interested in was finding what is common among all of these style guides? If these widely regarded entities generally agree on something, it would seem appropriate to at least look at the similarities.

Here is a list of items that seem to be agreed on in at least ¾ of the style guides

  • Soft Tabs. They’re the only way to guarantee code renders the same in any environment. 3 of the 4 recommended 2 spaces. One recommended four.
  • When grouping selectors, keep individual selectors to a single line. 2/4 indicated that in some cases (only one selector and attribute), single line css could be used.
  •  
    
    /* Bad CSS */
    .selector, .selector-secondary, .selector[type=text] {
      padding:15px;
      margin:0px 0px 15px;
      background-color:rgba(0, 0, 0, 0.5);
      box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
    }
    
    /* Good CSS */
    .selector,
    .selector-secondary,
    .selector[type="text"] {
      padding: 15px;
      margin-bottom: 15px;
      background-color: rgba(0,0,0,.5);
      box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
    }
    

    .selector {padding: 15px;}

  • Include one space before the opening brace of declaration blocks for legibility.
  • /* Bad CSS */
    .selector{
      padding:15px;
    }
    
    /* Good CSS */
    .selector {
      padding:15px;
    }
    
  • Place closing braces of declaration blocks on a new line
  • Include one space after : for each declaration, but none before.
  • End all declarations with a semi-colon. The last declaration’s is optional, but your code is more error prone without it.
  • All class names should be lowercase-hyphen (although 2/4 recognizes/encourages BEM and OOCSS naming conventions. The other two do not mention them.) Google does not explicitly call this out for classes, but “All code has to be lowercase: This applies to HTML element names, attributes, attribute values (unless text/CDATA), CSS selectors, properties, and property values (with the exception of strings).”
  • Comments – use them. Everyone includes that comments are needed and that it should be done in a consistent manner, but they each have slightly different comment styles.
  • Javascript hooks. 3/4 Javascript hooks in selectors to separate presentation from functionality from document “.js-“. Google does not call out specific js-hooks, but does talk about “Separating structure from presentation from behavior is important for maintenance reasons.”
  • IDs. 2/4 say never use IDs in css. 1/4 say to avoid using them. 1/4 (Google)makes no comment.
  • 4/4 have some verbiage about avoiding qualifying selectors and avoiding specificity (als0 related to ID item) . The more specific a rule is, the more fragile it tends to be and more labor intensive for the browser. 3/4 seem to have a preference to classes in lieu of any dom elements and Google doesn’t really mention much about it.
  • They all talk about appropriate class naming. Trying to avoid presentational naming and more reflects the purpose of the element. Brief as possible, but long as necessary.

What am I supposed to do with these CSS best practices?

Well, use them. They don’t NEED to be a part of your CSS best practices, but use them to understand what other people are doing and to be intentional about how you and your organization writes CSS. Even among the linked style guides, they each have some sort of discussion about consistency and working together to make a choice or respecting the formatting of the environment you are working in.

JavaScript closures explained

During my online learning endeavors, I have continually come across the word “closure”. I didn’t really know what it was, but like any inquisitive mind that loves to learn, there is never a time like the present to figure out what JavaScript Closures are.

MDN documentation on JavaScript Closures:

First thing to do is to check out the MDN documentation and they have a good description:

Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.

Check out these JavaScript closures examples

Consider the following HTML and JavaScript:

<!DOCTYPE html>
<html>
<head>
  <title>THIS IS A PAGE</title>
</head>
<body>
  <h1>BEHOOOOOOOLD!!!!</h1>
  <p>an html page</p>
  <script>
    function makeColor(theColor) {
      var toChangeTo = theColor;
      return function() {
        document.body.style.background = toChangeTo;
      };
    };
  </script>
</body>
</html>

If I open this page, it is blank and looks as follows:

original page without execution of javascript closures

Now, if in the console, I create a variable:

var theThings = makeColor("red");

Notice the actual function is returned. Since functions in JavaScript are first class citizens, they can be passed around similar to variables. This really is one of the beautiful and dangerous things about JavaScript.

So the variable is a function that was returned from makeColor, but when I do the following:

final - after execution of javascript closures

I call “theThings()”, and not only does it execute the returned function, but it remembers and is aware of the variable toChangeTo. That is what makes this a closure. theThings remembers the environment in which it was created and that toChangeTo was “red”, so it was able to change colors when executed.

Closures are not just a JavaScript tool and are available in some other languages, but JavaScript it is where I am exposed to them most often. JavaScript’s treatment of functions as first class citizens is one of the great things about the language and also creates opportunities to utilize closures. If you had confusion about what a closure is, I hope this helps get you closer and you may begin to notice just how often it is used.

jQuery Ready and Load Event Differences

The jQuery documentation clearly explains jQuery ready and load event differences, but I encountered an issue recently that I thought would make it worthwhile to cover. And even if you are placing your JavaScript code at the bottom of your page, without the almighty “$(document).ready()”, it is important to understand jQuery ready and load event differences.

jQuery ready and load differences blog title

What is $(document).ready()?

Most people have encountered the ready function at some point or another, even if it is just to be able to place your JavaScript at the top of your HTML Specifically, code placed within an anonymous function will execute after the Document Object Model(DOM) is loaded.

Consider the following ready call:

$(document).ready(function(){

console.log(“foo”);

});

If this is appropriately placed in an HTML document, it will execute after the DOM is loaded. What it doesn’t do, however, is wait for content to load and that is one of the key jQuery ready and load event differences.

What is $(window).on(“load”,function(){})

The jQuery load event does not seem to be used quite as often as the ready function and there is a reason.

If the same code shown above were slightly altered as follows:

$(window).on(“load”,function(){

console.log(“bar”);

});

You could have a different output than you might expect and that is why it is essential to understanding jQuery ready and load differences. In this instance, “bar” will only print out after the DOM is loaded, like ready, but also wait for the assets.

So how might jQuery ready and load event differences impact you?

I will share how this difference impacted me. I have a page with several divs that need to be of equal height on mobile views.  The content in the divs are dynamic, which could change the size of any individual div, and also container that need to be of equal heights.

To accommodate the changing heights, a bit of JavaScript was added to find the tallest div and set all the other divs to be that height.  Perhaps, if I were to write this again from scratch, I would have gone down other paths, but I am now invested in this solution. At this point, I did not wrap the code in either the “load event” or “document ready” solution.

The problem I found was that, even though the JavaScript is located at the bottom of the code, the heights were sporadically changing when the page was rendering on mobile. Furthermore, the problem didn’t really show itself until it lived in a non-local environment, so for some of us who have already been testing, it seemed to be fine.

I found that I was getting sporadic problems because the images within the divs were in different states of rendering while the snippet of JavaScript and jQuery was running to set the height.

It seemed sort of logical to me at the time to wrap my code in $(document).ready(), as I just had never encountered this problem before and have been exposed to the ready function, arguably, far too much. My bad. But since $(document).ready() only worries about the DOM and NOT the assets, it did not solve my problem. This was a bit of an unfortunate time suck for me.

That is when I opened up the jQuery documentation and found .load()… not to be confused with an AJAX method of the same name. Unfortunately, it had been deprecated, but that documentation sent my in the correct direction by suggesting to use the .on() function along with the “load” event.

This solution would wait until the DOM and the images have loaded before executing, which is great. It works wonderfully.

Are there trade offs?

Sure. All assets must load. So, what are the results if an image takes a really long time to load or a cdn is not loading? Well, your user is just going to have to wait to get the expected outcome. Often times, this will not be an issue, but it can impact usability and functionality of the page. Knowing the ready and load event differences can help you make informed decisions about your code.

In summary, I went down a bit of a rabbit hole with this problem and came out the other side with some good experience and additions to my growing knowledge base. It is important to work to understand the loading order of the window object and even more important to understand the actual functionality of the jQuery and JavaScript functions that are used. Understanding  the jQuery ready and load differences before hand would have saved me time and frustration.