CSS File Structure
The project uses a modular CSS architecture with three separate stylesheets, each serving a specific purpose:
css/
├── reset.css # Browser normalization
├── variables.css # Design tokens
└── global.css # Component styles
This separation creates a clear hierarchy: reset styles, design system tokens, then component implementations.
Load Order Matters
The HTML loads stylesheets in a specific order:
< link rel = "stylesheet" href = "css/reset.css" />
< link rel = "stylesheet" href = "css/variables.css" />
< link rel = "stylesheet" href = "css/global.css" />
This order ensures:
Reset - Normalize browser defaults first
Variables - Define design tokens
Global - Apply component styles using those tokens
reset.css: Browser Normalization
The reset file removes default browser styles for consistency:
* {
margin : 0 ;
padding : 0 ;
box-sizing : border-box ;
}
a {
text-decoration : none ;
color : inherit ;
}
button {
border : none ;
background : none ;
cursor : pointer ;
font-family : inherit ;
}
ul {
list-style : none ;
}
Why Reset Styles?
Browsers apply default styles inconsistently. A reset ensures:
No unexpected margins or padding
box-sizing: border-box for predictable sizing
Clean slate for custom styling
Using box-sizing: border-box means width includes padding and borders, making layouts more predictable.
variables.css: Design Tokens
CSS custom properties create a centralized design system:
:root {
/* Primary Colors */
--primary-black : #000000 ;
--primary-neutral : #404040 ;
--primary-white : #FFFFFF ;
/* Zinc Scale */
--zinc-100 : #f4f4f5 ;
--zinc-200 : #e4e4e7 ;
--zinc-300 : #d4d4d8 ;
--zinc-500 : #71717a ;
--zinc-800 : #27272a ;
/* Error */
--error-500 : #ef4444 ;
/* Spacing Scale */
--spacing-4 : 4 px ;
--spacing-8 : 8 px ;
--spacing-12 : 12 px ;
--spacing-16 : 16 px ;
--spacing-20 : 20 px ;
--spacing-24 : 24 px ;
--spacing-28 : 28 px ;
--spacing-32 : 32 px ;
--spacing-36 : 36 px ;
--spacing-40 : 40 px ;
--outline-width : 2 px ;
--max-width : 1280 px ;
}
Design System Benefits
Single Source of Truth Change a color once, update everywhere it’s used
Consistency All spacing uses the same 4px-based scale
Maintainability Easy to adjust designs without hunting through CSS
Semantic Naming Names describe purpose, not appearance
Responsive Variables
Some variables change at breakpoints:
@media ( min-width : 768 px ) {
:root {
--outline-width : 4 px ;
}
}
The outline effect on text becomes thicker on larger screens for visual impact.
global.css: Component Styles
The main stylesheet contains all component implementations:
Organization Pattern
/* Utility Classes */
.outlined { ... }
.section-title { ... }
.section-container { ... }
/* Header Section */
.header { ... }
.header__brand { ... }
.header__nav { ... }
/* Hero Section */
.hero { ... }
.hero__content { ... }
.hero__title { ... }
/* And so on... */
Components are grouped by section with clear comments:
/* --- HEADER SECTION --- */
/* --- HERO SECTION --- */
This organization makes finding and updating component styles straightforward. Each section comment acts as a visual bookmark.
BEM Naming Convention
The project uses a BEM-like (Block Element Modifier) naming pattern:
.block // Component root
.block__element // Child element
.block--modifier // Variation
Real Examples
Header Component:
.header // Block
.header__brand // Element
.header__logo // Element
.header__nav // Element
.header__nav--active // Modifier
Skill Card Component:
.skill-card // Block
.skill-card__icon // Element
.skill-card__label // Element
Project Card Component:
.project-card // Block
.project-card__image // Element
.project-card__title // Element
.project-card--reverse // Modifier
Why BEM?
The naming immediately shows which elements belong to which components.
Flat structure prevents specificity wars and makes styles predictable.
Class names describe structure and purpose without looking at HTML.
All selectors have equal specificity, avoiding !important hacks.
Utility-First Patterns
Some classes are reusable utilities:
Section Container
.section-container {
padding : var ( --spacing-40 ) var ( --spacing-16 );
max-width : var ( --max-width );
margin : 0 auto ;
width : 100 % ;
display : flex ;
flex-direction : column ;
gap : var ( --spacing-32 );
}
Used by every major section for consistent spacing and max-width:
< section class = "hero" >
< div class = "section-container" >
<!-- Content -->
</ div >
</ section >
Outlined Text Effect
.outlined {
font-weight : 800 ;
color : var ( --primary-white );
text-shadow :
var ( --outline-width ) 0 var ( --primary-black ),
calc ( var ( --outline-width ) * -1 ) 0 var ( --primary-black ),
/* ... 8 shadows total for outline effect ... */
}
Applied to text that needs the distinctive outline style:
Frontend < span class = "outlined" > Developer </ span >
All media queries use min-width for progressive enhancement:
/* Mobile styles (no media query) */
.element {
font-size : 16 px ;
}
/* Tablet and up */
@media ( min-width : 768 px ) {
.element {
font-size : 18 px ;
}
}
/* Desktop and up */
@media ( min-width : 1024 px ) {
.element {
font-size : 20 px ;
}
}
Mobile styles are the default with no media query. This ensures they work even if media queries fail.
Component Encapsulation
Each component’s styles are scoped with class names:
/* Hero styles don't affect other sections */
.hero { ... }
.hero__title { ... }
.hero__image { ... }
/* Project styles are separate */
.project-card { ... }
.project-card__title { ... }
.project-card__image { ... }
No styles bleed between components, even though they use the same element types (h1, img, etc.).
The CSS includes commented-out alternative approaches:
/* .skills__grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--spacing-20);
}
@media (min-width: 768px) {
.skills__grid {
grid-template-columns: repeat(4, 1fr);
gap: var(--spacing-32);
}
}
@media (min-width: 1024px) {
.skills__grid {
grid-template-columns: repeat(5, 1fr);
}
} */
This shows the original approach before switching to auto-fit. Great for learning different solutions!
Single CSS Bundle
All three CSS files are separate in development but could be combined in production:
<!-- Development: separate files for organization -->
< link rel = "stylesheet" href = "css/reset.css" />
< link rel = "stylesheet" href = "css/variables.css" />
< link rel = "stylesheet" href = "css/global.css" />
<!-- Production: combine for fewer HTTP requests -->
< link rel = "stylesheet" href = "css/styles.min.css" />
Efficient Selectors
All selectors use single class names for maximum performance:
/* ✅ Fast: single class */
.skill-card { ... }
/* ❌ Slow: deeply nested */
.skills .skills__grid .skill-card { ... }
No Unused Styles
Every style corresponds to an element in index.html. No bloat or unused code.
Best Practices Demonstrated
Modular Files Separate concerns: reset, variables, components
Custom Properties Centralized design system with CSS variables
BEM Naming Clear, predictable class names
Mobile-First Default styles for mobile, enhance for desktop
Comments Section markers for easy navigation
Flat Specificity Single class selectors, no specificity wars
Quick Reference
File Purpose Key Features reset.css Browser normalization Zero margins/padding, box-sizing variables.css Design tokens Colors, spacing, breakpoints global.css Component styles BEM naming, mobile-first
Next Steps
CSS Variables Explore all custom properties in detail
Responsive Breakpoints Learn the breakpoint strategy