CSS Architecture: Naming & Maintainability

CSS আর্কিটেকচার — নেমিং ও মেইনটেইনেবিলিটি

Read: ~24 min Intermediate 10 practice problems Live preview runner

1. Why CSS Gets Messy — And Why It Doesn't Have To

A ten-line stylesheet never causes problems. A ten-thousand-line stylesheet, built by several people over months, almost always does — unless the team agrees on a system. Class names collide, one small change in one file breaks a component on a completely different page, and nobody feels safe deleting old rules because nobody knows what still depends on them. This module is about the habits that keep CSS predictable no matter how large the project grows.

দশ লাইনের একটি CSS ফাইলে কখনোই সমস্যা হয় না। কিন্তু কয়েক মাস ধরে একাধিক মানুষ মিলে বানানো দশ হাজার লাইনের একটি stylesheet-এ প্রায় সবসময়ই সমস্যা হয় — যদি না টিম একটি নির্দিষ্ট সিস্টেম মেনে চলে। ক্লাস নেইম একে অপরের সাথে সংঘর্ষ করে, একটি ফাইলে করা ছোট পরিবর্তন সম্পূর্ণ ভিন্ন একটি পেজের কম্পোনেন্ট ভেঙে দেয়, এবং কেউ পুরনো নিয়ম মুছে ফেলার সাহস পায় না কারণ কেউ জানে না কী এখনো এর ওপর নির্ভরশীল। এই মডিউলে আমরা এমন কিছু অভ্যাস শিখবো যা প্রোজেক্ট যত বড়ই হোক না কেন CSS-কে অনুমানযোগ্য রাখে।

None of this is new syntax — everything here is the same selector { property: value; } you already know. What changes is discipline: how you name things, how specific your selectors are allowed to get, and how you organize files so the next person (often future-you) can find anything in seconds.

2. The BEM Naming Convention

BEM stands for Block, Element, Modifier. It is a naming convention — not a framework or a library — that gives every class name a predictable shape so you can tell, just by reading a class name, exactly what it does and where it belongs.

BEM মানে Block, Element, Modifier। এটি কোনো framework বা library নয় — একটি নেমিং কনভেনশন, যা প্রতিটি ক্লাস নেইমকে একটি অনুমানযোগ্য গঠন দেয়, যাতে শুধু ক্লাস নেইম পড়েই বোঝা যায় সেটি ঠিক কী করে এবং কোথায় ব্যবহৃত হয়।
PartSyntaxবাংলায়
Block.card — a standalone, reusable component.একটি স্বাধীন, পুনর্ব্যবহারযোগ্য কম্পোনেন্ট।
Element.card__title — a part that only makes sense inside its block. Double underscore.এমন একটি অংশ, যা শুধু তার block-এর ভেতরেই অর্থবহ। ডাবল আন্ডারস্কোর দিয়ে লেখা হয়।
Modifier.card--featured — a variant or state of the block/element. Double hyphen.block/element-এর একটি variant বা অবস্থা। ডাবল হাইফেন দিয়ে লেখা হয়।

The rule of thumb: a block's name never depends on where it is placed on the page. .card looks and behaves the same whether it's in the sidebar or the main content — you never write .sidebar .card to change it. Instead, if the card needs to look different in the sidebar, you give it a modifier: .card--compact.

মূল নিয়মটি হলো: একটি block-এর নেইম কখনো নির্ভর করে না সেটি পেজের কোথায় বসানো আছে তার ওপর। .card সাইডবারে থাকুক বা মূল কনটেন্টে — দেখতে ও আচরণে একই থাকে; একে বদলাতে .sidebar .card লেখা হয় না। বরং কার্ডটি সাইডবারে ভিন্নভাবে দেখাতে হলে একটি modifier দেওয়া হয়: .card--compact।

3. BEM in Action — Run It Live 🚀

Below is a small card component named with strict BEM: the block is .card, its parts are .card__title and .card__body, and one variant is switched on with .card--featured. Notice that every selector in the CSS is a single class — no nesting, no fighting over specificity.

নিচে কঠোরভাবে BEM নিয়ম মেনে বানানো একটি ছোট card কম্পোনেন্ট দেওয়া হলো: block হলো .card, এর অংশগুলো .card__title ও .card__body, আর একটি variant চালু করা হয়েছে .card--featured দিয়ে। লক্ষ করুন, CSS-এর প্রতিটি সিলেক্টর একটিমাত্র ক্লাস — কোনো নেস্টিং নেই, specificity নিয়ে কোনো লড়াই নেই।
bem-card.html
<div class="card">
  <h3 class="card__title">Standard Plan</h3>
  <p class="card__body">Good for personal projects.</p>
  <button class="card__button">Choose</button>
</div>

<div class="card card--featured">
  <h3 class="card__title">Pro Plan</h3>
  <p class="card__body">Best for freelancers & small teams.</p>
  <button class="card__button">Choose</button>
</div>
style.css
.card {
  border: 1px solid #d1d5db;
  border-radius: 10px;
  padding: 1.2rem;
  margin: 0.6rem 0;
  background: #fff;
}
.card__title {
  margin: 0 0 0.5rem;
  font-size: 1.1rem;
  color: #0f172a;
}
.card__body {
  margin: 0 0 0.8rem;
  color: #4b5563;
}
.card__button {
  border: none;
  border-radius: 6px;
  padding: 0.5rem 1rem;
  background: #39b549;
  color: white;
  font-weight: 600;
  cursor: pointer;
}
.card--featured {
  border-color: #39b549;
  border-width: 2px;
  box-shadow: 0 6px 16px rgba(57,181,73,0.15);
}
.card--featured .card__title {
  color: #1f6e2a;
}

Notice .card--featured .card__title is the one place we combine two BEM classes — that's fine, because it's still describing "this element, inside this specific modifier state," not an arbitrary page location.

লক্ষ করুন .card--featured .card__title-এই একমাত্র জায়গায় দুটি BEM ক্লাস একসাথে ব্যবহার করা হয়েছে — এটা ঠিক আছে, কারণ এটি বর্ণনা করছে "এই এলিমেন্ট, এই নির্দিষ্ট modifier অবস্থায়," কোনো এলোমেলো পেজ-লোকেশন নয়।

4. Avoiding Overly Specific Selectors

CSS specificity is a scoring system: ID selectors beat class selectors, class selectors beat element selectors, and !important beats almost everything. The trap is that once one rule uses a heavy selector to win an argument, the next developer has to write an even heavier one to override it — and the stylesheet spirals into a "specificity war" that nobody can safely edit.

CSS specificity হলো একটি স্কোরিং সিস্টেম: ID সিলেক্টর ক্লাস সিলেক্টরকে হারায়, ক্লাস সিলেক্টর এলিমেন্ট সিলেক্টরকে হারায়, আর !important প্রায় সবকিছুকে হারায়। সমস্যা হলো, একবার কোনো নিয়ম ভারী সিলেক্টর দিয়ে জিতে গেলে, পরের ডেভেলপারকে তার চেয়েও ভারী সিলেক্টর লিখে সেটি override করতে হয় — আর stylesheet একটি "specificity war"-এ পরিণত হয়, যা নিরাপদে সম্পাদনা করা যায় না।

❌ Overly Specific (অতিরিক্ত নির্দিষ্ট)

  • #sidebar div.widget ul li a
  • IDs mixed with tags mixed with classes
  • Breaks the moment HTML structure changes
  • Can only be overridden with something even heavier

✅ Flat & Class-Based (ফ্ল্যাট ও ক্লাস-ভিত্তিক)

  • .widget__link
  • One class, one clear meaning
  • Survives HTML restructuring
  • Easy to override with one more class if needed
Rule of thumb Prefer a single class per rule. Reach for element selectors like ul li a only for very generic, low-level defaults — never for a specific component you plan to reuse or theme later.

যতটা সম্ভব একটি সিলেক্টরে একটি মাত্র ক্লাস ব্যবহার করুন। ul li a-এর মতো এলিমেন্ট সিলেক্টর শুধু খুবই সাধারণ, নিম্ন-স্তরের default-এর জন্য ব্যবহার করুন — এমন কোনো নির্দিষ্ট কম্পোনেন্টের জন্য নয়, যা পরে পুনর্ব্যবহার বা থিম করার পরিকল্পনা আছে।

5. Organizing a Stylesheet

Even a single CSS file benefits from a consistent internal order. A common pattern, top to bottom: reset/base styles, CSS variables, generic layout helpers, then components (in alphabetical or feature order), then page-specific overrides last. Comment each section with a clear header so anyone can jump straight to what they need with a search.

একটি একক CSS ফাইলেও একটি ধারাবাহিক অভ্যন্তরীণ ক্রম থাকলে উপকার হয়। একটি সাধারণ প্যাটার্ন উপর থেকে নিচে: reset/base স্টাইল, CSS ভ্যারিয়েবল, জেনেরিক লেআউট হেল্পার, তারপর কম্পোনেন্ট (আলফাবেটিক বা ফিচার অনুযায়ী ক্রমে), এবং সবশেষে পেজ-নির্দিষ্ট override। প্রতিটি সেকশনে স্পষ্ট হেডার কমেন্ট রাখুন, যাতে যে কেউ সার্চ করেই সরাসরি প্রয়োজনীয় অংশে যেতে পারে।
OrderSectionবাংলায়
1Reset / base (margins, box-sizing, typography defaults)রিসেট / বেস (margin, box-sizing, ডিফল্ট টাইপোগ্রাফি)
2CSS variables (colors, spacing scale, fonts)CSS ভ্যারিয়েবল (রঙ, স্পেসিং স্কেল, ফন্ট)
3Layout helpers (containers, grids, generic utilities)লেআউট হেল্পার (কনটেইনার, গ্রিড, জেনেরিক ইউটিলিটি)
4Components (.card, .nav, .modal…)কম্পোনেন্ট (.card, .nav, .modal…)
5Page-specific overridesপেজ-নির্দিষ্ট override
6Media queries (either inline per component, or grouped last)মিডিয়া কোয়েরি (কম্পোনেন্টের সাথেই, অথবা সবশেষে একত্রে)

6. Reusable Utility Classes

A utility class does exactly one small job — .mt-2 adds top margin, .text-center centers text, .hidden sets display: none. Utilities complement BEM components: a component class defines what something is, a utility class tweaks one property without you inventing a new component modifier for every tiny spacing tweak.

একটি utility class ঠিক একটি ছোট কাজ করে — .mt-2 উপরে margin যোগ করে, .text-center টেক্সট মাঝখানে আনে, .hidden display: none সেট করে। Utility ক্লাস BEM কম্পোনেন্টের পরিপূরক: কম্পোনেন্ট ক্লাস বোঝায় কোনো কিছু কী, আর utility ক্লাস প্রতিটি ছোট spacing পরিবর্তনের জন্য নতুন modifier না বানিয়ে একটি প্রপার্টি সামান্য বদলে দেয়।
.mt-2 / .mb-2
margin-top / margin-bottom spacing steps
.text-center
text-align: center
.hidden
display: none
.flex / .grid
quick display switches
.fw-700
font-weight: 700
.w-full
width: 100%
Balance, not extremes Some teams (like Tailwind CSS users) go almost all-utility. Others go almost all-BEM. For a course project or small site, a handful of utilities alongside BEM components — not a replacement for them — keeps things both organized and fast to write.

কিছু টিম (যেমন Tailwind CSS ব্যবহারকারীরা) প্রায় পুরোপুরি utility-নির্ভর হয়ে যায়। অন্যরা প্রায় পুরোপুরি BEM-নির্ভর। একটি কোর্স প্রোজেক্ট বা ছোট সাইটের জন্য, BEM কম্পোনেন্টের পাশাপাশি হাতে গোনা কিছু utility — তার বদলে নয় — জিনিসগুলোকে গোছানো ও দ্রুত লেখার উপযোগী রাখে।

7. When to Split CSS Into Multiple Files

A single style.css is fine for a small site (this course keeps one lecture.css for exactly that reason). Once a project grows past a few hundred lines with clearly separate concerns — a design system of variables, a set of reusable components, and page-specific rules — splitting into files like base.css, components.css, and pages/home.css keeps each file small enough to reason about, even without a build tool: just link multiple <link rel="stylesheet"> tags in the order they should apply.

ছোট একটি সাইটের জন্য একটি মাত্র style.css যথেষ্ট (এই কোর্সেও ঠিক এই কারণেই একটি lecture.css ব্যবহার করা হয়েছে)। একটি প্রোজেক্ট যখন কয়েকশো লাইন ছাড়িয়ে যায় এবং স্পষ্টভাবে আলাদা অংশে ভাগ হয় — ভ্যারিয়েবলের একটি ডিজাইন সিস্টেম, পুনর্ব্যবহারযোগ্য কম্পোনেন্টের একটি সেট, এবং পেজ-নির্দিষ্ট নিয়ম — তখন base.css, components.css, pages/home.css-এর মতো ফাইলে ভাগ করলে প্রতিটি ফাইল বিল্ড টুল ছাড়াই যুক্তিসঙ্গতভাবে ছোট থাকে: শুধু একাধিক <link rel="stylesheet"> ট্যাগ সঠিক ক্রমে যোগ করলেই চলে।
SignalAction
File is under ~300 lines, one pageKeep it as one file.
Clear reusable components emerging (cards, buttons, nav)Split components into their own file/section.
Multiple pages with very different stylesOne shared base file + one file per page.
Team of multiple developers editing CSSSplit by ownership area to reduce merge conflicts.
Key insight Architecture rules exist to answer one question quickly: "if I need to change how this looks, where do I go, and what else might break?" BEM naming, low specificity, and organized files are three different tools aimed at that same single goal.

আর্কিটেকচার নিয়মগুলো একটি প্রশ্নের দ্রুত উত্তর দেওয়ার জন্যই তৈরি: "এটির চেহারা বদলাতে হলে কোথায় যাব, আর অন্য কী ভেঙে যেতে পারে?" BEM নেমিং, কম specificity, এবং গোছানো ফাইল — এই তিনটি ভিন্ন টুল একই লক্ষ্যে কাজ করে।

8. Practice Problems

Every problem has a Show Answer button. Try to solve it yourself first, then compare.

প্রতিটি প্রশ্নের সাথে Show Answer বাটন রয়েছে। প্রথমে নিজে সমাধান করার চেষ্টা করুন, তারপর মিলিয়ে নিন।
  1. Write the BEM class names for a "block" component with an "element" and a modifier that makes it stand out, following the pattern used in this lesson's card example.
    এই লেসনের card উদাহরণের প্যাটার্ন অনুসরণ করে একটি "block" কম্পোনেন্টের জন্য BEM ক্লাস নেইম লিখুন, সাথে একটি "element" এবং একটি modifier যা সেটিকে আলাদাভাবে চোখে পড়ার মতো করে তোলে।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: For an "alert" component: block .alert, element .alert__message, modifier .alert--danger. Used together: <div class="alert alert--danger"><p class="alert__message">...</p></div>

    একটি "alert" কম্পোনেন্টের জন্য: block .alert, element .alert__message, modifier .alert--danger। একসাথে ব্যবহার: <div class="alert alert--danger"><p class="alert__message">...</p></div>

  2. Rewrite the selector #main .sidebar ul li a.link as a single, flat BEM-style class selector.
    #main .sidebar ul li a.link সিলেক্টরটিকে একটি একক, ফ্ল্যাট BEM-স্টাইলের ক্লাস সিলেক্টর হিসেবে পুনরায় লিখুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: .sidebar__link — a single class on the anchor itself, applied directly in the HTML: <a class="sidebar__link">. No need to describe the entire ancestor chain.

    .sidebar__link — অ্যাংকরে সরাসরি একটি ক্লাস বসানো হয়েছে HTML-এ: <a class="sidebar__link">। পুরো ancestor চেইন বর্ণনা করার দরকার নেই।

  3. Build a runnable HTML + CSS "button" block with two modifiers: .btn--primary and .btn--outline, matching the naming style from this lesson.
    এই লেসনের নেমিং স্টাইল অনুসরণ করে একটি চালু-করার-যোগ্য HTML + CSS "button" block বানান, যাতে দুটি modifier থাকবে: .btn--primary ও .btn--outline।
    ✨ Show Answer (উত্তর দেখুন)
    ans3.html
    <button class="btn btn--primary">Save</button>
    <button class="btn btn--outline">Cancel</button>
    style.css
    .btn {
      padding: 0.6rem 1.2rem;
      border-radius: 6px;
      font-weight: 600;
      border: 1px solid transparent;
      cursor: pointer;
    }
    .btn--primary { background: #39b549; color: white; }
    .btn--outline { background: white; border-color: #39b549; color: #1f6e2a; }
  4. Explain, in your own words, why #header nav ul li a is considered "overly specific" and what problem it causes later.
    নিজের ভাষায় ব্যাখ্যা করুন, কেন #header nav ul li a-কে "অতিরিক্ত নির্দিষ্ট" ধরা হয় এবং এটি পরবর্তীতে কী সমস্যা তৈরি করে।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: It mixes an ID, three element tags, and a class into one very high-specificity selector. It only works if that exact HTML nesting never changes, and any future rule that needs to override it must be written even more specifically (or use !important), starting a specificity war.

    এটি একটি ID, তিনটি এলিমেন্ট ট্যাগ এবং একটি ক্লাসকে একসাথে মিশিয়ে খুব উচ্চ specificity-র একটি সিলেক্টর বানায়। এটি তখনই কাজ করে যখন এই ঠিক HTML nesting কখনো না বদলায়, আর ভবিষ্যতে এটিকে override করার প্রয়োজন হলে আরও নির্দিষ্ট সিলেক্টর (বা !important) লিখতে হয় — যা একটি specificity war শুরু করে।

  5. List, in the correct order, the sections of a well-organized single stylesheet, as described in this lesson.
    এই লেসনে বর্ণিত একটি সুশৃঙ্খল একক stylesheet-এর সেকশনগুলো সঠিক ক্রমে তালিকা করুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: 1) Reset/base styles, 2) CSS variables, 3) Layout helpers, 4) Components, 5) Page-specific overrides, 6) Media queries.

    ১) Reset/base স্টাইল, ২) CSS ভ্যারিয়েবল, ৩) লেআউট হেল্পার, ৪) কম্পোনেন্ট, ৫) পেজ-নির্দিষ্ট override, ৬) মিডিয়া কোয়েরি।

  6. Write two utility classes, .mt-1 and .text-center, that could be reused across an entire site.
    দুটি utility class লিখুন, .mt-1 এবং .text-center, যা পুরো সাইট জুড়ে পুনর্ব্যবহার করা যাবে।
    ✨ Show Answer (উত্তর দেখুন)
    ans6.html
    <p class="mt-1 text-center">Centered paragraph with small top margin.</p>
    style.css
    .mt-1 { margin-top: 0.5rem; }
    .text-center { text-align: center; }
  7. Explain why a component class like .card should never be named after its location on the page, such as .homepage-box.
    ব্যাখ্যা করুন কেন .card-এর মতো একটি কম্পোনেন্ট ক্লাসের নাম কখনো পেজের অবস্থান অনুযায়ী দেওয়া উচিত নয়, যেমন .homepage-box।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: Location-based names make a component impossible to reuse elsewhere without confusion — using .homepage-box on a profile page reads as wrong even if it's visually correct. Naming after what the component is (.card) keeps it portable to any page.

    অবস্থান-ভিত্তিক নাম একটি কম্পোনেন্টকে অন্য কোথাও বিভ্রান্তি ছাড়া পুনর্ব্যবহার করা অসম্ভব করে তোলে — একটি প্রোফাইল পেজে .homepage-box ব্যবহার করলে তা দৃষ্টিগতভাবে ঠিক থাকলেও পড়তে ভুল মনে হয়। কম্পোনেন্টটি কী তার ভিত্তিতে নাম দিলে (.card) সেটি যেকোনো পেজে বহনযোগ্য থাকে।

  8. Given a "modal" block with a close button element and an "open" state modifier, write all three BEM class names.
    একটি "modal" block, একটি close বাটন element, এবং একটি "open" অবস্থার modifier দেওয়া থাকলে — তিনটি BEM ক্লাস নেইম লিখুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: .modal (block), .modal__close (element), .modal--open (modifier). Combined in HTML: <div class="modal modal--open"><button class="modal__close">×</button></div>

    .modal (block), .modal__close (element), .modal--open (modifier)। HTML-এ একসাথে: <div class="modal modal--open"><button class="modal__close">×</button></div>

  9. A teammate wrote div.container > div.row > div.col > p { color: red; }. Identify what's wrong architecturally and suggest a BEM-friendly fix.
    একজন সহকর্মী div.container > div.row > div.col > p { color: red; } লিখেছে। এখানে আর্কিটেকচারগতভাবে কী ভুল, এবং BEM-বান্ধব একটি সমাধান বলুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: It targets a specific nesting path instead of a reusable class, so it breaks if the HTML structure changes and cannot be reused elsewhere. Fix: add a direct class to the paragraph, e.g. .col__warning { color: red; }, and apply it in the HTML.

    এটি পুনর্ব্যবহারযোগ্য ক্লাসের বদলে একটি নির্দিষ্ট nesting পথকে টার্গেট করে, তাই HTML গঠন বদলালে এটি ভেঙে যায় এবং অন্য কোথাও পুনর্ব্যবহার করা যায় না। সমাধান: প্যারাগ্রাফে সরাসরি একটি ক্লাস যোগ করুন, যেমন .col__warning { color: red; }, এবং HTML-এ সেটি প্রয়োগ করুন।

  10. Explain when it makes sense to split one CSS file into several files, and give one concrete signal from this lesson.
    কখন একটি CSS ফাইলকে একাধিক ফাইলে ভাগ করা যুক্তিসঙ্গত, তা ব্যাখ্যা করুন এবং এই লেসন থেকে একটি স্পষ্ট সংকেত উল্লেখ করুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: Split once a file grows past a few hundred lines with clearly separate concerns, or once multiple developers edit the same file often (causing merge conflicts). A concrete signal: reusable components emerging that deserve their own file, e.g. components.css.

    একটি ফাইল কয়েকশো লাইন ছাড়িয়ে গেলে এবং স্পষ্টভাবে আলাদা অংশে ভাগ হলে, অথবা একাধিক ডেভেলপার একই ফাইল ঘনঘন সম্পাদনা করলে (merge conflict তৈরি হয়) তখন ভাগ করা উচিত। একটি স্পষ্ট সংকেত: পুনর্ব্যবহারযোগ্য কম্পোনেন্ট তৈরি হওয়া, যেগুলোর নিজস্ব ফাইল প্রাপ্য, যেমন components.css।

Summary — Module 22

Large CSS projects survive on discipline, not luck. BEM gives every class a predictable block/element/modifier shape. Keeping selectors flat and class-based avoids specificity wars. Organizing a stylesheet in a consistent order — and splitting into multiple files once it grows — keeps everything findable. Reusable utility classes round things out for the small, one-off tweaks that don't deserve a whole new component.

বড় CSS প্রোজেক্ট টিকে থাকে শৃঙ্খলার ওপর, ভাগ্যের ওপর নয়। BEM প্রতিটি ক্লাসকে একটি অনুমানযোগ্য block/element/modifier গঠন দেয়। সিলেক্টর ফ্ল্যাট ও ক্লাস-ভিত্তিক রাখলে specificity war এড়ানো যায়। stylesheet-কে ধারাবাহিক ক্রমে সাজানো — এবং বড় হলে একাধিক ফাইলে ভাগ করা — সবকিছু সহজে খুঁজে পাওয়ার উপযোগী রাখে। পুনর্ব্যবহারযোগ্য utility ক্লাস ছোট, এককালীন পরিবর্তনের জন্য পুরোটাকে সম্পূর্ণ করে।

Next Module → Debugging with DevTools & Cross-Browser Basics — DevTools দিয়ে লাইভ CSS ডিবাগ করা ও ব্রাউজার-ভেদে পার্থক্য সামলানো শেখা।