DEV Community

Deepika Pusala
Deepika Pusala

Posted on

Day-5 as Full Stack Intern: Responsive Images & CSS methodologies

3. Responsive Images — srcset and <picture>

What are Responsive Images?

Responsive images are images that adapt to the user's device, viewport size, and display conditions.

For example, a website may be opened on:

📱 Mobile → 390px wide
📱 Tablet → 768px wide
💻 Laptop → 1366px wide
🖥️ Desktop → 1920px wide
Enter fullscreen mode Exit fullscreen mode

Instead of always downloading a very large image, we can provide different image versions and allow the browser to choose an appropriate one.

The main technologies used for responsive images are:

srcset
sizes
<picture>
<source>
Enter fullscreen mode Exit fullscreen mode

Why Do We Need Responsive Images?

Suppose we have:

hero.jpg
4000 × 3000
5 MB
Enter fullscreen mode Exit fullscreen mode

But on a mobile phone, the image is displayed at only:

390px wide
Enter fullscreen mode Exit fullscreen mode

Downloading a huge 4000px image for a small display can waste:

  • Bandwidth
  • Loading time
  • Mobile data
  • Browser resources

Responsive images allow us to provide multiple versions:

hero-400.jpg
hero-800.jpg
hero-1200.jpg
hero-1600.jpg
Enter fullscreen mode Exit fullscreen mode

Then the browser can choose an appropriate image.


Normal <img>

A normal image looks like:

<img src="hero.jpg" alt="Mountain landscape">
Enter fullscreen mode Exit fullscreen mode

Here:

src
↓
The image file to load

alt
↓
Alternative text describing the image
Enter fullscreen mode Exit fullscreen mode

The problem is that there is only one image source.


srcset

srcset allows us to provide multiple versions of the same image with different resolutions.

Example:

<img
    src="hero-800.jpg"
    srcset="
        hero-400.jpg 400w,
        hero-800.jpg 800w,
        hero-1200.jpg 1200w
    "
    alt="Mountain landscape"
>
Enter fullscreen mode Exit fullscreen mode

We are telling the browser:

Here are different versions of the same image.

400w → 400px wide image
800w → 800px wide image
1200w → 1200px wide image
Enter fullscreen mode Exit fullscreen mode

The browser can then choose an appropriate candidate.


What does w mean?

The w descriptor represents the intrinsic width of the image file.

For example:

hero-400.jpg 400w
Enter fullscreen mode Exit fullscreen mode

means:

This image file is 400px wide.

Similarly:

hero-800.jpg 800w
Enter fullscreen mode Exit fullscreen mode

means:

This image file is 800px wide.

So:

400w → 400px image
800w → 800px image
1200w → 1200px image
Enter fullscreen mode Exit fullscreen mode

How Does the Browser Choose?

Suppose we provide:

<img
    srcset="
        image-400.jpg 400w,
        image-800.jpg 800w,
        image-1200.jpg 1200w
    "
>
Enter fullscreen mode Exit fullscreen mode

The browser considers factors such as:

  • Viewport size
  • How large the image will be displayed
  • Device pixel density
  • Available image candidates

and chooses an appropriate image.

The important idea is:

srcset
   ↓
provides choices
   ↓
browser evaluates them
   ↓
browser chooses a suitable candidate
Enter fullscreen mode Exit fullscreen mode

We don't manually have to write JavaScript to detect the screen size.


What is sizes?

sizes tells the browser:

How wide the image is expected to be displayed in the layout.

Example:

<img
    src="hero-800.jpg"
    srcset="
        hero-400.jpg 400w,
        hero-800.jpg 800w,
        hero-1200.jpg 1200w
    "
    sizes="100vw"
    alt="Mountain landscape"
>
Enter fullscreen mode Exit fullscreen mode

Here:

sizes="100vw"
Enter fullscreen mode Exit fullscreen mode

means:

The image is expected to occupy approximately 100% of the viewport width.


srcset vs sizes

This is one of the most important things to understand.

srcset
↓
WHAT IMAGE FILES ARE AVAILABLE?


sizes
↓
HOW LARGE WILL THE IMAGE APPEAR?
Enter fullscreen mode Exit fullscreen mode

For example:

<img
    srcset="
        image-400.jpg 400w,
        image-800.jpg 800w,
        image-1200.jpg 1200w
    "
    sizes="100vw"
>
Enter fullscreen mode Exit fullscreen mode

Here:

srcset
→ available image candidates

sizes
→ expected displayed width
Enter fullscreen mode Exit fullscreen mode

sizes Does NOT Resize the Image

This is a common beginner mistake.

If we write:

sizes="50vw"
Enter fullscreen mode Exit fullscreen mode

it does not mean:

Make the image 50vw wide.

Instead, it tells the browser:

The image is expected to be displayed at approximately 50vw wide.

The actual visual size can be controlled with CSS.

For example:

img {
    width: 50%;
}
Enter fullscreen mode Exit fullscreen mode

Using Media Conditions Inside sizes

We can provide different expected sizes depending on the viewport.

Example:

<img
    src="hero-800.jpg"
    srcset="
        hero-400.jpg 400w,
        hero-800.jpg 800w,
        hero-1200.jpg 1200w,
        hero-1600.jpg 1600w
    "
    sizes="
        (min-width: 1200px) 50vw,
        (min-width: 768px) 70vw,
        100vw
    "
    alt="Mountain landscape"
>
Enter fullscreen mode Exit fullscreen mode

This means:

Viewport >= 1200px
→ image is expected to be about 50vw wide

Viewport >= 768px
→ image is expected to be about 70vw wide

Otherwise
→ image is expected to be about 100vw wide
Enter fullscreen mode Exit fullscreen mode

This helps the browser choose an appropriate candidate from srcset.


Responsive Display vs Responsive Source

These are different concepts.

CSS:

img {
    width: 100%;
    height: auto;
}
Enter fullscreen mode Exit fullscreen mode

controls:

How large the image appears on the page.

srcset controls:

Which image candidates are available to the browser.

sizes tells the browser:

How large the image is expected to appear.

So:

CSS
↓
controls displayed size

srcset
↓
provides image candidates

sizes
↓
describes expected displayed size
Enter fullscreen mode Exit fullscreen mode

x Descriptors

srcset can also use x descriptors.

Example:

<img
    src="image.jpg"
    srcset="
        image.jpg 1x,
        image@2x.jpg 2x
    "
    alt="Logo"
>
Enter fullscreen mode Exit fullscreen mode

Here:

1x
↓
normal pixel density

2x
↓
higher pixel density
Enter fullscreen mode Exit fullscreen mode

This is useful for high-density displays.

For example, an image displayed at 200 CSS pixels wide may need more physical pixels on a high-density screen.


w vs x

w

Represents the intrinsic width of the image.

image-400.jpg 400w
image-800.jpg 800w
Enter fullscreen mode Exit fullscreen mode

x

Represents pixel-density variants.

image.jpg 1x
image@2x.jpg 2x
Enter fullscreen mode Exit fullscreen mode

For general responsive image layouts, w descriptors combined with sizes are very important to understand.


<picture>

<picture> is another HTML element used for responsive images.

It is especially useful when we need:

  • Different image crops
  • Different image compositions
  • Different image formats
  • Different image sources based on conditions

Basic structure:

<picture>

    <source
        media="(max-width: 600px)"
        srcset="mobile.jpg"
    >

    <source
        media="(min-width: 601px)"
        srcset="desktop.jpg"
    >

    <img
        src="desktop.jpg"
        alt="Landscape"
    >

</picture>
Enter fullscreen mode Exit fullscreen mode

Why Use <picture>?

Imagine a desktop image:

┌────────────────────────────────────┐
│                                    │
│             PERSON                 │
│                                    │
│        Large background            │
│                                    │
└────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

On mobile, simply shrinking the same image might produce a poor composition.

Instead, we can create a mobile-specific crop:

┌──────────────┐
│              │
│    PERSON    │
│              │
└──────────────┘
Enter fullscreen mode Exit fullscreen mode

Then:

Mobile
→ mobile.jpg

Desktop
→ desktop.jpg
Enter fullscreen mode Exit fullscreen mode

This is called art direction.


<picture> for Different Image Formats

<picture> can also be used to provide different image formats.

For example:

hero.avif
hero.webp
hero.jpg
Enter fullscreen mode Exit fullscreen mode

We can write:

<picture>

    <source
        srcset="hero.avif"
        type="image/avif"
    >

    <source
        srcset="hero.webp"
        type="image/webp"
    >

    <img
        src="hero.jpg"
        alt="Mountain landscape"
    >

</picture>
Enter fullscreen mode Exit fullscreen mode

The browser can use a supported format and fall back to the <img> source when necessary.


What is <source>?

<source> provides an alternative image source inside <picture>.

For example:

<source
    srcset="hero.webp"
    type="image/webp"
>
Enter fullscreen mode Exit fullscreen mode

means:

This is an available WebP image source.

Another example:

<source
    media="(max-width: 600px)"
    srcset="mobile.jpg"
>
Enter fullscreen mode Exit fullscreen mode

means:

Use this source when the specified media condition matches.

The <img> element inside <picture> acts as the fallback/default image.


srcset vs <picture>

This is the most important comparison in responsive images.

srcset

Usually used when we have:

The same image in different sizes.

Example:

hero-400.jpg
hero-800.jpg
hero-1200.jpg
Enter fullscreen mode Exit fullscreen mode

Think:

SAME IMAGE
+
DIFFERENT SIZES
Enter fullscreen mode Exit fullscreen mode

<picture>

Used when we need:

Different image sources depending on conditions.

For example:

Mobile → mobile-crop.jpg
Desktop → desktop-crop.jpg
Enter fullscreen mode Exit fullscreen mode

or:

AVIF → WebP → JPEG
Enter fullscreen mode Exit fullscreen mode

Think:

DIFFERENT SOURCES
+
DIFFERENT CONDITIONS / FORMATS
Enter fullscreen mode Exit fullscreen mode

Simple Mental Model

Remember:

srcset
↓
"Here are different-sized versions
 of the same image."


sizes
↓
"Here is approximately how large
 the image will appear."


<picture>
↓
"Here are different image sources
 depending on the situation."
Enter fullscreen mode Exit fullscreen mode

Complete Responsive Image Example

<img
    src="hero-800.jpg"
    srcset="
        hero-400.jpg 400w,
        hero-800.jpg 800w,
        hero-1200.jpg 1200w,
        hero-1600.jpg 1600w
    "
    sizes="
        (min-width: 1200px) 50vw,
        (min-width: 768px) 70vw,
        100vw
    "
    alt="Mountain landscape"
>
Enter fullscreen mode Exit fullscreen mode

The structure is:

src
↓
fallback/default source

srcset
↓
different image candidates

sizes
↓
expected displayed width

alt
↓
alternative text
Enter fullscreen mode Exit fullscreen mode

When Should You Use srcset?

Use srcset when you have:

Same image
    ↓
Different resolutions
Enter fullscreen mode Exit fullscreen mode

For example:

product-400.jpg
product-800.jpg
product-1200.jpg
Enter fullscreen mode Exit fullscreen mode

When Should You Use <picture>?

Use <picture> when you need:

Different crop
Different composition
Different image format
Different source based on conditions
Enter fullscreen mode Exit fullscreen mode

For example:

Mobile → portrait image
Desktop → landscape image
Enter fullscreen mode Exit fullscreen mode

or:

AVIF → WebP → JPEG
Enter fullscreen mode Exit fullscreen mode

Important Summary

Responsive Images
        │
        ├── srcset
        │     ↓
        │  multiple image candidates
        │
        ├── sizes
        │     ↓
        │  expected displayed width
        │
        └── picture
              ↓
        different image sources
        / formats / crops
Enter fullscreen mode Exit fullscreen mode

The main goal is:

Deliver an appropriate image resource instead of unnecessarily downloading a huge image for every device.


4. CSS Methodologies — BEM Naming

What is a CSS Methodology?

A CSS methodology is a systematic approach for writing, naming, and organizing CSS so that the code remains understandable and maintainable as a project becomes larger.

In a small project, we might write:

<div class="box">
    <h2 class="title">Product</h2>
    <button class="button">Buy</button>
</div>
Enter fullscreen mode Exit fullscreen mode

and:

.box {
    ...
}

.title {
    ...
}

.button {
    ...
}
Enter fullscreen mode Exit fullscreen mode

This may work for a small project.

But in a large application, we might have:

100+ components
500+ classes
multiple developers
many pages
Enter fullscreen mode Exit fullscreen mode

Now generic class names such as:

.title
.button
.container
.box
.item
Enter fullscreen mode Exit fullscreen mode

can become confusing and cause style conflicts.

CSS methodologies provide conventions to solve these problems.


Examples of CSS Methodologies

Some commonly known CSS approaches are:

BEM
OOCSS
SMACSS
ITCSS
Utility-first CSS
CSS Modules
Enter fullscreen mode Exit fullscreen mode

Each approach has a different philosophy for organizing CSS.

For this topic, the most important one is:

BEM


What is BEM?

BEM stands for:

B → Block
E → Element
M → Modifier
Enter fullscreen mode Exit fullscreen mode

BEM is a naming methodology that helps us create clear and predictable CSS class names.

The main idea is to describe:

What is the component?
What parts belong to it?
What variations does it have?
Enter fullscreen mode Exit fullscreen mode

BEM Syntax

The basic BEM naming patterns are:

Block
block
Enter fullscreen mode Exit fullscreen mode
Element
block__element
Enter fullscreen mode Exit fullscreen mode
Modifier
block--modifier
Enter fullscreen mode Exit fullscreen mode
Element Modifier
block__element--modifier
Enter fullscreen mode Exit fullscreen mode

The two important symbols are:

__ → Element

-- → Modifier
Enter fullscreen mode Exit fullscreen mode

1. Block

A Block is an independent, reusable component.

Examples:

card
navbar
header
footer
button
form
modal
search
product-card
Enter fullscreen mode Exit fullscreen mode

Example:

<div class="card">
Enter fullscreen mode Exit fullscreen mode

Here:

card
↓
Block
Enter fullscreen mode Exit fullscreen mode

A Block should be meaningful and independent.

For example:

Card
Navbar
Button
Modal
Enter fullscreen mode Exit fullscreen mode

can exist as separate UI components.


Real-Life Analogy for a Block

Think of a LEGO block.

🧱
Enter fullscreen mode Exit fullscreen mode

It is an independent piece that can be reused in different places.

Similarly:

.card
Enter fullscreen mode Exit fullscreen mode

is an independent UI component.


2. Element

An Element is a meaningful part of a Block.

BEM uses two underscores:

__
Enter fullscreen mode Exit fullscreen mode

The syntax is:

block__element
Enter fullscreen mode Exit fullscreen mode

For example:

card__image
card__title
card__description
card__button
Enter fullscreen mode Exit fullscreen mode

Here:

card
 ↓
Block

title
 ↓
Element

card__title
 ↓
Element belonging to card
Enter fullscreen mode Exit fullscreen mode

Example of Block + Elements

<div class="card">

    <img class="card__image" src="phone.jpg" alt="Phone">

    <h2 class="card__title">
        Smartphone
    </h2>

    <p class="card__description">
        A powerful smartphone.
    </p>

    <button class="card__button">
        Buy Now
    </button>

</div>
Enter fullscreen mode Exit fullscreen mode

The structure is:

card
│
├── card__image
├── card__title
├── card__description
└── card__button
Enter fullscreen mode Exit fullscreen mode

3. Modifier

A Modifier represents a variation, state, or different version of a Block or Element.

BEM uses:

--
Enter fullscreen mode Exit fullscreen mode

The syntax is:

block--modifier
Enter fullscreen mode Exit fullscreen mode

Example:

card--featured
card--dark
card--large
Enter fullscreen mode Exit fullscreen mode

For example:

<div class="card card--featured">
Enter fullscreen mode Exit fullscreen mode

Here:

card
↓
Block

card--featured
↓
Modifier
Enter fullscreen mode Exit fullscreen mode

The card is still a card, but it is the featured version of the card.


Why Use Both Classes?

A common BEM pattern is:

<button class="button button--primary">
    Submit
</button>
Enter fullscreen mode Exit fullscreen mode

Here:

button
↓
Base Block

button--primary
↓
Modifier
Enter fullscreen mode Exit fullscreen mode

The base class provides the common styles:

.button {
    padding: 10px 20px;
    border-radius: 8px;
}
Enter fullscreen mode Exit fullscreen mode

The modifier provides the variation:

.button--primary {
    background: blue;
    color: white;
}
Enter fullscreen mode Exit fullscreen mode

So:

button
+
button--primary
↓
Primary button
Enter fullscreen mode Exit fullscreen mode

Modifiers Can Represent Different States

Modifiers are not only for colors.

They can represent:

Different types

button--primary
button--secondary
button--danger
Enter fullscreen mode Exit fullscreen mode

Different sizes

button--small
button--large
Enter fullscreen mode Exit fullscreen mode

Different themes

card--dark
card--light
Enter fullscreen mode Exit fullscreen mode

Different states

button--disabled
menu--open
input--invalid
Enter fullscreen mode Exit fullscreen mode

Element Modifiers

Elements can also have modifiers.

Example:

card__title
Enter fullscreen mode Exit fullscreen mode

Normal title.

A highlighted version:

card__title--highlighted
Enter fullscreen mode Exit fullscreen mode

So the structure becomes:

card
│
└── card__title
        │
        └── card__title--highlighted
Enter fullscreen mode Exit fullscreen mode

Complete BEM Example

Let's create a product card.

<article class="product-card product-card--featured">

    <img
        class="product-card__image"
        src="laptop.jpg"
        alt="Laptop"
    >

    <h2 class="product-card__title">
        Laptop
    </h2>

    <p class="product-card__price">
        ₹80,000
    </p>

    <button class="product-card__button product-card__button--primary">
        Buy Now
    </button>

</article>
Enter fullscreen mode Exit fullscreen mode

Let's identify everything.

Block

product-card
Enter fullscreen mode Exit fullscreen mode

Block Modifier

product-card--featured
Enter fullscreen mode Exit fullscreen mode

Elements

product-card__image
product-card__title
product-card__price
product-card__button
Enter fullscreen mode Exit fullscreen mode

Element Modifier

product-card__button--primary
Enter fullscreen mode Exit fullscreen mode

The structure is:

product-card
│
├── product-card--featured
│
├── product-card__image
├── product-card__title
├── product-card__price
│
└── product-card__button
        │
        └── product-card__button--primary
Enter fullscreen mode Exit fullscreen mode

CSS for the BEM Example

.product-card {
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 10px;
}

.product-card__image {
    width: 100%;
}

.product-card__title {
    font-size: 1.5rem;
}

.product-card__price {
    font-size: 1.2rem;
}

.product-card__button {
    padding: 10px 20px;
}

.product-card--featured {
    border: 2px solid gold;
}

.product-card__button--primary {
    background: blue;
    color: white;
}
Enter fullscreen mode Exit fullscreen mode

The names clearly tell us which component each style belongs to.


Real-Life Example: Navbar

A navigation bar can be represented as:

navbar
│
├── navbar__logo
├── navbar__menu
├── navbar__item
└── navbar__link
Enter fullscreen mode Exit fullscreen mode

HTML:

<nav class="navbar">

    <div class="navbar__logo">
        MySite
    </div>

    <ul class="navbar__menu">

        <li class="navbar__item">
            <a class="navbar__link" href="#">
                Home
            </a>
        </li>

        <li class="navbar__item">
            <a class="navbar__link" href="#">
                About
            </a>
        </li>

    </ul>

</nav>
Enter fullscreen mode Exit fullscreen mode

A dark version could be:

<nav class="navbar navbar--dark">
Enter fullscreen mode Exit fullscreen mode

Here:

navbar
↓
Block

navbar--dark
↓
Modifier
Enter fullscreen mode Exit fullscreen mode

Real-Life Example: Login Form

Block:

login-form
Enter fullscreen mode Exit fullscreen mode

Elements:

login-form__label
login-form__input
login-form__button
login-form__error
Enter fullscreen mode Exit fullscreen mode

Example:

<form class="login-form">

    <label class="login-form__label">
        Email
    </label>

    <input
        class="login-form__input"
        type="email"
    >

    <button class="login-form__button">
        Login
    </button>

</form>
Enter fullscreen mode Exit fullscreen mode

An invalid input could be:

<input class="login-form__input login-form__input--invalid">
Enter fullscreen mode Exit fullscreen mode

Here:

login-form
↓
Block

login-form__input
↓
Element

login-form__input--invalid
↓
Element Modifier
Enter fullscreen mode Exit fullscreen mode

HTML Nesting vs BEM Naming

One of the most important BEM rules is:

BEM naming does not have to follow the exact HTML nesting structure.

Suppose we have:

<div class="card">
    <div class="card__header">
        <h2 class="card__title">
            Product
        </h2>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Even though the title is inside the header, we normally don't write:

card__header__title
Enter fullscreen mode Exit fullscreen mode

Instead:

card__header
card__title
Enter fullscreen mode Exit fullscreen mode

Both are Elements of the card Block.

BEM describes logical relationships, not every level of HTML nesting.


Avoid Deep BEM Chains

Avoid names such as:

card__header__title__text
Enter fullscreen mode Exit fullscreen mode

Instead, keep the relationship directly connected to the Block:

card__title
Enter fullscreen mode Exit fullscreen mode

This keeps the naming simpler and easier to maintain.


Can a Block Contain Another Block?

Yes.

For example:

<div class="page">

    <header class="header">
        ...
    </header>

    <article class="product-card">
        ...
    </article>

    <footer class="footer">
        ...
    </footer>

</div>
Enter fullscreen mode Exit fullscreen mode

Here:

page
header
product-card
footer
Enter fullscreen mode Exit fullscreen mode

can all be independent Blocks.

If a component can exist independently and be reused, it can often be treated as a Block.


Block vs Element

A useful question to ask is:

Can this component exist independently?

If yes:

Block
Enter fullscreen mode Exit fullscreen mode

If it is a meaningful part of another Block:

Element
Enter fullscreen mode Exit fullscreen mode

For example:

product-card
↓
Block

product-card__title
↓
Element
Enter fullscreen mode Exit fullscreen mode

But a reusable Button could be its own Block:

button
Enter fullscreen mode Exit fullscreen mode

instead of:

product-card__button
Enter fullscreen mode Exit fullscreen mode

if the Button is an independent reusable component.


BEM Is Not "Every HTML Element Gets a Class"

BEM does not mean:

card__div__h2__span
Enter fullscreen mode Exit fullscreen mode

The goal is not to name every HTML tag.

The goal is to identify meaningful components and relationships.

For example:

card
card__title
card__price
card__button
Enter fullscreen mode Exit fullscreen mode

is much more useful than naming every nested <div>.


Naming Modifiers by Meaning

A modifier can describe the meaning or role of a variation.

For example:

button--danger
Enter fullscreen mode Exit fullscreen mode

is often better than:

button--red
Enter fullscreen mode Exit fullscreen mode

Why?

Because the design may change.

Today:

danger → red
Enter fullscreen mode Exit fullscreen mode

Tomorrow:

danger → orange
Enter fullscreen mode Exit fullscreen mode

The meaning of the component hasn't changed.

Therefore:

button--danger
Enter fullscreen mode Exit fullscreen mode

still makes sense.


BEM in React

BEM can also be used with React.

Example:

function ProductCard() {
    return (
        <article className="product-card">

            <h2 className="product-card__title">
                Laptop
            </h2>

            <p className="product-card__price">
                ₹80,000
            </p>

        </article>
    );
}
Enter fullscreen mode Exit fullscreen mode

CSS:

.product-card {
    padding: 20px;
}

.product-card__title {
    font-size: 1.5rem;
}

.product-card__price {
    color: gray;
}
Enter fullscreen mode Exit fullscreen mode

BEM works well with component-based development because the class names clearly describe the component structure.


Other CSS Methodologies

BEM is only one CSS methodology.

Some other approaches include:

BEM
OOCSS
SMACSS
ITCSS
Utility-first CSS
CSS Modules
Enter fullscreen mode Exit fullscreen mode

OOCSS

OOCSS stands for:

Object-Oriented CSS

The idea is to create reusable CSS objects and separate structure from appearance.

For example:

<div class="card rounded shadow">
Enter fullscreen mode Exit fullscreen mode

Conceptually:

card
↓
structure

rounded
↓
reusable appearance

shadow
↓
reusable appearance
Enter fullscreen mode Exit fullscreen mode

The goal is to create reusable styling patterns instead of making everything completely unique.


SMACSS

SMACSS stands for:

Scalable and Modular Architecture for CSS

It organizes CSS into categories such as:

Base
Layout
Module
State
Theme
Enter fullscreen mode Exit fullscreen mode

For example:

Base
↓
body, h1, p

Layout
↓
header, sidebar, grid

Module
↓
card, navbar, button

State
↓
is-active, is-hidden

Theme
↓
dark theme, light theme
Enter fullscreen mode Exit fullscreen mode

The main idea is to organize CSS based on the role of each style.


ITCSS

ITCSS stands for:

Inverted Triangle CSS

It organizes CSS from lower specificity to higher specificity.

A simplified structure is:

Settings
Tools
Generic
Elements
Objects
Components
Utilities
Enter fullscreen mode Exit fullscreen mode

The goal is to manage CSS specificity and make large stylesheets easier to control.


Utility-First CSS

Utility-first CSS uses small classes that each perform a specific styling task.

For example:

p-4
text-center
bg-blue-500
rounded-lg
flex
items-center
Enter fullscreen mode Exit fullscreen mode

A popular example of a utility-first framework is Tailwind CSS.

Instead of creating:

.card {
    padding: 20px;
    background: white;
    border-radius: 10px;
}
Enter fullscreen mode Exit fullscreen mode

you can compose styles using utilities.

The detailed comparison between utility-first styling and component-scoped styling is a separate concept.


Why Are CSS Methodologies Useful?

As projects become larger, CSS can become difficult to maintain.

Without a clear methodology:

Generic class names
        ↓
Style conflicts
        ↓
Specificity problems
        ↓
More overrides
        ↓
!important
        ↓
Hard-to-maintain CSS
Enter fullscreen mode Exit fullscreen mode

With a methodology:

Clear naming
      ↓
Predictable structure
      ↓
Easier maintenance
      ↓
Easier collaboration
      ↓
Scalable CSS
Enter fullscreen mode Exit fullscreen mode

BEM Cheat Sheet

Block

.block
Enter fullscreen mode Exit fullscreen mode

Independent component.

Example:

.card
Enter fullscreen mode Exit fullscreen mode

Element

.block__element
Enter fullscreen mode Exit fullscreen mode

Meaningful part of a Block.

Example:

.card__title
Enter fullscreen mode Exit fullscreen mode

Modifier

.block--modifier
Enter fullscreen mode Exit fullscreen mode

Variation or state of a Block.

Example:

.card--featured
Enter fullscreen mode Exit fullscreen mode

Element Modifier

.block__element--modifier
Enter fullscreen mode Exit fullscreen mode

Variation or state of an Element.

Example:

.card__title--highlighted
Enter fullscreen mode Exit fullscreen mode

The Two Symbols to Remember

__ → Element
Enter fullscreen mode Exit fullscreen mode

Read it as:

"part of this Block"

Example:

card__title
Enter fullscreen mode Exit fullscreen mode

Title belonging to the card.

And:

-- → Modifier
Enter fullscreen mode Exit fullscreen mode

Read it as:

"variation or state of this component"

Example:

card--featured
Enter fullscreen mode Exit fullscreen mode

Featured version of the card.


Final Mental Model

When creating a BEM class, ask three questions:

1. Is this an independent component?
        ↓
      BLOCK

2. Is this a meaningful part of the Block?
        ↓
     ELEMENT

3. Is this a variation or state?
        ↓
    MODIFIER
Enter fullscreen mode Exit fullscreen mode

So:

                 BEM
                  │
       ┌──────────┼──────────┐
       ↓          ↓          ↓
     BLOCK     ELEMENT    MODIFIER
       │          │          │
      card    card__title  card--featured
Enter fullscreen mode Exit fullscreen mode

And the complete pattern is:

block
block__element
block--modifier
block__element--modifier
Enter fullscreen mode Exit fullscreen mode

Final Takeaway

BEM is not a new CSS property or CSS feature.

It is a naming and organization methodology.

Its purpose is to make CSS class names predictable and understandable.

Remember:

Block
→ Independent component

Element
→ Part of a Block

Modifier
→ Variation or state
Enter fullscreen mode Exit fullscreen mode

Example:

product-card
product-card__image
product-card__title
product-card__price
product-card__button
product-card--featured
product-card__button--primary
Enter fullscreen mode Exit fullscreen mode

The most important rule is:

__ means Element, and -- means Modifier.

Once you understand Block → Element → Modifier, BEM becomes much easier to use in real projects.

Top comments (0)