এই পর্বে যা শিখবেন
- CSS framework কোন সমস্যার সমাধান করে, আর তার বিনিময়ে কী দাম দিতে হয়
- Bootstrap-এর grid, component, JavaScript আর রং-ফন্ট বদলানোর সঠিক উপায় — লাইভ প্রিভিউতে
- Tailwind CSS-এর utility-first ভাবনা, class থেকে CSS কীভাবে তৈরি হয়, variant, arbitrary value, v4-এর
@themeআর@apply-এর সতর্কতা - একই পণ্য-কার্ড তিনভাবে — সাধারণ CSS, Bootstrap আর Tailwind — আর daisyUI, shadcn/ui, Pico.css, Open Props-এর মতো বিকল্প
- প্রজেক্ট, দল আর বাজার দেখে বেছে নেওয়ার পদ্ধতি, আর AI-এর দেওয়া framework-কোড যাচাইয়ের চেকলিস্ট
১ · Framework কী দেয়, আর বিনিময়ে কী নেয়
রাকিব একজন নতুন ফ্রিল্যান্সার। একটি ক্লায়েন্ট বলল, “আমার কাপড়ের দোকানের জন্য এক সপ্তাহে একটি ওয়েবসাইট চাই — মোবাইলে সুন্দর দেখাতে হবে, মেনু থাকবে, পণ্যের কার্ড থাকবে, অর্ডারের আগে একটি নিশ্চিত করার জানালা খুলবে।” রাকিব জানে এসব শূন্য থেকে CSS লিখে বানানো যায় — পর্ব ২৫-এ Flexbox, পর্ব ২৭-এ Grid, পর্ব ৩০-এ রেসপন্সিভ নকশা শিখেছে। কিন্তু সময় মাত্র এক সপ্তাহ। তখন কেউ বলল, “Bootstrap নাও, এক দিনেই হয়ে যাবে।” আরেকজন বলল, “এখন সবাই Tailwind ব্যবহার করে।” কোনটি ঠিক?
প্রশ্নের উত্তরের আগে বুঝতে হবে CSS framework আসলে কী। সহজ কথায়: অন্য কেউ আগে থেকে লিখে রাখা, পরীক্ষা করা একগাদা CSS (কখনো সাথে কিছু JavaScript), যা আপনি নিজের পাতায় যোগ করে HTML-এ তাদের ঠিক করা class নাম বসিয়ে ব্যবহার করেন। Framework কোনো নতুন ভাষা নয় — ব্রাউজার শেষ পর্যন্ত সাধারণ CSS-ই পায়।
দর্জির দোকান আর রেডিমেড পোশাকের কথা ভাবুন। দর্জি আপনার মাপ নিয়ে একদম আপনার মতো পাঞ্জাবি বানান — নিখুঁত, কিন্তু সময় আর দক্ষতা লাগে। রেডিমেড দোকানে S, M, L, XL মাপ ঝোলানো থাকে — পাঁচ মিনিটে কেনা যায়, কিন্তু আপনার মতো আরও শত মানুষ একই পাঞ্জাবি পরে ঘোরেন, আর হাতা ছোট করতে গেলে সেলাই খুলতে হয়। সাধারণ CSS হলো দর্জি, Bootstrap রেডিমেড দোকান। আর Tailwind? সেটি কাপড়, বোতাম আর মাপের ফিতার একটি সুসংগঠিত সেট — নিজেই বানাবেন, তবে মাপ আর রং আগে থেকেই ঠিক করা।
যেকোনো framework মোটামুটি চারটি জিনিস দেয়, আর চারটি দাম চায়:
যা দেয়
Grid: সারি-কলামের তৈরি ব্যবস্থা, ফোনে এক কলাম, বড় পর্দায় তিন কলাম। Component: বোতাম, কার্ড, মেনু, modal — একটি class-এ। Utility: mt-3, text-center-এর মতো ছোট class. সামঞ্জস্য: পুরো দল একই মাপ, একই রং, একই ফাঁক ব্যবহার করে।
যা নেয়
আকার: অব্যবহৃত CSS-ও ডাউনলোড হতে পারে। একঘেয়েমি: নকশা না বদলালে সাইট “চেনা চেনা” লাগে। ভুল জিনিস শেখা: CSS-এর বদলে framework-এর class মুখস্থ। বদলানোর যন্ত্রণা: framework-এর নিয়ম হারাতে specificity-র লড়াই।
দীর্ঘমেয়াদে খরচ বাড়তে পারে“আকার” কথাটি মেপে দেখা যাক। Bootstrap 5.3.8-এর পুরো minify করা CSS ফাইল প্রায় ২৩২ KB; সার্ভার gzip দিয়ে চেপে পাঠালে প্রায় ৩১ KB. সাথে modal, dropdown-এর JavaScript (Popper-সহ bundle) আরও প্রায় ৮০ KB, চাপলে প্রায় ২৪ KB. আপনি হয়তো ব্যবহার করবেন এর দশ ভাগের এক ভাগ — বাকিটাও ফোনে নামবে, পার্স হবে, আর CSS ফাইলটি পর্ব ৪৯-এর ভাষায় render-blocking বলে পাতার প্রথম দৃশ্য দেখাতে দেরি করাবে। অন্যদিকে Tailwind শুধু ব্যবহৃত class-এর CSS বানায়, তাই ফল সাধারণত অনেক ছোট — সেটি কীভাবে, অংশ ৬-এ দেখবেন।
Framework-এর ধারণা নতুন নয়। ২০০০-এর দশকের শেষ ভাগে ওয়েব ডিজাইনাররা ৯৬০ পিক্সেল চওড়া পাতাকে ১২ বা ১৬ কলামে ভাগ করার “grid system” ব্যবহার করতেন — Blueprint আর 960 Grid System ছিল জনপ্রিয়। তখন লেআউট হতো float দিয়ে, কারণ Flexbox বা Grid ছিল না; framework-এর বড় কাজ ছিল সেই কৌশল লুকিয়ে রাখা আর ব্রাউজারভেদে পার্থক্য সামলানো। আজ Flexbox আর Grid ব্রাউজারেই আছে — তাই প্রশ্নটি বদলে গেছে: “framework ছাড়া লেআউট করা যায় কি?” থেকে “framework আমাকে আর কী বাড়তি দিচ্ছে?”
২ · Bootstrap — ইতিহাস আর ১২ কলামের grid
Bootstrap-এর জন্ম Twitter-এর ভেতরে। কোম্পানির নানা অভ্যন্তরীণ টুল নানা রকম দেখাত, তাই ডিজাইনার Mark Otto আর ডেভেলপার Jacob Thornton একটি সাধারণ নকশার সেট তৈরি করেন। ২০১১ সালের আগস্টে সেটি open source হিসেবে প্রকাশ পায়, আর অল্প দিনেই GitHub-এর সবচেয়ে জনপ্রিয় প্রজেক্টগুলোর একটি হয়ে ওঠে। প্রধান সংস্করণগুলো এক নজরে:
| সংস্করণ | সাল | বড় পরিবর্তন |
|---|---|---|
| 1 | ২০১১ | Twitter থেকে প্রকাশ; স্থির চওড়ার grid, Less-এ লেখা |
| 2 | ২০১২ | রেসপন্সিভ grid — স্মার্টফোনের উত্থানের ঠিক সময়ে |
| 3 | ২০১৩ | মোবাইল-ফার্স্ট, সমতল (flat) নকশা |
| 4 | ২০১৮ | Flexbox-ভিত্তিক grid, Less ছেড়ে Sass, card component |
| 5 | ২০২১ | jQuery বাদ, Internet Explorer বাদ, RTL সমর্থন, utility API |
| 5.3 | ২০২৩ | রঙের মোড (data-bs-theme="dark"), আরও বেশি CSS variable |
Bootstrap-এর হৃদয় তার grid system. তিনটি class মনে রাখলেই চলে: .container (পাতার মাঝখানে একটি সীমিত চওড়ার বাক্স), .row (একটি সারি) আর .col-* (সারির ভেতরের কলাম)। প্রতিটি সারি ১২ ভাগে ভাগ করা — .col-6 মানে ১২-র ৬ ভাগ, অর্থাৎ অর্ধেক। আর মাঝখানে breakpoint-এর নাম বসালে শর্ত যোগ হয়: .col-sm-6 মানে “sm মাপ (576px) বা তার বেশি চওড়া পর্দায় অর্ধেক; তার চেয়ে ছোট পর্দায় পুরো চওড়া।” এটি পর্ব ৩০-এর মোবাইল-ফার্স্ট ভাবনাই — ছোট পর্দার নিয়ম আগে, বড় পর্দার নিয়ম যোগ হয় পরে।
| নাম | যে চওড়া থেকে | .container-এর সর্বোচ্চ চওড়া |
|---|---|---|
| (কিছু না) — xs | ০ | পুরো চওড়া |
sm | 576px | 540px |
md | 768px | 720px |
lg | 992px | 960px |
xl | 1200px | 1140px |
xxl | 1400px | 1320px |
একই HTML বিভিন্ন চওড়ায় কীভাবে সাজে, আর ভেতরে আসলে কোন CSS কাজ করছে, ধাপে ধাপে দেখুন। ধরুন তিনটি পণ্য-কার্ডের প্রতিটিতে class="col-12 col-sm-6 col-lg-4":
<div class="container"> <div class="row g-3"> <div class="col-12 col-sm-6 col-lg-4">কার্ড ১</div> <div class="col-12 col-sm-6 col-lg-4">কার্ড ২</div> <div class="col-12 col-sm-6 col-lg-4">কার্ড ৩</div> </div> </div>
┌───────────────────────────┐ │ কার্ড ১ (১২/১২) │ ├───────────────────────────┤ │ কার্ড ২ (১২/১২) │ ├───────────────────────────┤ │ কার্ড ৩ (১২/১২) │ └───────────────────────────┘
┌─────────────┬─────────────┐ │ কার্ড ১ (৬) │ কার্ড ২ (৬) │ ├─────────────┼─────────────┘ │ কার্ড ৩ (৬) │ ← জায়গা না পেয়ে নিচে └─────────────┘
┌────────┬────────┬────────┐ │ কার্ড ১ │ কার্ড ২ │ কার্ড ৩ │ │ (৪) │ (৪) │ (৪) │ └────────┴────────┴────────┘
.row { --bs-gutter-x: 1.5rem; display: flex; flex-wrap: wrap;
margin-right: calc(-.5 * var(--bs-gutter-x)); … }
.row > * { flex-shrink: 0; width: 100%;
padding-right: calc(var(--bs-gutter-x) * .5); … }
@media (min-width: 576px) {
.col-sm-6 { flex: 0 0 auto; width: 50%; }
}
@media (min-width: 992px) {
.col-lg-4 { flex: 0 0 auto; width: 33.33333333%; }
}
- তিন স্তরের কাঠামো।
.containerপাতার মাঝখানে একটি সীমিত চওড়ার বাক্স দেয়,.rowএকটি সারি, আর প্রতিটি কলামে তিনটি class — প্রতিটি আলাদা মাপের পর্দার জন্য একটি নির্দেশ।g-3কলামগুলোর মাঝের ফাঁক (gutter) ঠিক করে। - ফোনে — সবচেয়ে ছোট নিয়ম। 375px চওড়া 576px-এর কম, তাই
col-sm-6বাcol-lg-4কোনোটিই খাটে না; শুধু শর্তহীনcol-12— তিনটি কার্ডই পুরো চওড়ায় একটির নিচে আরেকটি। মোবাইল-ফার্স্ট মানে ঠিক এটাই। - 576px পার হতেই। এখন
col-sm-6খাটে, প্রতিটি কার্ড ১২-র ৬ ভাগ। দুটি এক সারিতে ধরে; তৃতীয়টির জায়গা নেই, তাইflex-wrap: wrapতাকে পরের লাইনে পাঠায়। একটি.row-এ ১২-র বেশি ভাগ হলে এভাবেই নতুন লাইন হয়। - 992px পার হতেই।
col-lg-4খাটে — ৪ + ৪ + ৪ = ১২, তিনটিই এক সারিতে। খেয়াল করুন,col-sm-6নিয়মটি এখনো আছে, কিন্তুcol-lg-4CSS ফাইলে পরে লেখা, তাই একই specificity-তে পরেরটি জেতে (পর্ব ১৮)। - পর্দার পেছনে। কোনো জাদু নেই —
.rowএকটি flex container, প্রতিটি কলাম একটি flex item যারwidthশতাংশে, আর breakpoint মানে min-width media query. Gutter আসে কলামের padding থেকে, আর সারির negative margin সেই padding-কে দুই কিনারায় পূরণ করে। পর্ব ২৫ আর ৩১ জানা থাকলে এই পুরো grid আপনি নিজেই লিখতে পারতেন।
এই পর্বের কয়েকটি প্রিভিউ ইন্টারনেট থেকে framework নামায়। নিচের এডিটরগুলো jsDelivr CDN থেকে Bootstrap বা Tailwind আনে (আমরা Microsoft Edge-এ পরীক্ষা করে দেখেছি — ঠিকঠাক লোড হয়)। ইন্টারনেট না থাকলে, বা আপনার নেটওয়ার্ক CDN আটকে দিলে, প্রিভিউতে শুধু সাজহীন HTML দেখবেন — কোডে ভুল নেই, framework-টি আসেনি। যেগুলো সাধারণ CSS দিয়ে লেখা, সেগুলো ইন্টারনেট ছাড়াই চলে।
এবার আসল Bootstrap দিয়ে দুটি পণ্য-কার্ড। CDN (content delivery network — সারা পৃথিবীতে ছড়ানো সার্ভার, যা কাছের জায়গা থেকে ফাইল দেয়) থেকে একটি <link>-ই যথেষ্ট:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
<div class="container py-3">
<div class="row g-3">
<div class="col-12 col-sm-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h3 class="card-title h5">নকশী কাঁথা</h3>
<p class="card-text text-body-secondary">হাতে সেলাই, যশোরের কারিগর</p>
<p class="fs-5 fw-bold text-success">৳১,২৫০</p>
<button class="btn btn-success">কার্টে নিন</button>
</div>
</div>
</div>
<div class="col-12 col-sm-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h3 class="card-title h5">জামদানি শাড়ি</h3>
<p class="card-text text-body-secondary">নারায়ণগঞ্জের তাঁত</p>
<p class="fs-5 fw-bold text-success">৳৮,৫০০</p>
<button class="btn btn-success">কার্টে নিন</button>
</div>
</div>
</div>
</div>
</div>প্রিভিউতে দুটি সাদা কার্ড পাশাপাশি দেখবেন — হালকা ছায়া, গোল কোণ, সবুজ দাম আর সবুজ বোতাম; একটিও CSS লাইন আপনি লেখেননি। প্রিভিউ সাধারণত 576px-এর চেয়ে চওড়া, তাই col-sm-6 খাটছে। চেষ্টা করুন: (১) দুই জায়গায় col-sm-6-কে col-lg-6 করুন — প্রিভিউ 992px-এর কম চওড়া হলে কার্ড দুটি একটির নিচে আরেকটি চলে যাবে। (২) <div class="container py-3">-এ data-bs-theme="dark" attribute যোগ করুন — v5.3-এর রঙের মোডে কার্ডগুলো গাঢ় হয়ে যাবে।
৩ · Bootstrap-এর component, JavaScript আর utility
Bootstrap-এর আসল শক্তি grid নয় — grid এখন CSS নিজেই দেয়। শক্তি হলো তৈরি component-এর বিশাল ভাণ্ডার: navbar (মেনু, ছোট পর্দায় ভাঁজ হয়ে “হ্যামবার্গার” বোতাম), card, alert, badge, form-এর সাজ, pagination, modal (পাতার ওপর ভেসে ওঠা জানালা), dropdown, tooltip, offcanvas (পাশ থেকে বেরিয়ে আসা প্যানেল), carousel, toast. এর মধ্যে যেগুলো ক্লিকে খোলে-বন্ধ হয়, তাদের জন্য Bootstrap একটি JavaScript ফাইলও দেয়। আপনাকে JavaScript লিখতে হয় না — HTML-এ data-bs-toggle আর data-bs-target attribute বসালেই হয়।
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
<style> body { min-height: 400px; } </style>
<button type="button" class="btn btn-primary m-3"
data-bs-toggle="modal" data-bs-target="#order">অর্ডার নিশ্চিত করুন</button>
<div class="modal fade" id="order" tabindex="-1" aria-labelledby="order-title" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="order-title">অর্ডারটি পাঠাবেন?</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="বন্ধ করুন"></button>
</div>
<div class="modal-body">নকশী কাঁথা × ১ — মোট ৳১,২৫০ (ক্যাশ অন ডেলিভারি)</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">না, ফিরে যাই</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">হ্যাঁ, পাঠান</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>নীল বোতামে ক্লিক করুন — পেছনটা কালচে হয়ে একটি জানালা আস্তে নেমে আসবে। Esc চাপলে, ✕-এ বা পেছনের কালো অংশে ক্লিক করলে বন্ধ হয়; খোলা থাকা অবস্থায় Tab চাপলে focus জানালার ভেতরেই ঘোরে। এই আচরণগুলো Bootstrap-এর JavaScript দিচ্ছে। চেষ্টা করুন: (১) শেষ লাইনের <script> মুছে দিন — বোতাম আর কিছুই খুলবে না, কারণ CSS শুধু চেহারা দেয়, আচরণ নয়। (২) modal-dialog-এর পাশে modal-dialog-centered যোগ করুন — জানালা উল্লম্বভাবে মাঝখানে আসবে।
Bootstrap 4 পর্যন্ত এই JavaScript চলত jQuery নামের একটি পুরোনো library-র ওপর, যা পাতায় চাপা অবস্থায়ও আরও প্রায় ৩০ KB যোগ করত। v5 jQuery ছাড়াই সাধারণ JavaScript-এ লেখা — এটিই v5-এর সবচেয়ে বড় পরিবর্তন। আর আজকের HTML-এ নিজস্ব <dialog>, <details> আর popover আছে (পর্ব ১১), যা JavaScript ছাড়াই এর অনেক কাজ করে। নতুন প্রজেক্টে আগে দেখুন HTML নিজে পারে কি না।
Component-এর পাশাপাশি Bootstrap-এ শত শত ছোট utility class আছে, যেগুলো একটি করে CSS ঘোষণা: mt-3 (ওপরে margin), p-2 (padding), d-flex (display: flex), justify-content-between, text-center, fw-bold, d-none d-md-block (ছোট পর্দায় লুকানো, md থেকে দেখানো)। ফাঁকের মাপ ০ থেকে ৫ — 1 মানে 0.25rem, 3 মানে 1rem, 5 মানে 3rem. v5-এ বাম-ডানের বদলে start-end নাম এসেছে — ms-3 (margin-start), me-3 (margin-end) — যাতে আরবি-উর্দুর মতো ডান-থেকে-বাম ভাষায়ও (RTL) একই class ঠিক কাজ করে; পর্ব ৩৫-এর logical property-র ভাবনাই।
৪ · Bootstrap নিজের মতো করা — Sass, CSS variable আর override-এর যন্ত্রণা
ক্লায়েন্ট বলল, “বোতাম Bootstrap-এর নীল নয়, আমাদের ব্র্যান্ডের সবুজ চাই।” এখানেই অনেক নতুন ডেভেলপার প্রথম ধাক্কা খান। সহজ মনে হয় — নিজের CSS-এ .btn-primary-এর রং বদলে দিলেই তো হয়! নিচের দুটি বোতাম দেখুন — দুটিই সবুজ করার চেষ্টা, দুই ভাবে:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
<style>
/* উপায় ১: সরাসরি রং বসানো */
.btn-a { background: #006a4e; border-color: #006a4e; }
/* উপায় ২: Bootstrap-এর নিজের CSS variable বদলানো */
.btn-b {
--bs-btn-bg: #006a4e; --bs-btn-border-color: #006a4e;
--bs-btn-hover-bg: #00513b; --bs-btn-hover-border-color: #00513b;
--bs-btn-active-bg: #003d2c; --bs-btn-active-border-color: #003d2c;
}
</style>
<div class="d-flex flex-wrap gap-2 p-3">
<button class="btn btn-primary btn-a">উপায় ১ — মাউস রাখুন</button>
<button class="btn btn-primary btn-b">উপায় ২ — মাউস রাখুন</button>
</div>দুটি বোতামই সবুজ দেখায় — কিন্তু প্রথমটির ওপর মাউস রাখুন: হঠাৎ Bootstrap-এর নীল ফিরে আসে! কারণ Bootstrap-এর .btn:hover নিয়মের specificity (০,২,০), আপনার .btn-a-র (০,১,০) — hover-এ ওদেরটাই জেতে। দ্বিতীয় বোতাম hover-এ গাঢ় সবুজ হয়, কারণ Bootstrap-এর নিজের নিয়মই আপনার দেওয়া variable পড়ছে। চেষ্টা করুন: (১) দুটি বোতামে Tab দিয়ে focus আনুন — focus-এর আভা এখনো নীল; .btn-b-তে --bs-btn-focus-shadow-rgb: 0, 106, 78; যোগ করে ঠিক করুন। (২) উপায় ১ “জোর করে” ঠিক করতে !important লিখতে ইচ্ছা করবে — লিখবেন না; সেটিই specificity-যুদ্ধের শুরু।
Bootstrap নিজের মতো করার তিনটি স্তর আছে — ভালো থেকে কম ভালো ক্রমে:
সবচেয়ে পরিষ্কার উপায়। Bootstrap-এর উৎস Sass-এ লেখা (পর্ব ৫০)। নিজের Sass ফাইলে Bootstrap আনার আগে variable বদলালে পুরো framework নতুন রঙে তৈরি হয় — বোতাম, লিংক, focus, hover, সব একসাথে। সাথে যে component লাগবে না সেগুলো বাদ দিয়ে ফাইল ছোটও করা যায়। এর জন্য npm আর একটি build ধাপ লাগে।
// custom.scss — Bootstrap আনার আগে নিজের মান
$primary: #006a4e;
$border-radius: .75rem;
$font-family-base: "Noto Sans Bengali", system-ui, sans-serif;
@import "bootstrap/scss/bootstrap";নতুন Dart Sass @import-এর জন্য deprecation সতর্কবার্তা দেয়; Bootstrap 5.3 এখনো এই পথেই কাস্টমাইজ শেখায়, তাই সতর্কবার্তাটি আপাতত স্বাভাবিক।
build ধাপ ছাড়া, CDN থেকে আনা Bootstrap-এও কাজ করে। v5.2 থেকে বেশিরভাগ component নিজের --bs-* variable পড়ে (উপরের উপায় ২), আর পাতাজুড়ে কিছু সাধারণ variable আছে, যেমন --bs-body-font-family, --bs-border-radius. সীমা একটাই: Sass-এ হিসাব করা কিছু মান (যেমন $primary থেকে বানানো হালকা-গাঢ় রং) variable বদলালে নিজে থেকে বদলায় না — প্রতিটি আলাদা করে দিতে হয়।
নিজের CSS দিয়ে Bootstrap-এর নিয়ম ঢেকে দেওয়া (উপায় ১) — সবচেয়ে প্রচলিত, সবচেয়ে ঝামেলার। প্রতিটি অবস্থা (hover, focus, active, disabled) আলাদা করে খুঁজে বের করতে হয়, আর specificity মেলাতে selector লম্বা হতে থাকে। তবু করতে হলে একটি আধুনিক কৌশল আছে — পরের “আরও গভীরে” বাক্সে।
আরও গভীরে: পর্ব ৩৫-এর cascade layer override-এর যুদ্ধ প্রায় মিটিয়ে দেয়। Bootstrap নিজে কোনো @layer ব্যবহার করে না, কিন্তু আপনি তাকে একটি layer-এ ঢুকিয়ে আনতে পারেন: @import url("bootstrap.min.css") layer(bootstrap);. তখন layer-এর বাইরে লেখা আপনার যেকোনো সাধারণ CSS, specificity যত কমই হোক, Bootstrap-এর সব নিয়মকে হারায় — কারণ cascade আগে layer-এর ক্রম দেখে, specificity দেখে তার পরে। @layer আর @import … layer() দুটিই Baseline Widely available. Tailwind v4 ঠিক এই কারণেই নিজের সব CSS আসল layer-এ সাজায়, যা অংশ ৬-এ দেখবেন।
৫ · Tailwind CSS — utility-first ভাবনা
Tailwind CSS সম্পূর্ণ উল্টো পথে হাঁটে। এতে কোনো .card বা .btn নেই। আছে হাজারো ছোট class, প্রতিটি সাধারণত একটি CSS ঘোষণা — p-4, flex, rounded-lg, text-white — আর আপনি HTML-এ সেগুলো জোড়া দিয়ে নিজের component বানান। এই ধারণার নাম utility-first. Bootstrap-এও utility আছে, কিন্তু সেখানে সেগুলো component-এর সহকারী; Tailwind-এ utility-ই প্রধান হাতিয়ার।
Tailwind তৈরি করেন Adam Wathan, প্রথম প্রকাশ ২০১৭ সালে। একই বছর তাঁর একটি প্রবন্ধ — “CSS Utility Classes and ‘Separation of Concerns’” — ওয়েব জগতে বড় বিতর্ক তোলে। তাঁর যুক্তি: “HTML-এ অর্থ, CSS-এ চেহারা” নিয়ম মানতে গিয়ে আমরা .author-bio__image-wrapper-এর মতো নাম বানাই, যা আসলে HTML-এর কাঠামোরই প্রতিচ্ছবি — ফলে HTML বদলালে CSS-ও বদলাতে হয়, আলাদা থাকল কোথায়? ছোট utility class আগেও ছিল (Yahoo-র Atomic CSS, Tachyons), কিন্তু Tailwind এটিকে একটি পূর্ণ, ভালো ডিজাইন-স্কেলের ব্যবস্থায় পরিণত করে। v2.1-এ “JIT” engine আসে, v3-এ সেটিই ডিফল্ট, আর ২০২৫ সালের শুরুতে আসে নতুন করে লেখা v4.
একটি Tailwind class আসলে কী, সবচেয়ে ভালো বোঝা যায় নিজে কয়েকটি বানিয়ে। নিচের এডিটরে কোনো framework নেই — শুধু সাধারণ CSS-এ Tailwind-এর মতো নাম ও মাপের কয়েকটি utility (ইন্টারনেট ছাড়াই চলে):
:root { --spacing: 0.25rem; } /* Tailwind v4-এর মাপের একক */
body { font-family: system-ui, sans-serif; background: #f4f4f5; padding: 1rem; }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.p-5 { padding: calc(var(--spacing) * 5); } /* 1.25rem */
.px-4 { padding-inline: calc(var(--spacing) * 4); } /* 1rem */
.py-2 { padding-block: calc(var(--spacing) * 2); }
.mt-1 { margin-top: calc(var(--spacing) * 1); }
.mt-4 { margin-top: calc(var(--spacing) * 4); }
.m-0 { margin: 0; } .mb-0 { margin-bottom: 0; }
.max-w-72 { max-width: calc(var(--spacing) * 72); } /* 18rem */
.rounded-lg { border-radius: 0.5rem; } .rounded-xl { border-radius: 0.75rem; }
.shadow { box-shadow: 0 1px 3px rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1); }
.bg-white { background: #fff; } .bg-green { background: #006a4e; border: 0; }
.text-white { color: #fff; } .text-green { color: #006a4e; } .text-gray { color: #52525b; }
.text-lg { font-size: 1.125rem; } .font-bold { font-weight: 700; }একটি সাদা কার্ড দেখবেন — নাম, বিবরণ, নিচে বাঁয়ে সবুজ দাম আর ডানে সবুজ বোতাম। প্রতিটি class ঠিক এক কাজের, আর সব মাপ একটি --spacing থেকে আসছে। চেষ্টা করুন: (১) প্রথম লাইনে --spacing-কে 0.3rem করুন — পুরো কার্ডের সব ফাঁক একসাথে একটু বড় হবে; একটি design token বদলালে পুরো নকশা বদলায়। (২) .justify-between-এর মান flex-start করুন — দাম আর বোতাম গায়ে গায়ে বাঁয়ে চলে আসবে।
আসল Tailwind এই কাজটিই করে, শুধু অনেক বড় পরিসরে আর একটি নিয়মিত ব্যাকরণে। একটি class-এর নামে তিনটি অংশ থাকতে পারে: শর্ত (variant, যেমন md:, hover:), property (যেমন p = padding, bg = background) আর মান (যেমন 4, emerald-700). নিচের class-গুচ্ছটি ধাপে ধাপে ভেঙে দেখুন — প্রতিটি টুকরো কোন CSS হয়:
- এক শব্দ, এক ঘোষণা।
flexমানে শুধুdisplay: flex. পর্ব ২৫-এ যা শিখেছেন, Tailwind তার একটি ছোট নাম দিয়েছে মাত্র — Flexbox না জানলে এই নাম কোনো কাজে আসবে না। - নাম CSS থেকেই আসে।
items-centerহলোalign-items: center;justify-betweenহলোjustify-content: space-between. বেশিরভাগ নাম CSS property-র সংক্ষেপ, তাই CSS জানলে অনুমান করা যায়। - স্কেলের সংখ্যা।
gap-4-এর ৪ কোনো পিক্সেল নয় — এটি স্কেলের ধাপ। v4-এ প্রতিটি ধাপ--spacing(ডিফল্ট 0.25rem)-এর গুণিতক, তাই ৪ মানে 1rem. সবাই একই স্কেল থেকে মাপ নেয় বলে নকশায় এলোমেলো 13px, 17px আসে না। - Padding-এর ধাপ।
p-6চারদিকে 1.5rem.px-(দুই পাশ),py-(ওপর-নিচ),pt-(শুধু ওপরে) — একই নিয়মে margin-এর জন্যm-. - রেসপন্সিভ prefix.
md:একটি variant — “শুধু 48rem (768px) বা তার বেশি চওড়ায়।” Bootstrap-এর মতো এখানেও মোবাইল-ফার্স্ট: prefix ছাড়াp-6সব পর্দায়,md:p-10বড় পর্দায় তাকে বদলায়। ধাপগুলোsm40rem,md48rem,lg64rem,xl80rem,2xl96rem. আসল CSS-এ selector হয়.md\:p-10— class নামের:চিহ্নটিকে\দিয়ে escape করতে হয়। - অবস্থার prefix.
hover:,focus-visible:,active:,disabled:— পর্ব ৩৪-এর pseudo-class. v4-এhover:আরও একটি শর্ত যোগ করে:@media (hover: hover), অর্থাৎ মাউসওয়ালা যন্ত্রেই শুধু, যাতে ফোনে চাপার পর রং “আটকে” না থাকে। prefix জোড়াও যায়:md:hover:…. - Dark mode prefix.
dark:ডিফল্টভাবে পর্ব ৩৬-এরprefers-color-scheme: dark. নিজের থিম-বোতাম দিয়ে চালাতে চাইলে v4-এ@custom-variantলিখেdark:-কে একটি class বাdata-themeattribute-এর সাথে বাঁধা যায়। - Arbitrary value. বর্গাকার বন্ধনীতে যেকোনো মান:
w-[37rem],bg-[#1877f2],grid-cols-[1fr_2fr](ফাঁকা জায়গার বদলে_)। এটি জরুরি পালানোর দরজা — কিন্তু HTML ভরে গেলে বুঝবেন আপনি স্কেল ছেড়ে দিয়ে ঘুরিয়ে inline style লিখছেন।
৬ · Tailwind-এর ভেতরে — build, @theme, layer আর @apply
প্রশ্ন জাগে: হাজারো class-এর CSS তো বিশাল হওয়ার কথা। Tailwind ছোট থাকে কীভাবে? উত্তর: Tailwind আগে থেকে কোনো বড় CSS ফাইল দেয় না। একটি build টুল আপনার প্রজেক্টের ফাইলগুলো পড়ে, class-এর মতো দেখতে শব্দগুলো খুঁজে বের করে, আর শুধু সেগুলোর CSS তৈরি করে। এই পদ্ধতিকে বলা হয় JIT (just-in-time — দরকারের মুহূর্তে বানানো)।
- আপনার ফাইল
.html .jsx .phpclass লেখা আছে - Scanner
candidatesclass-এর মতো শব্দ - Engine
@themeমান মিলিয়ে CSS - Layer
@layerতাকে সাজানো - output.css
কয়েক KBব্রাউজারে যায়
<button class="rounded-lg bg-brand px-4 py-2 text-white hover:bg-brand-dark">
কার্টে নিন
</button>
rounded-lg bg-brand px-4 py-2 text-white hover:bg-brand-dark
button class কার্টে নিন ← এগুলোও “প্রার্থী”, কিন্তু কোনো utility নয় — বাদ
@import "tailwindcss"; @theme { --color-brand: #006a4e; /* → bg-brand, text-brand, border-brand … */ --color-brand-dark: #00513b; --font-bangla: "Noto Sans Bengali", sans-serif; /* → font-bangla */ }
@layer theme, base, components, utilities; @layer theme { :root { --color-brand: #006a4e; --spacing: .25rem; … } } @layer base { /* Preflight: margin শূন্য, বোতামের সাজ মোছা … */ } @layer utilities { .bg-brand { background-color: var(--color-brand); } … }
.rounded-lg { border-radius: var(--radius-lg); }
.bg-brand { background-color: var(--color-brand); }
.px-4 { padding-inline: calc(var(--spacing) * 4); }
… ছয়টি class-এর নিয়ম, হাজার হাজার নয় …
bg-red-500 লেখেননি? তার CSS-ও নেই।
- আপনি class লেখেন। HTML, React-এর JSX, Laravel-এর Blade, PHP — যে ফাইলেই হোক। Tailwind v4 প্রজেক্টের ফাইলগুলো নিজে খুঁজে নেয় (
.gitignore-এ থাকা ফাইল বাদ দিয়ে); বাড়তি কোনো জায়গা পড়াতে হলে CSS-এ@sourceলিখতে হয়। - Scanner শব্দ খোঁজে। এটি HTML বা JavaScript বোঝে না — শুধু এমন টুকরো খোঁজে যা class নাম হতে পারে। তাই একটি বড় সতর্কতা:
"bg-" + color + "-500"-এর মতো জোড়া দেওয়া নাম scanner কখনো দেখে না, তার CSS-ও তৈরি হয় না। পুরো নাম সবসময় পুরোটা লিখুন, যেমন শর্ত দেখেbg-red-500বাbg-green-500. - Engine মান মেলায়। v4-এ নকশার মান (রং, ফন্ট, ফাঁক, breakpoint) লেখা হয় CSS-এর ভেতরে
@themeব্লকে — v3-এরtailwind.config.jsফাইলের বদলে।--color-brandলিখলেইbg-brand,text-brand-এর মতো সব class পাওয়া যায়, আর মানটি একটি সাধারণ CSS variable হিসেবেও থাকে, যা নিজের CSS-এvar(--color-brand)দিয়ে পড়া যায়। - Layer-এ সাজানো। v4 তৈরি CSS-কে ব্রাউজারের আসল
@layer-এ রাখে — theme, base (Preflight নামের reset), components, utilities. utilities সবার শেষে, তাই একই উপাদানে component-এর চেয়ে utility জেতে, selector যেমনই হোক। আর layer-এর বাইরে লেখা আপনার নিজের CSS এদের সবাইকে হারায়। - ছোট ফাইল। শুধু ব্যবহৃত class-এর নিয়ম থাকে, তাই সাধারণ সাইটে চাপার পর CSS প্রায়ই কয়েক KB-তে থাকে — যত বড় সাইটই হোক, utility-র সংখ্যা সীমিত, তাই ফাইল এক জায়গায় থেমে যায়। পুরোনো দিনে এই অব্যবহৃত CSS ছাঁটাইকে “purge” বলা হতো (v2-এর
purgeসেটিং); এখন এটি আলাদা ধাপ নয়, শুরু থেকেই এভাবে বানানো।
শেখার আর ছোট পরীক্ষার জন্য Tailwind একটি “ব্রাউজার সংস্করণ” দেয় — একটি <script>, যা পাতার ভেতরে বসেই class পড়ে CSS বানায়। নিচের এডিটরে সেটিই আছে, সাথে @theme দিয়ে নিজের ব্র্যান্ড রং:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
<style type="text/tailwindcss">
@theme {
--color-brand: #006a4e;
--color-brand-dark: #00513b;
}
</style>
<div class="space-y-3 p-4">
<button class="rounded-lg bg-brand px-4 py-2 text-white hover:bg-brand-dark
focus-visible:outline-3 focus-visible:outline-offset-2
focus-visible:outline-amber-500 sm:px-8">কার্টে নিন</button>
<p class="w-[22rem] max-w-full rounded-md border border-brand/30 p-3 text-sm">
এই বাক্সের চওড়া w-[22rem] — স্কেলের বাইরের এককালীন মান।
</p>
<div class="grid grid-cols-[1fr_2fr] gap-2 text-center text-white">
<div class="bg-brand p-2">1fr</div>
<div class="bg-brand-dark p-2">2fr</div>
</div>
</div>একটি সবুজ বোতাম (মাউস রাখলে গাঢ় হয়, Tab-এ focus দিলে কমলা দাগ), হালকা সবুজ সীমানার একটি বাক্স, আর নিচে ১:২ অনুপাতে দুটি সবুজ ঘর দেখবেন। bg-brand কোনো Tailwind-এর তৈরি নাম নয় — @theme-এ --color-brand লেখার ফলেই এসেছে। border-brand/30-এর /30 মানে ৩০% অস্বচ্ছতা। চেষ্টা করুন: (১) --color-brand-কে #c2410c করুন — বোতাম, সীমানা আর ঘর একসাথে কমলা হবে। (২) @theme-এ --color-gold: #b45309; যোগ করে বোতামে bg-gold লিখুন — নতুন class তৈরি হয়ে যাবে। (Tailwind-এর ডকুমেন্টেশন এই ব্রাউজার সংস্করণকে শুধু development-এর জন্য বলে — আসল সাইটে build টুল ব্যবহার করুন।)
@apply — সুবিধা আর ফাঁদ
লম্বা class-গুচ্ছ বারবার লিখতে বিরক্ত লাগলে Tailwind একটি পথ দেয়: নিজের CSS-এ @apply দিয়ে utility-গুলো একটি নামে জড়ো করা।
/* কাজ করে — কিন্তু বেশি করলে Tailwind-এর মূল সুবিধাই হারায় */
.btn-brand {
@apply rounded-lg bg-brand px-4 py-2 text-white hover:bg-brand-dark;
}সমস্যা হলো, সব কিছু @apply দিয়ে লিখলে আপনি আবার সেই নাম-বানানো, আলাদা-ফাইলে-খোঁজা পুরোনো CSS-এ ফিরে গেলেন — শুধু মাঝখানে একটি বাড়তি টুল রেখে। Tailwind-এর নিজের ডকুমেন্টেশনও বারবার ব্যবহৃত অংশের জন্য প্রথমে component (React, Vue, Blade-এর partial) বা লুপ ব্যবহারের পরামর্শ দেয়; @apply রাখুন ছোট, সত্যিকারের পুনরাবৃত্ত জিনিসের জন্য — যেমন বাইরের কোনো library-র HTML, যেখানে class বসানো যায় না।
আরও গভীরে: v4 শুধু কনফিগ বদলায়নি, ভিত্তিও বদলেছে। এটি ব্রাউজারের নতুন ক্ষমতার ওপর ভর করে — cascade layer, @property দিয়ে নিবন্ধিত custom property (পর্ব ৩৭), color-mix() (যা দিয়ে /30-এর অস্বচ্ছতা হিসাব হয়) আর oklch রং। ফলে তৈরি CSS পরিষ্কার, কিন্তু পুরোনো ব্রাউজারে ঠিক চলে না; Tailwind-এর ডকুমেন্টেশন মোটামুটি ২০২৩–২৪ সালের পরের ব্রাউজার (Safari 16.4, Chrome 111, Firefox 128 বা নতুন) ধরে নেয় আর পুরোনো ব্রাউজারের জন্য v3.4 ব্যবহারের পরামর্শ দেয়। @layer আর color-mix() এখন Baseline Widely available; @property ২০২৪-এ সব প্রধান ব্রাউজারে এসেছে (Baseline Newly available). নতুন engine-এর কিছু ভারী অংশ Rust-এ লেখা, তাই build আগের চেয়ে অনেক দ্রুত।
৭ · একই কার্ড তিনভাবে — সাধারণ CSS, Bootstrap আর Tailwind
তুলনা করার সবচেয়ে সৎ উপায় হলো একই জিনিস তিনভাবে বানানো। অংশ ২-এ Bootstrap কার্ড দেখেছেন। এবার একই নকশী কাঁথার কার্ড — ওপরে রঙিন ছবির জায়গা, নিচে নাম, বিবরণ, দাম আর বোতাম — প্রথমে নিজের লেখা CSS-এ, যেখানে HTML পরিষ্কার আর সব সিদ্ধান্ত CSS ফাইলে:
:root { --brand: #006a4e; --brand-dark: #00513b; --radius: 12px; }
body { font-family: system-ui, sans-serif; background: #f4f4f5; padding: 1rem; }
.card { max-width: 18rem; background: #fff; border-radius: var(--radius);
overflow: hidden; box-shadow: 0 2px 8px rgb(0 0 0 / .12); }
.card-img { aspect-ratio: 16 / 9; display: grid; place-items: center;
font-size: 3rem; background: linear-gradient(135deg, #fde68a, #fca5a5); }
.card-body { padding: 1rem 1.25rem 1.25rem; }
.card-title { margin: 0 0 .25rem; font-size: 1.15rem; }
.card-text { margin: 0; color: #52525b; }
.price { margin: .75rem 0; font-size: 1.25rem; font-weight: 700; color: var(--brand); }
.btn { font: inherit; color: #fff; background: var(--brand); border: 0;
border-radius: 8px; padding: .5rem 1rem; cursor: pointer; }
.btn:hover { background: var(--brand-dark); }
.btn:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }ওপরে হলুদ-গোলাপি gradient-এ একটি সুতার আইকন, নিচে কাঁথার নাম, ধূসর বিবরণ, সবুজ দাম আর সবুজ বোতাম। পুরো নকশা পনেরো লাইনেরও কম CSS-এ, framework ছাড়া, ইন্টারনেট ছাড়া। চেষ্টা করুন: (১) --radius-কে 0 করুন — কার্ড চারকোনা হবে; এক জায়গায় বদল, পুরো নকশায় প্রভাব। (২) .card-এর max-width মুছে দিন — কার্ড পুরো প্রিভিউ জুড়ে ছড়াবে; কার্ডের চওড়া আসলে তার পাত্রের সিদ্ধান্ত, পর্ব ২৯-এর লেআউট প্যাটার্নের মতো।
এবার হুবহু একই কার্ড Tailwind-এ। খেয়াল করুন, CSS ফাইল নেই — সব সিদ্ধান্ত HTML-এর class-এ:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3"></script>
<div class="bg-zinc-100 p-4">
<article class="max-w-72 overflow-hidden rounded-xl bg-white shadow-md">
<div class="grid aspect-video place-items-center bg-linear-135
from-amber-200 to-red-300 text-5xl" aria-hidden="true">🧵</div>
<div class="p-5">
<h3 class="text-lg font-semibold">নকশী কাঁথা</h3>
<p class="text-zinc-600">হাতে সেলাই, যশোরের কারিগর</p>
<p class="my-3 text-xl font-bold text-emerald-700">৳১,২৫০</p>
<button class="rounded-lg bg-emerald-700 px-4 py-2 text-white
hover:bg-emerald-800 focus-visible:outline-3
focus-visible:outline-offset-2 focus-visible:outline-amber-500">
কার্টে নিন
</button>
</div>
</article>
</div>দেখতে প্রায় হুবহু আগের কার্ড। কিন্তু খেয়াল করুন: <h3>-এর ব্রাউজার-ডিফল্ট বড় লেখা আর margin নেই — Tailwind-এর Preflight (base layer-এর reset) সব heading-কে সাধারণ লেখার মতো করে দেয়, তাই text-lg font-semibold লিখতে হয়েছে। চেষ্টা করুন: (১) max-w-72-কে max-w-96 করুন — কার্ড চওড়া হবে (৭২ × 0.25rem = 18rem, ৯৬ × 0.25rem = 24rem). (২) <article>-এ md:flex যোগ করুন, আর ছবির ঘরে md:w-40 — প্রিভিউ 768px বা তার বেশি চওড়া হলে ছবি বাঁয়ে, লেখা ডানে চলে আসবে।
তিনটি পদ্ধতি পাশাপাশি রাখলে পার্থক্যটা পরিষ্কার হয়:
| প্রশ্ন | সাধারণ CSS | Bootstrap | Tailwind |
|---|---|---|---|
| নকশার সিদ্ধান্ত কোথায় | CSS ফাইলে | Bootstrap-এর ফাইলে (আপনি বাছেন) | HTML-এর class-এ |
| HTML দেখতে | পরিষ্কার, অর্থবহ নাম | মাঝারি — card, btn btn-success | লম্বা class-এর সারি |
| ব্র্যান্ডের রং বদল | একটি variable | Sass build বা অনেক --bs-* variable | @theme-এ একটি লাইন |
| ব্রাউজারে যায় | শুধু আপনার লেখা | পুরো framework (না ছাঁটলে) | শুধু ব্যবহৃত utility |
| build ধাপ লাগে? | না | না (CDN), কাস্টমাইজে হ্যাঁ | আসল সাইটে হ্যাঁ |
| দেখতে আলাদা হবে? | পুরোপুরি আপনার | চেষ্টা না করলে “Bootstrap-চেনা” | পুরোপুরি আপনার, স্কেলের ভেতরে |
| নতুন কাউকে বোঝাতে | CSS জানলেই হলো | Bootstrap-এর ডকুমেন্টেশন লাগে | Tailwind-এর নাম শিখতে হয় |
৮ · ওপরের তলা আর অন্য বিকল্প — daisyUI, shadcn/ui, Bulma, Pico.css, Open Props
Tailwind শুধু utility দেয়, তৈরি বোতাম বা modal দেয় না। তাই এর ওপর দাঁড়িয়ে বেশ কিছু component library গড়ে উঠেছে। দুটি পরিচিত নাম, দুটি আলাদা দর্শন:
daisyUI
Tailwind-এর একটি plugin, যা btn, card, modal-এর মতো component class আর তৈরি থিম যোগ করে। অর্থাৎ Tailwind-এর ভেতরে Bootstrap-এর মতো অভিজ্ঞতা — দরকারে পাশে utility দিয়ে বদলানো যায়। শুধু CSS, কোনো নির্দিষ্ট JavaScript framework লাগে না।
shadcn/ui
একটি সাধারণ npm library নয় — একটি টুল আপনার প্রজেক্টে component-এর উৎস কোড সরাসরি কপি করে দেয়, যা Tailwind দিয়ে সাজানো আর ভেতরে অ্যাক্সেসিবিলিটি সামলানো headless primitive-এর ওপর দাঁড়ানো। কোড আপনার, যেমন খুশি বদলান; বিনিময়ে আপডেটও নিজেকে মেলাতে হয়। মূলত React প্রজেক্টে ব্যবহৃত।
কোড কপি করা componentBootstrap আর Tailwind ছাড়াও কয়েকটি বিকল্প চেনা থাকা ভালো:
| নাম | ধরন | কখন ভাবা যায় |
|---|---|---|
| Foundation (ZURB) | Bootstrap-এর সমসাময়িক পূর্ণ framework, ২০১১ | পুরোনো প্রজেক্ট আর ইমেইল টেমপ্লেটে এখনো দেখা যায় |
| Bulma | শুধু CSS, কোনো JavaScript নয়, Flexbox-ভিত্তিক, পড়ার মতো class নাম | Bootstrap-এর মতো component চান, কিন্তু JavaScript-এর বোঝা চান না |
| Pico.css | classless — class ছাড়াই অর্থবহ HTML সাজায় | ডকুমেন্টেশন, ছোট টুল, প্রোটোটাইপ |
| Open Props | framework নয় — তৈরি CSS variable (রং, ছায়া, ফাঁক, easing)-এর সংগ্রহ | নিজের CSS লিখবেন, শুধু ভালো design token চান |
Classless CSS-এর ধারণাটি সবচেয়ে সহজে বোঝা যায় চোখে দেখে। নিচের HTML-এ একটিও class নেই — শুধু পর্ব ৮ আর ১০-এর মতো অর্থবহ ট্যাগ:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2.1.1/css/pico.classless.min.css">
<main>
<h2>অর্ডারের জন্য যোগাযোগ</h2>
<form>
<label>আপনার নাম <input name="name" required></label>
<label>মোবাইল নম্বর <input name="phone" type="tel" inputmode="tel"></label>
<fieldset>
<legend>পেমেন্ট</legend>
<label><input type="radio" name="pay" value="cod" checked> ক্যাশ অন ডেলিভারি</label>
<label><input type="radio" name="pay" value="mobile"> মোবাইল ব্যাংকিং</label>
</fieldset>
<button>পাঠান</button>
</form>
</main>বড় ঘর, গোল কোণ, নীল বোতাম, সুন্দর radio — সব এসেছে শুধু ট্যাগ দেখে। আপনার কম্পিউটার dark mode-এ থাকলে Pico নিজে থেকেই গাঢ় চেহারা দেখাবে। নাম ফাঁকা রেখে “পাঠান” চাপুন — ব্রাউজারের নিজের সতর্কবার্তা আসবে; নাম লিখে চাপলে নিচে লেখা আসবে “ফর্ম জমা হতো → …”. চেষ্টা করুন: (১) প্রথম লাইনের <link> মুছে দিন — একই HTML ব্রাউজারের সাদামাটা ডিফল্টে ফিরে যাবে। (২) <label>-গুলো মুছে শুধু <input> রাখুন — classless CSS কতটা সঠিক HTML-এর ওপর নির্ভর করে, টের পাবেন।
৯ · কোনটি কখন — আর কেন CSS জানা এখনো জরুরি
“সেরা framework কোনটি?” প্রশ্নটির সঠিক উত্তর নেই — আছে “এই প্রজেক্টে, এই দলের জন্য কোনটি?” সিদ্ধান্তের সময় এই প্রশ্নগুলো নিজেকে করুন:
| প্রশ্ন | যদি উত্তর হয়… | ঝোঁক |
|---|---|---|
| নকশা কতটা নিজস্ব? | ডিজাইনারের Figma আছে, ব্র্যান্ড আলাদা দেখাতে হবে | Tailwind বা নিজের CSS |
| admin প্যানেল, অভ্যন্তরীণ টুল — চেহারা “পরিষ্কার হলেই চলে” | Bootstrap বা তৈরি component library | |
| প্রজেক্ট কত বড়? | এক পাতার ল্যান্ডিং পেজ, ছোট ব্যক্তিগত সাইট | প্রায়ই framework ছাড়া সাধারণ CSS, বা Pico |
| বহু পাতা, বহু মানুষ, বছরের পর বছর রক্ষণাবেক্ষণ | যেকোনো একটি নিয়মিত ব্যবস্থা — framework বা পর্ব ৪৬-এর architecture | |
| দল কী জানে? | দলে সবাই Bootstrap চেনেন, সময় কম | Bootstrap — নতুন কিছু শেখানোর খরচ নেই |
| বাকি প্রযুক্তি কী? | React, Vue, Next.js, Laravel-এর component-ভিত্তিক কাজ | Tailwind — class বারবার লেখার সমস্যা component নিজেই মেটায় |
| WordPress থিম, পুরোনো jQuery সাইট | যা আছে তাই — প্রায়ই Bootstrap | |
| build ধাপ সম্ভব? | শুধু FTP-তে ফাইল তোলা যায়, কোনো npm নয় | CDN-এর Bootstrap, বা নিজের CSS |
বাংলাদেশের কাজের বাজারে দুটো নামই নিয়মিত দেখা যায়। ফ্রিল্যান্সিং মার্কেটপ্লেসে ল্যান্ডিং পেজ, WordPress থিম, admin ড্যাশবোর্ড আর পুরোনো সাইট ঠিক করার বহু কাজে Bootstrap আসে, কারণ লাখো টেমপ্লেট আর থিম এর ওপর বানানো। নতুন React বা Next.js প্রজেক্ট, স্টার্টআপ আর বিদেশি এজেন্সির কাজে Tailwind-এর চাহিদা গত কয়েক বছরে দ্রুত বেড়েছে; Laravel-এর মতো জনপ্রিয় backend-এর শুরুর টেমপ্লেটেও Tailwind থাকে। তাই দুটোরই মূল জিনিসগুলো চেনা থাকলে সুবিধা — কিন্তু ক্লায়েন্ট আসলে কেনেন একটি দ্রুত, সুন্দর, সবার জন্য ব্যবহারযোগ্য সাইট, কোনো framework-এর নাম নয়। (ফ্রিল্যান্সিংয়ের বিস্তারিত পথ জানতে ICT কোর্সের ফ্রিল্যান্সিং পর্ব দেখতে পারেন।)
Framework হলো CSS-এর ওপর একটি স্তর, CSS-এর বদলে নয়। col-sm-6 আসলে Flexbox আর media query, md:p-10 আসলে media query আর padding, --bs-btn-bg আসলে custom property, Tailwind-এর ক্রম আসলে cascade layer. যখন কিছু ভুল দেখায় — কার্ড উপচে পড়ছে, hover-এ রং বদলাচ্ছে না, ফোনে পাশাপাশি স্ক্রল আসছে — DevTools আপনাকে framework-এর নাম নয়, সাধারণ CSS দেখাবে। এই কোর্সের আগের ৫০টি পর্ব ঠিক সেই মুহূর্তের জন্য।
আরেকটি কারণ আছে: framework বদলায়। Bootstrap 3 থেকে 4-এ যাওয়া মানে অনেক প্রজেক্টে প্রায় নতুন করে লেখা; Tailwind v3 থেকে v4-এ কনফিগের জায়গাই বদলে গেছে। দশ বছর আগে যিনি শুধু Bootstrap 3-এর class মুখস্থ করেছিলেন, আজ তাঁকে আবার শুরু করতে হয়। যিনি Flexbox, Grid আর cascade বুঝেছিলেন, তিনি যেকোনো নতুন framework এক বিকেলে ধরতে পারেন।
পরীক্ষা ও ইন্টারভিউতে — বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে:
- Bootstrap grid-এ কয়টি কলাম, আর
.col-md-6মানে কী? — ১২টি; 768px বা তার বেশি চওড়ায় অর্ধেক (৬/১২), তার কমে পুরো চওড়া। - Utility-first CSS কী? — প্রতিটি class একটি ছোট কাজ (সাধারণত একটি ঘোষণা) করে, আর HTML-এ সেগুলো জোড়া দিয়ে নকশা হয়; Tailwind CSS এর প্রধান উদাহরণ।
- Tailwind-এর CSS ফাইল ছোট থাকে কেন? — build টুল ফাইল স্ক্যান করে শুধু ব্যবহৃত class-এর CSS তৈরি করে।
- Bootstrap 5-এর প্রধান পরিবর্তন? — jQuery আর Internet Explorer সমর্থন বাদ, RTL, utility API; পরে v5.3-এ রঙের মোড।
- Inline style আর Tailwind class-এর পার্থক্য? — inline style-এ hover বা media query লেখা যায় না, কোনো ডিজাইন স্কেল নেই, আর specificity সবচেয়ে বেশি; Tailwind class-এ variant, স্কেল আর সাধারণ class-এর specificity থাকে।
১০ · AI-এর যুগে — framework-এর কোড AI-কে দিয়ে লেখালে
AI-কে “Bootstrap দিয়ে একটি navbar বানাও” বা “Tailwind-এ একটি pricing কার্ড দাও” বললে কয়েক সেকেন্ডে কোড পাবেন — আর প্রায়ই সেটি দেখতে ঠিকঠাক লাগবে। সমস্যা লুকিয়ে থাকে সংস্করণে। AI শিখেছে বহু বছরের পুরোনো-নতুন কোড মিশিয়ে, তাই এক উত্তরে Bootstrap 4 আর 5, বা Tailwind v3 আর v4 মিলে যায়। আর framework থাকলেই কোড অ্যাক্সেসিবল হয় না — framework-এর class দিয়েও div-soup লেখা যায়।
AI সাধারণত যেসব ভুল করে
| AI-এর ভুল | আপনি যা দেখবেন | ঠিক উপায় |
|---|---|---|
Bootstrap 5-এ v4-এর data-toggle, ml-3, float-left, sr-only | মেনু খোলে না, ফাঁক নেই, লুকানো লেখা দেখা যায় | v5-এ data-bs-toggle, ms-3, float-start, visually-hidden |
Bootstrap 5-এর সাথে jQuery যোগ বা $('#x').modal() | অকারণ বাড়তি ফাইল, বা “$ is not defined” | v5-এর নিজের JavaScript বা data attribute |
v4 প্রজেক্টে tailwind.config.js আর @tailwind base; | রং-ফন্ট কাজ করে না, build-এ ত্রুটি বা সতর্কবার্তা | @import "tailwindcss"; আর @theme |
bg-${color}-500-এর মতো জোড়া দেওয়া class | development-এ চলে মনে হয়, আসল build-এ রং নেই | পুরো class নাম লেখা, শর্ত দেখে বাছা |
| আসল সাইটে Tailwind-এর ব্রাউজার script | ধীর লোড, লেআউট লাফায় | build টুল দিয়ে তৈরি CSS ফাইল |
ক্লিকযোগ্য <div>, ✕ বোতামে নাম নেই, outline-none | কি-বোর্ডে চলে না, screen reader “button” বলে না | <button>, aria-label, স্পষ্ট focus-visible: দাগ |
AI-কে কাজ দেওয়ার সময় সংস্করণ, পরিবেশ আর শর্ত স্পষ্ট লিখে দিন:
AI-এর দেওয়া framework-কোড হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলোই আপনাকে framework ব্যবহারকারী থেকে সিদ্ধান্ত নিতে পারা প্রকৌশলী বানাবে।
প্র ০১Bootstrap এত দ্রুত এত জনপ্রিয় হলো কেন, আর “সব সাইট দেখতে একই রকম” অভিযোগটি কোথা থেকে এলো?
সময়টা ছিল অসাধারণ। ২০১১-১২ সালে স্মার্টফোন দ্রুত ছড়াচ্ছে, অথচ বেশিরভাগ ওয়েবসাইট তখনো স্থির চওড়ার ডেস্কটপ পাতা। “রেসপন্সিভ ডিজাইন” শব্দটি সবে জনপ্রিয় হয়েছে, কিন্তু float দিয়ে রেসপন্সিভ grid লেখা কঠিন, আর Internet Explorer-এর পুরোনো সংস্করণ সামলানো আরও কঠিন। Bootstrap 2 ঠিক তখন একটি পরীক্ষিত রেসপন্সিভ grid আর সুন্দর ডিফল্ট দিল — বিনামূল্যে, ভালো ডকুমেন্টেশনসহ, আর Twitter-এর নামের ভরসায়।
- ব্যাকএন্ড ডেভেলপারের রক্ষাকর্তা: যাঁরা সার্ভারের কোড লেখেন কিন্তু নকশায় দক্ষ নন, তাঁরা এক দিনে “পেশাদার দেখায়” এমন admin প্যানেল বানাতে পারলেন।
- টেমপ্লেটের বাজার: থিম বিক্রির মার্কেটপ্লেসে হাজারো Bootstrap-ভিত্তিক টেমপ্লেট এলো; WordPress থিমেও এটি ঢুকে গেল। একবার এই বাস্তুতন্ত্র তৈরি হলে নতুনরা সেখানেই শেখেন।
- সাধারণ ভাষা: দলে নতুন কেউ এলে
.btn-primaryবা.col-md-4বোঝাতে হয় না — এটি একটি শিল্প-মানের শব্দভাণ্ডারে পরিণত হলো।
“একই রকম” অভিযোগটি এই সাফল্যেরই ছায়া। বেশিরভাগ মানুষ ডিফল্ট রং, ডিফল্ট বোতাম, ডিফল্ট navbar-ই রেখে দিতেন — কারণ বদলানো ঝামেলার (অংশ ৪)। ফলে এক সময় এক নজরে চেনা যেত, “এটা Bootstrap সাইট।” Bootstrap নিজেও এটি বুঝে পরের সংস্করণগুলোতে Sass variable, utility API আর v5.2-এর পর component-ভিত্তিক CSS variable বাড়িয়েছে, যাতে চেহারা বদলানো সহজ হয়। Tailwind-এর উত্থানের পেছনেও এই ক্লান্তি একটি কারণ: সে কোনো তৈরি চেহারাই দেয় না, তাই “Tailwind সাইট” চেনার কোনো ডিফল্ট নেই — যদিও এখন তার জনপ্রিয় টেমপ্লেট আর component library-ও নিজস্ব “চেনা চেহারা” তৈরি করছে।
মূল উপলব্ধি: একটি টুলের ডিফল্ট আসলে একটি সিদ্ধান্ত, যা লক্ষ মানুষ না ভেবে মেনে নেন। ডিফল্ট দিয়ে শুরু করা দোষের নয় — ডিফল্টে থেমে থাকাটাই নকশাকে একঘেয়ে করে।
প্র ০২Tailwind কি আসলে “inline style-এর নতুন নাম”? সমালোচকরা কী বলেন, আর পার্থক্যটা কোথায়?
সমালোচনাটি বোঝা যায়: class="p-4 bg-white rounded-lg shadow" দেখতে প্রায় style="padding:1rem; background:#fff; …"-এর মতোই — চেহারার তথ্য HTML-এর ভেতরে। পর্ব ১৬-এ শিখেছেন inline style কেন সাধারণত এড়ানো হয়। তাহলে Tailwind কি একই ভুল?
না, কারণ কয়েকটি গুরুত্বপূর্ণ জায়গায় পার্থক্য আছে:
- শর্ত লেখা যায়: inline style-এ
:hover,:focus-visible, media query বা dark mode লেখা অসম্ভব। Tailwind-এhover:,md:,dark:আছে। - সীমিত স্কেল: inline style-এ যে কেউ 13px বা 17px লিখতে পারেন; Tailwind-এর
p-3,p-4একটি নির্দিষ্ট স্কেল থেকে আসে। এই সীমাবদ্ধতাই দলের নকশাকে সামঞ্জস্যপূর্ণ রাখে — যদিও arbitrary value দিয়ে সেটি ভাঙা যায়। - Specificity: inline style প্রায় সব নিয়মকে হারায় (পর্ব ১৮), বদলাতে
!importantলাগে। Tailwind class সাধারণ এক-class-এর specificity, আর v4-এ সবাই একটি layer-এ। - Cache: একই
.p-4নিয়ম সারা সাইটে একবারই লেখা থাকে, CSS ফাইল ব্রাউজারে জমা থাকে।
তবে সমালোচনার সত্য দিকও আছে। লম্বা class-এর সারি পড়া কঠিন, git-এর পরিবর্তন দেখতে কষ্ট হয়, আর কোনটি “কার্ড” কোনটি “বোতাম” — সেই অর্থবহ নাম HTML থেকে হারিয়ে যায়। Tailwind-এর উত্তর হলো component: React বা Blade-এ <ProductCard> একবার লিখুন, class-গুলো এক জায়গায় থাকুক। কিন্তু শুধু HTML-এর সাইটে, যেখানে component নেই, এই সমাধান দুর্বল — সেখানে একই কার্ড দশবার কপি করলে দশ জায়গায় বদলাতে হয়। CSS জগতের এই বিতর্ক — “অর্থভিত্তিক নাম” বনাম “কাজভিত্তিক ছোট class” — এক দশকের বেশি পুরোনো, আর পর্ব ৪৬-এর BEM আর utility-র আলোচনা তারই অংশ।
মূল উপলব্ধি: একটি পদ্ধতিকে তার চেহারা দিয়ে নয়, তার সীমাবদ্ধতা আর সুবিধা দিয়ে বিচার করুন। একই রকম দেখতে দুটি জিনিস একেবারে আলাদা সমস্যার সমাধান হতে পারে।
প্র ০৩“Tailwind বা Bootstrap জানলে CSS শেখার দরকার নেই” — কথাটি কেন ভুল, বাস্তব উদাহরণ দিয়ে বলুন।
কারণ framework আপনার হয়ে চিন্তা করে না — শুধু টাইপ কমায়। কয়েকটি প্রতিদিনের পরিস্থিতি ভাবুন:
- কার্ড উপচে পড়ছে: একটি Flexbox সারিতে লম্বা ইমেইল ঠিকানা কার্ডকে চওড়া করে পাশাপাশি স্ক্রল আনছে। সমাধান
min-w-0(বাmin-width: 0) — কিন্তু কেন, সেটি বুঝতে পর্ব ২৫-এর flex item-এর automatic minimum size জানতে হবে। Framework-এর ডকুমেন্টেশন এটি শেখায় না। - z-index কাজ করছে না: Bootstrap-এর dropdown একটি কার্ডের নিচে চাপা পড়ছে।
z-indexযত বাড়ান, কিছু হয় না — কারণ পর্ব ২৪-এর stacking context. শুধু class মুখস্থ থাকলে এখানে ঘণ্টার পর ঘণ্টা যায়। - রং বদলাচ্ছে না: অংশ ৪-এর hover-এর নীল — specificity না বুঝলে মনে হবে Bootstrap “বাগি”।
- সংস্করণ বদল: Tailwind v4-এ ডিফল্ট সীমানার রং, ছায়ার নাম, ring-এর মাপ কিছু বদলেছে। যিনি CSS বোঝেন, DevTools-এ দেখে এক মিনিটে বুঝবেন কী বদলাল।
এর সাথে আছে framework যা দেয় না: অ্যাক্সেসিবিলিটির বিচার (পর্ব ৪৫), পারফরম্যান্স (পর্ব ৪৯), container query বা anchor positioning-এর মতো নতুন ফিচার, যা framework-এ আসতে দেরি হয়। আর ইন্টারভিউতে প্রায়ই বলা হয়, “framework ছাড়া এই লেআউট বানান” — কারণ নিয়োগকর্তা জানেন framework শেখা যায় দুই সপ্তাহে, CSS-এর বোধ গড়ে ওঠে বছরে।
একটি তুলনা: ক্যালকুলেটর থাকলেও গণিত জানতে হয় — না হলে ভুল বোতাম চাপলে বোঝা যায় না উত্তরটি অসম্ভব। AI-এর যুগে এটি আরও সত্য: AI framework-এর class খুব দ্রুত লেখে, কিন্তু ভুল class দিলে ধরার ক্ষমতা আপনার CSS-জ্ঞান থেকেই আসে।
মূল উপলব্ধি: Framework হলো শর্টকাট; শর্টকাট তাঁর জন্যই কাজের, যিনি পুরো রাস্তাটি চেনেন। CSS-এর ভিত্তি থাকলে framework আপনাকে দ্রুত করে, না থাকলে আপনাকে আটকে রাখে।
প্র ০৪একটি কোম্পানি পাঁচ বছর চলবে এমন একটি প্রজেক্টে framework বেছে নিচ্ছে। দীর্ঘমেয়াদি ঝুঁকিগুলো কী, আর কীভাবে কমানো যায়?
শুরুর দিনে framework সময় বাঁচায়, কিন্তু খরচের হিসাব আসে পরে। প্রধান ঝুঁকিগুলো:
- বড় সংস্করণের বদল: Bootstrap 3 থেকে 4-এ grid Flexbox-এ গেল, Less থেকে Sass, বহু class-এর নাম বদলাল — বড় প্রজেক্টে এটি কয়েক সপ্তাহের কাজ। v4 থেকে 5-এ jQuery আর বাম-ডান নামের বদল। Tailwind v3 থেকে v4-এ কনফিগ JavaScript থেকে CSS-এ এলো, কিছু class-এর নাম ও ডিফল্ট বদলাল; Tailwind একটি স্বয়ংক্রিয় upgrade টুল দেয়, তবু হাতে যাচাই লাগে।
- আটকে যাওয়া (lock-in): হাজার হাজার HTML ফাইলে framework-এর class ছড়ানো থাকলে অন্য কিছুতে যাওয়া প্রায় নতুন করে লেখার সমান।
- পুরোনো সংস্করণে আটকে থাকা: upgrade-এর খরচ বেশি বলে অনেক প্রতিষ্ঠান বছরের পর বছর পুরোনো সংস্করণে থাকে — তখন নিরাপত্তা আপডেট আর নতুন ব্রাউজার ফিচার থেকে বঞ্চিত হয়। আজও বহু সরকারি-বেসরকারি সাইটে Bootstrap 3 আর পুরোনো jQuery চলে।
- লোক বদল: পাঁচ বছরে দলের মানুষ বদলাবেন। যে framework বাজারে কম পরিচিত, তার জন্য লোক পাওয়া কঠিন।
ঝুঁকি কমানোর কৌশল:
- নকশার মান নিজের হাতে রাখুন: রং, ফাঁক, ফন্ট CSS custom property বা design token-এ রাখুন (পর্ব ৩৩) — framework বদলালেও এগুলো থাকে। Tailwind v4-এর
@themeনিজেই CSS variable তৈরি করে, যা এই কাজে সাহায্য করে। - Component-এর আড়াল: framework-এর class সরাসরি হাজার পাতায় না ছড়িয়ে কয়েকটি component-এর ভেতরে রাখুন; বদলালে শুধু সেগুলো বদলাতে হবে।
- অর্থবহ HTML: সঠিক ট্যাগ আর কাঠামো framework-নিরপেক্ষ — CSS বদলালেও HTML টিকে থাকে।
- পরিকল্পিত upgrade: প্রতিটি বড় সংস্করণের পর একটি নির্দিষ্ট সময়ের মধ্যে upgrade-এর নীতি রাখুন, আর বিভিন্ন পর্দার screenshot তুলনা করার মতো পরীক্ষা রাখুন।
মূল উপলব্ধি: যেকোনো dependency একটি ঋণ — আজ সময় ধার নেন, পরে সুদসহ শোধ করেন। ভালো প্রকৌশল মানে ঋণ না নেওয়া নয়, জেনে-বুঝে আর শোধের পরিকল্পনাসহ নেওয়া।
প্র ০৫shadcn/ui-এর “কোড কপি করে নিন” মডেল আর Bootstrap-এর মতো “library install করুন” মডেলের পার্থক্য কী? দুটির ভালো-মন্দ কোথায়?
Bootstrap, daisyUI বা বেশিরভাগ npm library-তে component-এর কোড থাকে library-র ভেতরে। আপনি ব্যবহার করেন, কিন্তু ভেতরের কোড বদলান না; নতুন সংস্করণ এলে একটি কমান্ডে আপডেট পান। shadcn/ui উল্টো ভাবে: একটি কমান্ড চালালে, ধরুন, Dialog component-এর পুরো উৎস কোড আপনার প্রজেক্টের একটি ফোল্ডারে চলে আসে। তারপর সেটি আপনার কোড — যেমন খুশি বদলান।
- কপি-মডেলের সুবিধা: পুরো নিয়ন্ত্রণ। ব্র্যান্ডের মতো বদলাতে override-এর যুদ্ধ নেই (অংশ ৪-এর সমস্যা), কারণ আপনি সরাসরি উৎসেই বদলাচ্ছেন। অপ্রয়োজনীয় কিছুই প্রজেক্টে ঢোকে না।
- কপি-মডেলের দাম: আপডেট আর আপনাআপনি আসে না। মূল কোডে কোনো ভুল ঠিক হলে, বা অ্যাক্সেসিবিলিটির উন্নতি হলে, আপনাকে নিজে মিলিয়ে নিতে হবে — আর নিজের বদলের সাথে সংঘাত মেটাতে হবে।
- Library-মডেলের সুবিধা ও দাম: আপডেট সহজ, দল জুড়ে একরকম; কিন্তু বদলানোর স্বাধীনতা কম, আর library যা দেয় না, তা পেতে কৌশল লাগে।
একটি গভীর বিষয় দুটি মডেলেই সমান: modal, dropdown, tab-এর মতো জিনিস ঠিকভাবে বানানো কঠিন — focus আটকে রাখা, Esc-এ বন্ধ, screen reader-কে সঠিক role আর অবস্থা জানানো (পর্ব ১২)। তাই আধুনিক অনেক library এই আচরণ “headless” primitive-এ রাখে — চেহারা নেই, শুধু সঠিক আচরণ ও অ্যাক্সেসিবিলিটি — আর চেহারা দেয় Tailwind বা নিজের CSS. আর আজকের HTML-এর <dialog>, popover আর <details> ব্রাউজারের ভেতরেই এর বড় অংশ দিয়ে দেয়, যা ভবিষ্যতে এসব library-র বোঝা আরও কমাবে।
মূল উপলব্ধি: “মালিকানা বনাম সুবিধা” — সফটওয়্যারের প্রায় প্রতিটি নির্ভরতার সিদ্ধান্তে এই টানাপোড়েন। যত বেশি নিজের হাতে রাখবেন, তত বেশি স্বাধীনতা, তত বেশি দায়িত্ব।
অনুশীলন
বেশিরভাগই দেখা আর ভাবার কাজ — শেষেরটিতে একটু কোড লিখতে হবে।
-
Bootstrap-এর ভেতরে উঁকি: getbootstrap.com-এর যেকোনো উদাহরণ পাতায় একটি নীল
.btn-primaryবোতামে ডান-ক্লিক করে Inspect চাপুন। Styles প্যানেলেbackground-colorকোথা থেকে আসছে দেখুন, আর Computed ট্যাবে চূড়ান্ত মান মিলিয়ে নিন।দেখবেন
.btnনিয়মে লেখা আছেbackground-color: var(--bs-btn-bg), আর.btn-primaryনিয়মে--bs-btn-bg: #0d6efdসহ একগাদা--bs-btn-*variable. অর্থাৎ.btnশুধু কাঠামো দেয়, আর রঙের class শুধু variable বদলায়। Styles প্যানেলে--bs-btn-bg-এর মান বদলে দেখুন — বোতাম সঙ্গে সঙ্গে রং বদলাবে। অংশ ৪-এর উপায় ২ ঠিক এই নকশার সুবিধা নেয়। -
অনুবাদক হোন: নিচের Tailwind class-গুলোর প্রতিটি কোন CSS তৈরি করে, লিখুন:
hidden md:block,mx-auto,grid-cols-3,text-center,focus-visible:ring-2.hidden md:block— সব পর্দায়display: none, কিন্তু 48rem থেকেdisplay: block; অর্থাৎ ফোনে লুকানো, বড় পর্দায় দেখা যায়।mx-auto—margin-inline: auto; চওড়া সীমিত থাকলে উপাদান মাঝখানে বসে (পর্ব ১৯)।grid-cols-3—grid-template-columns: repeat(3, minmax(0, 1fr)); তিনটি সমান কলাম।minmax(0, 1fr)লম্বা শব্দকে কলাম চওড়া করতে দেয় না।text-center—text-align: center.focus-visible:ring-2—:focus-visible-এ একটি ২px-এর box-shadow “ring”. সতর্কতা: Windows-এর forced colors মোডে box-shadow মুছে যায় (পর্ব ৪৫), তাই গুরুত্বপূর্ণ focus-এর জন্য outline-ভিত্তিক class (focus-visible:outline-2) বেশি নিরাপদ।
-
অব্যবহৃত CSS মাপুন: Bootstrap দিয়ে বানানো যেকোনো একটি সাইট খুলুন (অনেক টেমপ্লেট সাইটে পাবেন)। DevTools-এ Ctrl+Shift+P চেপে “Coverage” লিখে প্যানেলটি খুলুন, reload চাপুন, আর bootstrap.min.css-এর লাল (অব্যবহৃত) অংশের শতাংশ দেখুন।
সাধারণ একটি পাতায় Bootstrap-এর CSS-এর বড় অংশ — প্রায়ই অর্ধেকের অনেক বেশি — লাল দেখায়, অর্থাৎ এই পাতায় কোনো কাজে আসেনি। তবে সংখ্যাটি একটু সাবধানে পড়ুন: Coverage শুধু এই মুহূর্তের এই পাতা মাপে; মেনু খুললে বা অন্য পাতায় গেলে আরও কিছু নিয়ম কাজে লাগে। তবু এটি স্পষ্ট দেখায় কেন Sass দিয়ে অপ্রয়োজনীয় component বাদ দেওয়া, বা Tailwind-এর মতো “শুধু যা লাগে” পদ্ধতি পারফরম্যান্সে সাহায্য করে (পর্ব ৪৯)।
-
Framework ছাড়া একই grid: অংশ ২-এর স্টেপারের লেআউট — ফোনে ১টি, মাঝারি পর্দায় ২টি, বড় পর্দায় ৩টি কার্ড — কোনো framework ছাড়া সাধারণ CSS-এ লিখুন। সম্ভব হলে কোনো media query ছাড়াই।
পর্ব ২৮-এর
auto-fitআরminmax()দিয়ে এক লাইনেই হয় — কলামের সংখ্যা ব্রাউজার নিজে হিসাব করে:.products { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); gap: 1rem; }প্রতিটি কার্ড অন্তত 16rem চওড়া হতে চায়; পাত্রে যতগুলো ধরে, ততগুলো কলাম।
min(16rem, 100%)খুব সরু ফোনে কার্ডকে পাত্রের বাইরে যেতে দেয় না। Bootstrap-এর মতো ঠিক “২টি, তারপর ৩টি” চাইলে@media (width >= 36rem)আর(width >= 62rem)-এgrid-template-columns: repeat(2, 1fr)ওrepeat(3, 1fr)লিখুন। দুই ক্ষেত্রেই কোনো framework লাগেনি — Bootstrap-এর grid যা দিত, আধুনিক CSS তা নিজেই দেয়।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমTailwind CSS-এর class থেকে ব্রাউজারে CSS পৌঁছানোর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- 📄 HTML বা component ফাইলে utility class লেখা
- 🔍 Scanner ফাইল পড়ে class-এর মতো শব্দ খুঁজে বের করে
- ⚙️ Engine
@theme-এর মান মিলিয়ে শুধু সেই class-গুলোর CSS তৈরি করে - 🗂️ তৈরি CSS theme, base, components, utilities layer-এ সাজানো হয়
- 📦 ছোট CSS ফাইলটি পাতার সাথে ব্রাউজারে যায়
Bootstrap 5-এ একটি কলামে class="col-12 col-sm-6" দেওয়া আছে। 700px চওড়া পর্দায় কলামটি কত চওড়া হবে?
- সারির পুরো চওড়া
- সারির অর্ধেক
- সারির এক-তৃতীয়াংশ
- কলামটি লুকিয়ে যাবে, কারণ sm শুধু ছোট পর্দার জন্য
Tailwind CSS-এ md:p-10 class-টির অর্থ কী?
- মাঝারি মাপের padding, সব পর্দায়
- 768px-এর কম চওড়া পর্দায় 10px padding
- 48rem (768px) বা তার বেশি চওড়ায় চারদিকে 2.5rem padding
- সব পর্দায় 10px padding
Bootstrap 4 থেকে Bootstrap 5-এ সবচেয়ে বড় পরিবর্তনগুলোর একটি কোনটি?
- JavaScript component থেকে jQuery-র নির্ভরতা বাদ দেওয়া
- প্রথমবার Flexbox-ভিত্তিক grid আনা
- Sass ছেড়ে Less-এ ফিরে যাওয়া
- grid-কে ১২ থেকে ১৬ কলামে বদলানো
Tailwind CSS v4-এ প্রজেক্টের ব্র্যান্ড রং (যেমন --color-brand) সংজ্ঞায়িত করার প্রস্তাবিত জায়গা কোনটি?
- tailwind.config.js ফাইলের theme অংশে
- প্রতিটি HTML উপাদানের style attribute-এ
- package.json ফাইলে
- CSS ফাইলের
@themeব্লকে
একটি Tailwind প্রজেক্টে কোড আছে class="bg-${color}-500", যেখানে color চলার সময় "red" বা "green" হয়। build করা সাইটে রং দেখা যাচ্ছে না। কারণ কী?
- Tailwind-এ red-500 বা green-500 নামের কোনো রং নেই
- Build টুল ফাইলে পুরো class নাম খুঁজে পায়নি, তাই তার CSS তৈরি হয়নি
- ব্রাউজার $ চিহ্নওয়ালা class নাম পড়তে পারে না
- অন্য কোনো class-এর specificity বেশি বলে রং হারছে
Bootstrap 5.3-এ .btn-primary বোতামের রং hover আর active অবস্থাসহ বদলানোর সবচেয়ে পরিষ্কার উপায় কোনটি (build ধাপ ছাড়া)?
- নিজের CSS-এ
.btn-primary { background: … }লেখা - প্রতিটি নিয়মে
!importantযোগ করা - বোতামের
--bs-btn-bg,--bs-btn-hover-bg-এর মতো CSS variable বদলানো - bootstrap.min.css ফাইল খুলে নীল রঙের সব জায়গা হাতে বদলানো
Pico.css-এর মতো “classless” CSS framework-এর মূল বৈশিষ্ট্য কোনটি?
- কোনো class ছাড়াই অর্থবহ HTML ট্যাগকে সরাসরি সাজায়
- প্রতিটি CSS ঘোষণার জন্য একটি করে ছোট class দেয়
- পাতা সাজাতে JavaScript দিয়ে class যোগ করে
- শুধু build টুল দিয়েই ব্যবহার করা যায়
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- CSS framework হলো আগে থেকে লেখা CSS — grid, component, utility আর সামঞ্জস্য দেয়; দাম হিসেবে নেয় আকার, একঘেয়েমি, শেখার সময় আর override-এর ঝামেলা।
- Bootstrap: ১২ কলামের
.container/.row/.col-sm-6grid, তৈরি component আর তাদের JavaScript (v5-এ jQuery নেই); রং বদলান Sass বা--bs-*variable দিয়ে, ওপর থেকে ঢেকে নয়। - Tailwind: utility-first;
md:,hover:,dark:variant,[ ]-এ arbitrary value; build শুধু ব্যবহৃত class-এর CSS বানায়; v4-এ মান লেখা হয়@theme-এ, ফল থাকে আসল cascade layer-এ; class নাম কখনো জোড়া দিয়ে বানাবেন না। - daisyUI, shadcn/ui-এর মতো library Tailwind-এর ওপর component দেয়; Pico.css classless, Open Props শুধু design token; ছোট সাইটে framework ছাড়া সাধারণ CSS-ও পুরোপুরি বৈধ পছন্দ।
- বেছে নিন নকশা, প্রজেক্টের আকার, দল আর বাকি প্রযুক্তি দেখে — আর মনে রাখুন, প্রতিটি framework class শেষ পর্যন্ত সাধারণ CSS; ভুল ধরা আর AI-এর কোড যাচাই হয় CSS-জ্ঞান দিয়েই।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৫২ · HTML-CSS আর JavaScript-এর মিলন — DOM, template আর Web Componentsপরবর্তী পর্বframework ছাড়াই নিজের component বানানোর ব্রাউজার-নিজস্ব পথ।
- পর্ব ৪৬ · CSS architecture — BEM, utility class আর বড় প্রজেক্টে গোছানো CSSঝালিয়ে নিনutility বনাম অর্থভিত্তিক নামের বিতর্কের ভিত্তি।
- পর্ব ৫০ · Sass আর PostCSS — CSS-এর সহকারী টুলঝালিয়ে নিনBootstrap কাস্টমাইজ আর build ধাপের পেছনের টুল।
- HTML ও CSS · কোর্স হোম৫৯টি পর্বপুরো কোর্সের রোডম্যাপ — কোন পর্ব কখন।
- JavaScript · Framework-এর জগৎপাশের ট্র্যাকReact, Vue-এর মতো component framework — যেখানে Tailwind সবচেয়ে বেশি ব্যবহৃত।
- JavaScript · npm আর build টুলপাশের ট্র্যাকTailwind বা Sass build চালাতে যে npm আর টুল লাগে।