CSS looks simple at first, but understanding how the browser calculates sizes and decides which style to apply is extremely important for building predictable and maintainable web pages.
Three important concepts are the CSS Box Model, Cascade, and Specificity. This blog explains these concepts in simple terms with practical examples.
- What is the CSS Box Model?
In CSS, every HTML element can be thought of as a rectangular box.
Whether it is a heading, paragraph, button, image, card, header, or footer, the browser treats the element as a box for layout purposes.
The CSS Box Model has four parts:
Content → Padding → Border → Margin
From the inside to the outside:
Content – The actual text, image, button, or other content inside the element.
Padding – The space between the content and the border.
Border – The visible boundary around the element.
Margin – The space outside the border that separates one element from other elements.
Example
Suppose we have a card containing the text:
"Welcome to my blog"
The text is the content.
If there is some empty space around the text before the visible border starts, that is padding.
The visible line surrounding the card is the border.
The space between this card and another card is the margin.
A simple way to remember the structure is:
Margin → Border → Padding → Content
- Padding vs Border vs Margin
These three are often confusing at first, so it is important to understand their exact purpose.
Padding
Padding creates space inside the element, between the content and the border.
For example:
padding: 20px;
means the element gets 20px of padding on all four sides.
So it is equivalent to:
padding-top: 20px
padding-right: 20px
padding-bottom: 20px
padding-left: 20px
Border
A border creates a visible boundary around the element.
For example:
border: 2px solid black;
means:
2px → border thickness
solid → border style
black → border color
Margin
Margin creates space outside the border.
For example:
margin-bottom: 40px;
creates 40px of space below the element.
Unlike padding, margin is outside the element's border.
- What is box-sizing?
The box-sizing property controls how CSS calculates the width and height of an element.
The two important values are:
content-box
border-box
Understanding these two values is extremely important when working with layouts.
- content-box
content-box is the default value of box-sizing.
With content-box, the declared width applies only to the content area.
For example:
.card {
width: 300px;
padding: 20px;
border: 2px solid black;
}
Here:
Content width = 300px
Left padding = 20px
Right padding = 20px
Left border = 2px
Right border = 2px
Therefore:
Total width = 300 + 20 + 20 + 2 + 2 = 344px
So even though we wrote:
width: 300px
the complete element becomes 344px wide.
This can sometimes cause unexpected overflow.
- border-box
With border-box, the declared width includes:
Content + Padding + Border
For example:
.card {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 2px solid black;
}
Now the entire box is 300px wide.
The padding and border are included inside those 300px.
Therefore, the content area becomes smaller to make room for the padding and border.
Conceptually:
300px total width
minus:
40px padding
minus:
4px border
equals:
256px content width
The important point is:
With border-box, the element stays 300px wide. The content area adjusts to fit the padding and border inside that width.
- Why is border-box commonly used?
A common practice is:
- { box-sizing: border-box; }
The * is the universal selector, so this applies border-box to all elements.
It makes layouts easier to predict because when we say:
width: 300px
we can think:
"The entire element will be 300px wide."
This is especially useful when creating cards, forms, columns, navigation bars, and responsive layouts.
- Understanding the Box Model in Chrome DevTools
Chrome DevTools provides a visual representation of the Box Model.
When inspecting an element, we can see:
Margin → Border → Padding → Content
The innermost area represents the content box.
This is important because the number shown in the center of the DevTools Box Model represents the content area's dimensions, not necessarily the entire element's width.
For example, suppose the viewport is approximately 603px wide.
With:
width: 100%
and content-box:
Content = approximately 603px
Padding = 40px on each side
Border = 5px on each side
So the total width becomes approximately:
603 + 40 + 40 + 5 + 5 = 693px
Since 693px is greater than the 603px viewport, horizontal overflow can occur.
With border-box:
Entire element = approximately 603px
Padding and border are included within those 603px
The remaining space becomes the content area
So the content may be approximately 514px wide.
The important distinction is:
603px is the total border-box width, while approximately 514px is the content width.
- Margin Collapsing
Margin collapsing is a behavior that can happen with vertical margins of block-level elements.
For example:
.box1 {
margin-bottom: 30px;
}
.box2 {
margin-top: 20px;
}
It might seem that the gap should be:
30 + 20 = 50px
But in a normal block layout, these vertical margins can collapse into one margin.
The larger margin generally wins.
So the resulting gap can be:
30px
rather than 50px.
Margin collapsing mainly occurs with vertical margins in normal block layouts.
It does not work the same way for items inside Flexbox or Grid layouts.
- What is the CSS Cascade?
The word cascade refers to the process the browser uses to decide which CSS declaration should be applied when multiple CSS rules target the same element.
For example:
p {
color: blue;
}
p {
color: green;
}
Both rules target the same paragraph.
Both have the same specificity.
Therefore, the later rule wins.
The paragraph becomes:
green
This is called the source order part of the cascade.
The cascade considers several factors, including:
Origin and importance
Specificity
Source order
Understanding the cascade is much better than trying to fight CSS using !important everywhere.
- What is CSS Specificity?
Specificity is the system browsers use to determine which selector is more specific when multiple selectors target the same element.
You can think of specificity as a priority score for selectors.
The main selector categories are:
ID selector
Example:
contact
An ID has high specificity.
Class selector
Example:
.send-btn
Classes have lower specificity than IDs.
Attribute selector
Example:
button[type="submit"]
Attribute selectors have the same specificity level as classes.
Type selector
Example:
button
Element/type selectors have lower specificity than classes and IDs.
- Specificity Example
Suppose we have:
button {
background-color: gray;
}
.send-btn {
background-color: yellow;
}
contact button {
background-color: green;
}
And our HTML contains:
Send MessageThe button matches all three rules.
Now compare their specificity:
button
→ Type selector
.send-btn
→ Class selector
contact button
→ ID + type selector
The ID-based selector is more specific, so:
contact button
wins.
The button becomes:
green
- Specificity Score
Specificity is commonly represented using three levels:
(ID, Class, Type)
For example:
button
(0, 0, 1)
One type selector.
.send-btn
(0, 1, 0)
One class selector.
contact
(1, 0, 0)
One ID selector.
contact .send-btn
(1, 1, 0)
One ID + one class.
The browser compares the numbers from left to right.
So:
(1, 0, 0) beats:
(0, 100, 0)
because an ID is in a higher specificity category than classes.
- What Happens When Specificity is Equal?
Suppose we write:
.button {
background-color: blue;
}
.button {
background-color: red;
}
Both selectors have exactly the same specificity.
Therefore, source order decides the winner.
The second rule wins.
The button becomes:
red
So a simple rule to remember is:
If specificity is tied, the later applicable rule wins.
- Inline Styles
Inline styles are written directly inside the HTML element.
Example:
Send
Inline styles have very high priority compared with normal stylesheet rules.
They are therefore another important part of understanding CSS conflicts.
However, using inline styles everywhere can make a project harder to maintain, so stylesheets or reusable classes are generally preferred for normal styling.
- Why should we avoid excessive !important?
!important gives a declaration very high priority.
Example:
.button {
background-color: red !important;
}
It can be useful in specific situations, but using it repeatedly can create specificity wars.
For example, if many rules contain !important, overriding a style becomes difficult.
Instead of immediately writing:
color: red !important;
it is better to ask:
Which selector is currently winning?
Is another selector more specific?
Is the rule appearing later?
Is there an inline style?
Can I simplify the selectors?
The goal is to understand the cascade rather than fight it.
- Inheritance
Inheritance means that some CSS properties can automatically receive their value from a parent element.
For example:
.parent {
color: darkblue;
}
If a paragraph is inside that parent, the paragraph can inherit the text color.
Not every CSS property is inherited.
For example, properties such as:
color → commonly inherited
font-family → commonly inherited
margin → not normally inherited
padding → not normally inherited
border → not normally inherited
So inheritance depends on the specific CSS property.
- inherit
The keyword inherit tells an element:
"Use the value from my parent."
Example:
.parent {
box-sizing: border-box;
}
.child {
box-sizing: inherit;
}
The child takes the parent's box-sizing value.
If the parent uses border-box, the child also uses border-box.
If the parent changes to content-box, the child follows it.
- initial
initial means:
"Use the property's initial value defined by CSS."
For box-sizing, the initial value is:
content-box
Therefore:
box-sizing: initial;
sets it back to:
content-box
- unset
unset works differently depending on whether the property normally inherits.
It means:
If the property normally inherits, inherit it. Otherwise, use its initial value.
Since box-sizing is not normally inherited:
box-sizing: unset;
results in its initial value:
content-box
- revert
revert tells the browser to step back in the cascade and use the value that would have applied from an earlier cascade origin.
In simple terms:
"Undo the styling from this CSS level and go back to the previous applicable value."
It is useful when we want to remove an author-level override without manually specifying another value.
- revert-layer
revert-layer is related to CSS Cascade Layers.
It means:
"Undo the value from the current cascade layer and use the value from an earlier applicable layer."
For example, modern CSS can organize styles into layers such as:
Reset
Components
Utilities
revert-layer can move the property back to what an earlier layer specified.
This is a more advanced feature and is mainly useful when a project is using CSS cascade layers.
- CSS Custom Properties
CSS custom properties are commonly called CSS variables.
They allow us to store reusable values.
Example:
:root {
--main-color: #173b6c;
--spacing: 16px;
}
We can then use them with:
.card {
color: var(--main-color);
padding: var(--spacing);
}
Instead of writing the same value repeatedly, we can store it once and reuse it.
If we later change:
--main-color
the elements using that variable can automatically use the new value.
- Why Simple CSS is Better
When working on a real project, CSS can become difficult to maintain if selectors are overly complicated.
For example, this is unnecessarily specific:
body div.sidebar ul li a {
color: red;
}
A simpler class-based selector is often easier to understand:
.sidebar-link {
color: red;
}
Simple selectors make the cascade easier to predict and reduce the need for !important.
- Using Chrome DevTools for CSS Debugging
Chrome DevTools is extremely useful when something doesn't look right.
A useful workflow is:
Open the webpage.
Right-click the element.
Select Inspect.
Look at the Styles panel.
Look at the Computed styles when necessary.
Look at the Box Model diagram.
Check which rules are active.
Check which declarations are crossed out.
Temporarily uncheck a CSS property to see what changes.
This helps us understand why a style is being applied instead of guessing.
- Final Practical Summary
The most important concepts to remember are:
Box Model
Content → Padding → Border → Margin
Content is the actual material inside the element.
Padding is space inside the border.
Border is the visible boundary.
Margin is space outside the border.
content-box
Width = Content width
Padding and border are added outside.
border-box
Width = Entire border-box width
Padding and border fit inside the declared width.
Cascade
The browser uses the cascade to decide which competing CSS declaration wins.
Specificity
A selector with higher specificity normally wins.
The basic order is:
ID → Class/Attribute/Pseudo-class → Type
If specificity is tied:
Later rule wins.
Inheritance
Some properties can pass from a parent to its children.
Global Keywords
inherit → use parent's value
initial → use property's initial value
unset → inherit if normally inherited, otherwise use initial
revert → step back through the cascade
revert-layer → step back through the current cascade layer
!important
Use carefully. Understanding the cascade is better than repeatedly forcing styles with !important.
CSS Variables
Use custom properties such as:
--main-color
and access them with:
var(--main-color)
Conclusion
Understanding CSS is not about memorizing hundreds of properties. It is about understanding how the browser thinks.
The Box Model explains how an element occupies space.
The Cascade explains how competing CSS rules are resolved.
Specificity explains which selector has more priority.
Inheritance explains how some styles move from parent to child.
And box-sizing: border-box helps make element dimensions more predictable.
Once these fundamentals are clear, debugging CSS becomes much easier because instead of randomly changing properties, we can inspect the element, understand the box model, check the cascade, and identify exactly why a particular style is winning.
Top comments (0)