Skip to main content

Command Palette

Search for a command to run...

CSS : Evolution and Usage

Published
10 min read

When HTML was first developed - sure it was revolutionary but something was missing. We humans are always hungry for better - and this time we were bored of those heading para - heading para - heading para - and occasionally some links. We wanted aesthetic. We wanted beauty. We wanted design. And that is why CSS came to be.

CSS stands for Cascading Style Sheets. Now we know its called a style sheet because its - well - styling the webpage but what’s this cascading you must wonder- and you must - because its important. And we will soon be learning - Why.

Now when html was first present - people wanted to style the text - so they created new tags for that purpose. <font></font> <center></center> and so on. But html is already so specific about what it needs to be. Adding in tags for designing is - logically speaking very congested and dirty. It also makes the html code unreadable and difficult to maintain. Hence we needed a different way to represent designs.

Then came in - the inline style attribute. For every element you could define a style attribute like:

<p style="color:red">
Hello
</p>

Now it seems nice. We can work nicely now …Or can we?
Imagine this

<p style="color:red">
Hello
</p>
<p style="color:red">
My name is Parikar
</p>

Now you have to define the same style again and again. And if you need to change the color to pink - imagine you will need to work out through all the tags. Just imagine how difficult that would be.

And hence came the concept of the <style> tag. Separating the CSS section form the HTML section. So in documents you could write -

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Page</title>
<style>
    div{
        color:red
    }
</style>
</head>
<body>
    <div>This is your product</div>
</body>
</html>

Separating the style into the head and keeping HTML clean. But can we do better?
I mean we are just writing down another type of file in HTML for no reason. In fact if we want to have another file with the same design taste - we will again have to copy paste the whole file - and again - change everywhere if there is a change in one place.

Now we need to solve this problem. How do we? Well - we can have a separate file for css and link it to our document. That way we can have truly modular code and separation of concerns.

Now when we will be writing this code then maybe we want to group some elements without a common pattern to have same properties ,or style a specific element - but for that we will have to specify that element. I mean how can we use different ways of telling our computer which styles to apply to which elements.

And this is the question that births the concept of selectors.

CSS Selectors

CSS Selectors are used to point out the elements in the HTML - in the DOM whose design we want to specify. They come in many forms - evolved to solve different types of problems. Let’s explore some of the most popular ones and try to understand their intention, design, usage and most importantly the problem they solve.

The format of writing CSS with selectors is simple:

selector_name{ //curly braces open
key:value;
//key - to specify what aspect of the style to change
//value specifying what to change it to
//semi -colon to separate multiple pairs
} //closing braces

Element Selector

The element selector is used to target a particular tag. For example if we do:

div{
color:red;
}

All the div in the document will be shown with a red color. It helps us target and generalize designs for a particular type of content in the document and is very useful in trying to maintain consistency in the design as there won’t be 2 div with different color (even tho we can intentionally later.

Here the selector is simply the contents of the tag.

Group Selectors

The group selectors are used to have multiple types of selectors in a single line as a selector and all of them will share the same style. The selectors here are separated by a comma.

div,h1,.class_name{
color:red;
}

All the three selectors will now have their content colored in red. Notice we have not only tags but some other type of selector. We will learn more about it - but for now - we can understand that the group selectors allow us to fuse together any number of selectors and apply a common style to them.

Descendant Selectors

Descendant Selectors feel complex to understand but they are fairly simple. A descendant selector indicated a path to reach the final node in the DOM to specify what element is meant to be targeted.

Its like saying - call John whose dad is Mark whose dad is Jonathan whole dad is Joseph… and so on. This is because there can be many named John but there is a small chance of finding one with this heritage.

Similarly when we write a selector in this format we specify it by separating it with a white space.

body div ul li a{
color:black;
text-decoration:node;
}

Here the computer will ask - a , his parent li - ok - his parent - ul okay - his parent - div and his parent body. If at any point the parent is not present that element is disqualified from being checked further.

Like if you find 400 Johns and find 100 of them has their father who has a name - Mark then you will not even consider talking to the rest 300 Johns. Its the same thing.

Also the general format uses any selector and not just the element tag.
We can do :

.hero_header .hero_title{
color:pink;
}

Class Selector

Class selector is one of the most abundantly used form of selector and it is almost a solution to most of the problems of CSS specification.

A class selector relies on the elements in html being placed under some class explicitly which can be utilized later on. This is done using the class attribute in HTML tags.

<div class="user">
Hello
</div>

Now we have a class named user. To target this element using the class user we do:

.user{
key:value;
}

So the syntax is a period (.) followed by the class name.

.class_name.

The best thing about class is that any two elements can share the same class as long as they are a valid element in the html file. This allows us for custom groupings and be very specific. Class is objectively the most flexible selector. Now only any two elements can have same class - an element can have multiple classes as well. This allows us to specify an a design for one element separate to another one even if it shares a class with it.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Page</title>
<style>
    body{
        background-color: brown;
    }
    .class1{
        background-color: azure;
        color:purple
    }
    .class2{
        color:green;
    }
</style>
</head>
<body>
    <div class="class1">
        Hello I am Parikar
    </div>
    <div class="class1 class2">
        I love researching things in depth
    </div>
    <div class="class1">
        Join me in my resolve to understand things
    </div>
</body>
</html>

Consider the above code and output. Here I wanted all 3 div to have the same background color - so I gave them the class class1. But for the second div I wanted text green while for others I wanted purple. So instead of rewriting it again I added another class and gave it another design.

But How does the system decide which design to listen to? And here comes the concept of Cascading.

The Genius of Cascading

The word cascading is used by CSS because of its nature of over-riding its past code. In fact even if we don’t style code - the browser has a default stylesheet. This is called as - user agent style sheet. And this is why we see a heading tag big and a link - underlined and blue.

Now when we specify our own design as an Author - the previous design is over-written and we get a new style. However this fact still continues on as we write css. If ever we write two conflicting styles for the same element - than the one which is specified later is used. Because the one specified later is processed later and it cascaded the previous definition. Also it is important to note that when we cascade than we don’t invalidate all previous definitions of an element. We just over-ride the specific ones we defined and the rest are kept as it is. This also allows in the wonderful control that classes provide us for styling.

However this cascading effect is not permanent and is over-ridden in a specific circumstance - and no I am not talking about !important - because that is not a general circumstance but an artificially created exception.

The ID selector

Just like a class - we can add an ID to an element via its attributes. An id is unique to an element and cannot be reused. This allows us to specifically target one element. And when we do that it could become easy to extract an element specifically when we are drowned in too many classes even tho that generally won’t happen.

The specifier goes like this.

#id_name

For example in this code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Page</title>
<style>
    body{
        margin:0px;
        background-color: brown;
    }
    #name{
        background-color: aquamarine;
        color:purple;
        padding:4px;
    }
</style>
</head>
<body>
    <div id="name">
        Hello I am Parikar
    </div>
</body>
</html>

Here we can see - that we added an Id to an element via the id attribute and styled it using the #id_name selector.

Now even tho ids seem very convenient to find the element and design them - it is generally best practice to avoid them because of a nature of css rule application - called :

The Specificity Algorithm

The Specificity algorithm performs a simple and logical execution. No matter when and where the style is paced for an element in the css file - assuming !important is not used - a specifier that targets the element more specifically will always take priority in showing the final design for an element.

For example if we have a class for an element and an id for it. There are multiple elements that can share the same class. But there can be only one element that can have a particular id. Meaning if both class design and id design is specified - the element will take on the id design. This is because it more specifically targets that element. Think of it like this.

If we say that John will get gold medal or roll number BT23CSE133 will get the gold medal. Now many people can be John but we know that there can be only one person with that ID. And so since the machine will know for sure which node to target it will ensure its css stays preserved.

Even cascading cannot over-ride it.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product Page</title>
<style>
    body{
        margin:0px;
        background-color: brown;
    }
    #name{
        background-color: aquamarine;
        color:purple;
        padding:4px;
    }
    .class1{
        background-color:pink;
    }
</style>
</head>
<body>
    <div id="name" class="class1">
        Hello I am Parikar
    </div>
</body>
</html>

As we can see - even when the class was specified later It preferred to give priority to id’s css.

As such if we target elements by ID we will face difficulty in managing the stylesheets. Because a class design we are applying could be over-ridden by some id. Hence it would be better to just add a class at the end and design it.

Another popular term is !important over-ride . If one has to use this it means that the code is severely compromised and is so unmanageable that you cannot alter the CSS to match up so you need to specify !important to over-ride the design. It is usually used by the end user to inject their own design to increase accessibility. This also could prevent that - and hence should be used as the absolute final last resort.

This was all about CSS selectors and how it works . The working of CSS is not very difficult to understand but once you do - you will never fear about CSS breaking ever again.