Heeding to the Structure of your House — The Paint & The Decor

Harshdeep Bilaiya
Globant
Published in
9 min readJan 5, 2021

Continuing from where we left, you have now built yourself a house with strong structural integrity, simplicity & maintainability. It doesn’t look very appealing right now, though. Now, you want to cover the brick & mortar walls with some plaster, apply those wallpapers, add that wooden flooring, decorate the interiors, exteriors, and so on.

The task might look daunting at the beginning. But you will be surprised to see how easy it could actually be, once you follow the protocol.

What’s inside your house?

Let’s add some styling to make the page in previous example CodePen, a bit easy on the eye. Effectively use CSS (with BEM methodology, preprocessor like SCSS…), in order to have well structured, readable & maintainable style documents. Have a brief look into Mobile First approach for Responsive Web Design (RWD).

JS is not the only hero. (Background vector created by photoroyalty — Freepik)

Organise your CSS — Use the tools Effectively

Begin by checking off these items…

1. Ways to implement CSS

You can declare styles in 3 ways. Let’s check them out in descending order of precedence:

  • Inline styles
    If you use style attribute in HTML to declare styling rules, that’s an inline style.
<h1 style="color: red">Heading</h1>
  • Internal styles
    If you declare styling rules inside <style> tag in HTML head , that’s internal style.
<style type="text/css">
.heading { color: red }
</style>
  • External styles
    If you use the most common styling approach and have separate files to write your styling rules, that’s external style. External CSS files are declared using link tags inside head .
<link rel="stylesheet" type="text/css" href="style.css" />

All three of these ways have their pros & cons. External styles are preferred for separation of concerns. Although inline styles are used quite frequently in modern JS frameworks & libraries.

2. Know the specificity rules

CSS — Cascading Style Sheets works from top to bottom, i.e., if two or more styling declarations point to the same element, the last declaration is applied to the element.
This is not all though. You could easily bypass this rule by using various selectors or a combination of selectors.

<!-- HTML -->
<span class="item">item 1</span>
<span class="item">item 2</span>
// CSS
.item { color: red; }
span { color: blue; }

The above example will have both “item 1” & “item 2” in red color. This is because class selectors have higher specificity as compared to element selectors. Thus, even if style declaration using element selector follows the class selector based declaration, color is still red.

In general, the universal selector (*) has low specificity, while ID selectors are highly specific!

Following 4 categories define the specificity level of a selector:

  • Inline styles are attached directly to the element. Eg: <h2 style="color: red">Section Heading</h2>.
  • IDs are unique identifiers for the page elements. A good practice is to avoid ID selectors in CSS. They are mostly used to reference a specific element in JS. IDs could also be used to bookmark or go to a specific section of the page. You could link href of an <a> to the ID by prepending # .
<h2 id="credits">Credits</h2><a href="#credits">See Credits</a>
  • Classes (.color-red), attributes ([disabled], input[type="text"], etc.) and pseudo-classes (:hover, :focus, etc.) all fall under the 3rd category of selectors.
  • Elements (h1, section, etc.) and pseudo-elements (::before , ::after ,::selection, etc.) falls under the last category. Note that in CSS3, the single-colon notation was replaced by the double colon for pseudo-elements. This was a W3C attempt to distinguish between pseudo-classes and pseudo-elements.

While writing style declarations, you can calculate the specificity score by following these rules:

  • Inline style — 1000
  • ID selectors — 100
  • Class selectors — 10
  • Element selectors — 1
  • Universal selectors, inherited values — 0
<!-- HTML -->
<h1 class="heading" id="main" style="color: red">Heading</h1>
// CSS
#main { color: blue}
.heading { color: yellow }h1 { color: orange }* { color: green }

In the above example, inline style (color: red) with be applied to h1 because of highest specificity. Selectors are often combined, scoring which is a matter of simple addition.

.heading#main { color: red }
#main { color: blue }

h1 will be red in color, as 1st declaration has a specificity = 10+100 = 110, which the 2nd is 100.

Note that any CSS property followed by !important overrides any other declarations. Although technically !important has nothing to do with specificity, it interacts directly with it. Using it, however, is bad practice and should be avoided because it makes debugging more difficult by breaking the natural cascading in your stylesheets. When two conflicting declarations with the !important rule are applied to the same element, the declaration with a greater specificity will be applied.

3. “Select”ing Appropriately

There are a bunch of selectors in CSS. Some of those are commonly used (like classes, ids, elements, etc). But there are some which could be very powerful, if used appropriately. Let’s discuss some of them:

Descendant & Sibling selectors

<!-- HTML -->
<section>
<p>some text</p>
<div>
<p>more text</p>
<p>even more text</p>
</div>
</section>
// CSS
section p { color: red } // all descendants
section > p { color: blue } // direct descendant

If you want to target only a direct descendant of some element, rather than all the descendants, > comes handy. Rule 1 applies red color to all the descendants of section , while rule 2 overwrites rule 1 only for “some text”, which is a direct descendant of section .

If you want to target only p which is followed by another p in above example, you could use + like this:

p + p { color: red }

This would apply color red to a p which is sibling of another p , i.e., “even more text”

If you have a list of elements, and you want to target some elements after a specific element, you could use ~ like this:

<!-- HTML -->
<ul>
<li>item 1</li>
<li>item 2</li>
<li class="break">item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
// CSS
.break ~ li { color: red }

This would apply red color only to the li elements following the one with .break class (“item 4”, “item 5”).

Now, as we touched upon some basics of styling, let’s move on to cooler stuff…

Adding Responsive Styles by Combining CSS preprocessors with BEM

A CSS preprocessor is a program that lets you generate CSS from the preprocessor’s own unique syntax. There are many CSS preprocessors to choose from, however most CSS preprocessors will add some features that don’t exist in pure CSS, such as mixin, nesting selector, inheritance selector, and so on. These features make the CSS structure more readable and easier to maintain.
To use a CSS preprocessor, you must install a CSS compiler on your web server; or use the CSS preprocessor to compile on the development environment, and then upload compiled CSS file to the web server.

SCSS, LESS, Stylus are some of the popular preprocessors. Let’s see by example how SCSS makes your life easier. BEM (Block Element Modifier) class naming convention goes very well with SCSS.

There are a few points to take from above snippets:

1. BEM class naming conventions makes naming classes easier for us developers. It provides a categorisation for class names, based upon the nature and purpose of class being applied to the element.

  • Block encapsulates a standalone entity that is meaningful on its own. While blocks can be nested and interact with each other, semantically they remain equal; there is no precedence or hierarchy. Holistic entities without DOM representation (such as controllers or models) can be blocks as well. In the example I used, the section wrapping the entire application has class app . Header, main content, footer are also blocks of their own.
  • Elements are parts of a block and have no standalone meaning. Any element is semantically tied to its block. For example, header element has the class app__header , which denotes that header is a part of app.
  • Modifiers acts as flags on blocks or elements. You can use them to change appearance, behavior or state. For example, app__navigation-list-item has another class item--active , which adds some style on active nav item.

2. Special SCSS features (other preprocessors also support similar features, more or less) provides an efficient way to write styles, reuse code and have a better style structure overall.

  • Nesting works well with BEM conventions. If you observe the SCSS file, blocks are at highest level. Under which, I’ve nested the elements. Modifiers could be nested further within an element or block, as required. You must practice restraint while nesting classes. Keeping a nesting level ≤4 is a good practice. Higher nesting levels present problems while overwriting styles. Nesting also helps avoiding leaking styles.
  • Variables in programming are always handy. Although CSS supports custom variables (using var()), SCSS variables fit right in with all the other syntactic sugar. You can define a variable with $ sign. Having separate SCSS partials with separation of concern is also a good idea. For example, you can have _colors.scss for all your colors.
  • Mixins are useful, if you want to reuse code blocks. You can define a mixin for properties which require different browser prefixes. Media query mixin is another useful example, which I’ve demonstrated in the example application.

That’s not it. SCSS has much more to offer, like placeholders, functions, etc. You should explore all these features because when used properly, they give you immense power & you’ll soon notice the cleanliness and structure in your style documents. Preprocessors make styles highly maintainable.

3. Most modern web applications are responsive. As a developer, you must ensure your application supports various screen sizes. Be it mobile, tablet or desktops with largest of screens. RWD is implemented using media queries. And the standard approach for it is Mobile First. As the name suggests, you style your webpage for mobile screens first. Afterwards, just overwrite whatever properties you need (like font-sizes, spacing, etc) for each supported breakpoint.

This makes the development very smooth & efficient. Mobile first approach uses min-width media queries, as we move from smaller screen sizes to larger ones.

Remember to always overwrite only those properties which need overwrites. As developers, we have a tendency to copy code we are testing on devtools, and we copy the entire block.

Bonus
If you are reading this article on a laptop/ desktop (bigger screen), try to resize the window to a smaller viewport width. You’ll notice that on smaller viewports, the text content of the article expands to cover full width. But as you resize the viewport to larger widths, the content expands only to a certain width and then it sits centred for all sizes beyond. The header & footer, on the other hand takes the entire screen width at all viewports (and their content again, sits centred). This is a standard UI layout for many modern web applications.

In the example, I’ve used a modifier class content--centered to provide header, main & footer content some max-width at each breakpoint. margin: 0 auto keeps the content centred, once viewport has more than enough real estate.

You can see a working demo in the following CodePen.

Carefully structured HTML & CSS documents go a long, long way in increasing a developer’s efficiency & productivity. And keeps the code clean, understandable, readable, maintainable & scalable.

Ready to Move-in?

You have been really mindful in planning & building this house of yours. You heeded to the finer details of execution, which made the process fun for you (hopefully). From laying the foundation, to using the tools effectively, to decor, to painting - you finished it all. Your house is beautiful, maintainable, scalable & all your friends are impressed when they visit these delightful corners of your grand, luxurious house.

Photo by Ralph (Ravi) Kayden on Unsplash

If you haven’t already, you could check out Part 1 of this article — Heeding to the Structure of your House — The Tools & The Foundation.

--

--

Harshdeep Bilaiya
Globant
Writer for

Professional Web UI Developer and technology enthusiast. Thank heavens for JavaScript!