CSS Fundamentals Review
Before diving into advanced CSS topics, it is important to review some fundamental concepts that affect how styles are applied and calculated. This review covers CSS specificity, the box model, the cascade, and the modern CSS landscape. These concepts should be familiar from previous coursework, but a refresher will help ensure you have a solid foundation moving forward.
CSS Specificity
Specificity determines which CSS rules are applied when multiple rules target the same element. Understanding specificity helps you predict which styles will win when conflicts arise and write more maintainable CSS.
How Specificity is Calculated
Specificity is calculated based on the types of selectors used in a rule. Each selector type has a different weight:
- Inline styles: Highest specificity (1,0,0,0)
- IDs: High specificity (0,1,0,0)
- Classes, attributes, and pseudo-classes: Medium specificity (0,0,1,0)
- Elements and pseudo-elements: Low specificity (0,0,0,1)
When comparing two selectors, the one with higher specificity wins. If specificity is equal, the rule that appears later in the stylesheet takes precedence.
/* Specificity: 0,0,0,1 */
p {
color: blue;
}
/* Specificity: 0,0,1,0 */
.intro {
color: green;
}
/* Specificity: 0,1,0,0 */
#header {
color: red;
}
/* Specificity: 0,0,1,1 */
p.intro {
color: purple;
}
Specificity Calculator Tools
When working with complex selectors, it can be helpful to use a specificity calculator to determine which rule will win. Here are some useful tools:
- CSS Bootcamp Specificity Calculator
- Specificity Calculator by Keegan Street
- Polypane CSS Specificity Calculator
Common Mistakes and !important
A common mistake is overusing IDs or overly specific selectors, which makes stylesheets difficult to maintain and override. Another pitfall is relying on !important to force styles to apply. While !important can be useful in specific situations, it should be used sparingly because it overrides normal specificity rules and makes debugging harder.
/* Avoid this pattern */
p {
color: blue !important;
}
/* Now this won't work, even though it's more specific */
#content p.highlight {
color: red;
}
Reserve !important for overriding third-party styles or handling exceptional cases. In most situations, adjusting your selector specificity is a better approach. You should avoid using !important in this course.
The Box Model
Every element in HTML is represented as a rectangular box. The box model describes how the size of these boxes is calculated, including content, padding, border, and margin.
content-box vs border-box
By default, browsers use content-box sizing, which means the width and height properties only apply to the content area. Padding and border are added on top of the specified dimensions, making the actual rendered size larger than expected.
/* content-box (default) */
.box {
width: 200px;
padding: 20px;
border: 5px solid black;
}
/* Actual width: 200px + 40px padding + 10px border = 250px */
The border-box model includes padding and border within the specified width and height, making sizing more intuitive and predictable.
/* border-box */
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid black;
}
/* Actual width: 200px (padding and border included) */
Why We Use border-box Globally
Most developers prefer border-box sizing because it simplifies layout calculations. A common practice is to apply border-box to all elements using the universal selector:
*,
*::before,
*::after {
box-sizing: border-box;
}
This rule ensures consistent sizing behavior across your entire page, including pseudo-elements.
Margin Collapse
Margins between adjacent elements can collapse, meaning they combine into a single margin rather than adding together. The larger of the two margins is used.
.element-one {
margin-bottom: 30px;
}
.element-two {
margin-top: 20px;
}
/* The space between them is 30px, not 50px */
Margin collapse only happens with vertical margins between block-level elements. Horizontal margins, padding, and margins inside flex or grid containers do not collapse.
The CSS Cascade
The cascade is the algorithm browsers use to determine which CSS rules apply to each element. Understanding the cascade helps you write CSS that behaves predictably.
Order of Importance
When multiple rules apply to the same element, the browser considers three factors in this order:
-
Source and importance: Inline styles override external stylesheets, and
!importantdeclarations override normal declarations. - Specificity: Rules with higher specificity override those with lower specificity.
- Order: If two rules have the same specificity, the one that appears later in the stylesheet wins.
/* First rule */
p {
color: blue;
}
/* Second rule with same specificity - this wins */
p {
color: red;
}
Common Cascade Mistakes
A frequent mistake is placing a less specific rule after a more specific one and expecting it to override. Another issue is not considering the cascade when organizing stylesheets, leading to unexpected behavior when rules are reordered or combined.
/* More specific rule */
div.content p {
color: blue;
}
/* This won't work because it's less specific */
p {
color: red;
}
Organize your stylesheets logically, with general styles first and more specific styles later. This approach leverages the cascade naturally and reduces the need for overly specific selectors.
Modern CSS Landscape
CSS has evolved significantly in recent years, with new features that make layout, styling, and responsive design much easier. Staying aware of modern CSS capabilities helps you write cleaner, more maintainable code.
Browser Compatibility
Not all CSS features are supported equally across browsers. Before using a new CSS property or feature, check its compatibility using Can I Use. This tool shows which browsers support specific features and provides usage statistics to help you decide if a feature is safe to use for your target audience.
What's New in CSS
Recent additions to CSS include container queries for responsive components, the :has() selector for parent styling, cascade layers for better style organization, and native CSS nesting. These features reduce the need for preprocessors and JavaScript workarounds in many cases.
Looking Ahead
CSS continues to evolve with proposals for new features like advanced color functions, scoped styles, and improved animation capabilities. As the course progresses, we will explore some of these modern features and discuss when and how to use them effectively.
While modern CSS features are powerful, always consider your project's browser support requirements. Progressive enhancement (providing a good experience for all users while enhancing for capable browsers) remains a best practice.
Putting It All Together
Modern CSS now supports native nesting, which allows you to write more organized and readable stylesheets. Here is a practical example that demonstrates specificity, the box model, and the cascade working together:
/* Global border-box reset */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Base card styling - Low specificity (0,0,1,0) */
.card {
width: 300px;
padding: 20px;
margin: 20px;
border: 2px solid #ddd;
background: white;
/* Nested selector for card title */
h2 {
margin-top: 0; /* Prevents margin collapse at top */
color: #333;
font-size: 1.5rem;
}
/* Nested selector for card content */
.content {
margin-bottom: 0; /* Prevents margin collapse at bottom */
line-height: 1.6;
/* Further nesting for links inside content */
a {
color: #0066cc;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
/* Nested modifier for featured cards */
&.featured {
border-color: #0066cc;
border-width: 3px;
h2 {
color: #0066cc; /* Higher specificity wins */
}
}
}
/* This would NOT override .card.featured h2 */
/* Specificity: 0,0,1,1 vs 0,0,2,1 */
.card h2 {
color: #666;
}
This example demonstrates several key concepts:
-
The
border-boxreset ensures the card's 300px width includes padding and border - Margin is set on top and bottom to control spacing, with specific values at 0 to prevent margin collapse issues
-
Nested selectors create higher specificity naturally (
.card.featured h2is more specific than.card h2) -
The cascade order matters: the
.card h2rule at the end would normally override earlier rules with the same specificity, but it loses to.card.featured h2due to specificity -
Modern nesting syntax with
&references the parent selector, making the structure clear and maintainable
Native CSS nesting is now supported in all modern browsers. It reduces the need for preprocessors like Sass while keeping your styles organized and your selectors appropriately specific.
Moving Forward
With these fundamentals refreshed, you are ready to tackle more advanced CSS topics. Keep these concepts in mind as you work through assignments and build projects. Understanding specificity, the box model, and the cascade will help you debug issues faster and write more maintainable stylesheets.