Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy to maintain CSS or lightweight HTML?

I'm in charge of supervising the whole IT side of a website (both infrastructure and development) and I'm having a difference of opinion with the lead frontend developer. His approach is to create individual classes that each bring one functionality, and combine as many classes as needed to style an element:

HTML
<div class="float_left padding_10 width_60_percent"></div>
<div class="float_left width_30_percent"></div>
<div class="float_left padding_10 width_10_percent"></div>
CSS
.float_left { float: left; }
.padding_10 { padding: 10px; }
.width_60_percent { width: 60%; }
.width_30_percent { width: 30%; }
.width_30_percent { width: 10%; }

Pros:

-understanding of CSS via the HTML: you can understand what the CSS is doing by just looking at the class names in the HTML.
-ease of creation: once you have your set of classes defined, it's just a matter of combining them in the HTML, you don't have to constantly write new CSS.
-ease of maintenance: same reason as above.
-portability: you can use the same approach for any website you work on (which makes sense for him as he is a contractor working on different projects).
-smaller CSS: as long as your layout reaches a certain critical size whereby the same classes are being re-used again and again (which would be the case with a proper layout, but obviously isn't reflected above due to the conciseness of the example).

Cons:

-bigger HTML.
-HTML harder to read if you're not interested in the CSS part (which my backend developers creating the views aren't).
-harder to integrate Javascript based on class selectors (we're using jQuery).

My approach isn't dictated by the ease of writing/maintaining CSS itself, but rather by concerns that a substantial part of our HTML code is going to be used solely for the purpose of integrating our CSS, which will impact performance: I believe it's better to have a bigger CSS which gets served and cached once, and a smaller HTML which saves you bandwidth on every page view, rather than the opposite. Accordingly, I would opt for the following approach:

HTML
<div id="column_left"></div>
<div id="column_middle"></div>
<div id="column_right"></div>
CSS
#column_left { float: left; padding: 10px; width: 60%; }
#column_middle { float: left; width: 30%; }
#column_right { float: left; padding: 10px; width: 10%; }

Pros/Cons
Opposite as above.

I have the feeling that having a lightweight HTML code is critical to achieving growth of your website:
-page load will be faster which will help with SEO and user experience.
-more pages can be served with the same bandwidth will which save you infrastructure cost.

In an attempt to get a de-facto answer, we scanned "big" websites to see what part of HTML was allocated to using ids and classes. Here is the code:

<?php
require_once 'simple_html_dom.php';
$pages = array('http://www.amazon.com', 'http://www.ebay.com', 'mywebsite.html', 'http://stackoverflow.com','facebook.html');
foreach ($pages as $page) {
    echo "\n$page\n";
    $html = new simple_html_dom();
    $string = file_get_contents($page);
    $total = mb_strlen($string);
    echo "HTML = " . $total . " characters\n";
    $html->load($string);
    foreach (array('id', 'class') as $attribute) {
        $count = 0;
        $elements = $html->find("*[$attribute]");
        foreach ($elements as $element) {
            // length of id or classes, + id="..." or class="..."
            $count = $count + mb_strlen($element->$attribute) + mb_strlen($attribute) + 3;
            //echo $element->$attribute . "\n";
        }
        echo "  -from $attribute attributes = $count -> " . round($count / $total * 100) . "%\n";
    }
}

and here are the results:

http://www.amazon.com
HTML = 101680 characters
  -from id attributes = 943 -> 1%
  -from class attributes = 6933 -> 7%

http://www.ebay.com
HTML = 71022 characters
  -from id attributes = 1631 -> 2%
  -from class attributes = 4689 -> 7%

ourwebsite.html
HTML = 35929 characters
  -from id attributes = 754 -> 2%
  -from class attributes = 2607 -> 7%

http://www.imdb.com/
HTML = 74178 characters
  -from id attributes = 1078 -> 1%
  -from class attributes = 5653 -> 8%

http://stackoverflow.com
HTML = 204169 characters
  -from id attributes = 3376 -> 2%
  -from class attributes = 39015 -> 19%

facebook.html
HTML = 419001 characters
  -from id attributes = 6871 -> 2%
  -from class attributes = 85016 -> 20%

So far we've been using "my" approach and I'm happy to see we're keeping the percentages of code related to the id andclass` attributes within the same proportions as other big websites (around 2% and 7% respectively). Nonetheless in order to validate that choice, I would like to ask the following questions that I hope experienced developers/webmasters will be able to answer:

Q1: Do you see other pros/cons in favour/against either of the 2 approaches?

Q2: From your experience, is it that critical to worry about having a lightweight HTML code, or does this become neglectable with the use of compression and other criteria (e.g. you will spend more money fighting with your frontend developers)?

By looking at the results, you will see that there seems to be a pattern in the amount of code related to the id and class attributes (although I know scanning more websites would provide a more accurate picture):
-all websites have around 1% to 2% of their HTML code related to id attributes.
-4 of the websites have around 7% of their HTML code related to classes.
-the others have around 20% of their HTML code related to classes.

Q3: Is there a technical explanation (e.g. are Facebook and Stackoverflow using the same frameworks to generate their CSS) for these patterns?

like image 370
Max Avatar asked May 02 '12 10:05

Max


2 Answers

I'm a frontend dev on a corporate web software project, with about 50 people writing code, most of them backend. Initially I agreed with having as few classes as possible to make the code lighter, using lots of inheritance in the css. So we've been using the "as few classes as possible" approach.

A1: With the few classes approach, lots of css definitions will use element names to add style, something like .left-column section li a this makes life easier for devs, but actually makes the css slower, as css is analysed from right to left. In my example, the browser first checks all the links, then all the list elements, and so on. If I just had a.lc-link the css would be faster to use, having fewer elements to look for.

Another problem we run into is the lack of modularity. I can style a nice element, let's call it .flight-dates and it works great. Then a new use-case comes along and someone wants to use in the middle of a form, not a s a primary page-module. But the form was built to use a single class on the form tag and everything else uses inheritance. All the inheritance pollutes .flight-dates so I need to go back and add higher specificity to the css, so all the .flight-dates styles have an extra definition for when they're a child of the form.

That kind of thing happens 3 or 4 times a week. Less classes = less flexibility + ugly stylesheets with very high specificity, is what I've taken away from it.

A2: With the amount of javascript happening on the pages, the amount of classes used is now almost irrelevant. It doesn't make any difference to DOM manipulation speeds that I'm aware of. So we've already lost any advantage we may have gained from the few classes approach.

With reference to your tests, remember, downloading css and parsing css are not the same thing.

Also, the afore-mentioned css amendments have actually made things slower for both backend and frontend devs. Because we tried to use as few classes as possible to make things easier for backend, backend are left with components which cry like a baby if you put them in a new context, and frontend have to change css they wrote 6 months ago. I personally have wasted weeks.

I'd say it's made the work slower, and there's no performance advantage worth talking about.

A3: Things like Sass and Less tend to lead to common patterns in css. Also, a lot of good grids and related css frameworks use common class names. Think jQuery ui or 960 grids.

If you want to learn from our mistake, listen to your frontend guy. Your backend folks will be happier because components will always behave the way they expect them to. Your frontend folks will be happier because they'll be able to write robust, fire-and-forget css, that they won't have to rehash for new use-cases every time they pop up. Your html will be a little bigger, but honestly the difference will be neglible, I don't believe it's going to lead to any significant bottleneck. Your css will run quicker. Work will ultimately take less time to do.

like image 135
daveyfaherty Avatar answered Oct 31 '22 22:10

daveyfaherty


What your frontend dev is doing is called object oriented css (OOCSS), which some believe can be beneficial to the speed of your site.

I don't feel like rehashing the arguments for OOCSS here, so just read this FAQ:

https://github.com/stubbornella/oocss/wiki/faq

Edit: I would rather err on the side of facebook/stack than amazon/ebay when it comes to coding standards. Notice the more progressive sites (fb/stack) seem to have higher class percentages?

like image 39
izolate Avatar answered Nov 01 '22 00:11

izolate