সরাসরি পর্বে যান
পর্ব ৪৭ · ৫৯-এর মধ্যে · মডিউল ৭

DevTools দিয়ে HTML-CSS debugging

Debugging HTML & CSS with DevTools — a Method, Styles & Computed, Overlays, Rendering, Coverage and Common Layout Bugs

Taught in Bangla, this lesson teaches a six-step debugging method, then the Elements and Styles panes with forced states, struck-through rules, warnings and inactive CSS, the Computed tab, layout overlays, fonts and accessibility panes, Changes, Rendering emulation and device toolbar, Network, Coverage, Performance and Lighthouse, special Firefox tools, the outline-everything trick and fixes for six common layout bugs.

এই পর্বে যা শিখবেন

  • যেকোনো HTML-CSS বাগ ধরার ছয় ধাপের একটি নিয়মিত পদ্ধতি, আর সেটি এই কোর্সের প্রিভিউর ভেতরেই কীভাবে চালাবেন
  • Elements আর Styles প্যানের গভীর ব্যবহার — জীবন্ত HTML বদল, state জোর করে আনা, কাটা দাগ, সতর্কচিহ্ন আর inactive CSS-এর অর্থ, color picker-এর contrast আর box model editor
  • Computed, Layout, Fonts আর Accessibility প্যান — শেষ মান, overlay, আসল ফন্ট আর accessible name যাচাই
  • Changes, Rendering, device toolbar, Network, Coverage, Performance আর Lighthouse — কখন কোনটি খুলবেন
  • Firefox-এর বিশেষ টুল, “সব কিছুতে outline” কৌশল আর ছয়টি প্রচলিত লেআউট-বাগের কারণ ও সমাধান

১ · Debugging মানে অনুমান নয় — ছয় ধাপের পদ্ধতি

রুমানা নারায়ণগঞ্জ থেকে অনলাইনে শাড়ি বিক্রি করেন। নিজের দোকানের ওয়েবসাইট নিজেই বানিয়েছেন। একদিন এক ক্রেতা জানালেন, “আপু, ফোনে আপনার পাতা ডানে-বাঁয়ে নড়ে, লেখা কেটে যায়।” রুমানা AI-কে জিজ্ঞেস করলেন। উত্তর এলো: body-তে overflow-x: hidden দিন। নড়াচড়া থামল। কিন্তু এক সপ্তাহ পরে দেখলেন, ওপরের আটকে থাকা মেনুটি আর আটকে থাকছে না, আর একটি অফার ব্যানারের ডান পাশ কাটা পড়ে আছে — কেউ খেয়ালই করেনি।

আসলে সমস্যাটি সারেনি, শুধু চোখের আড়ালে গেছে। ব্যানারের একটি width ভুল ছিল, সেটিই পাতাকে চওড়া করছিল। এই পর্বের মূল কথা এখানেই: debugging মানে ভুলের আসল কারণ খুঁজে বের করা, আর সেটি হয় একটি পদ্ধতি মেনে — অনুমানে নয়। সেই পদ্ধতির প্রধান হাতিয়ার হলো ব্রাউজারের DevTools, যার সাথে প্রথম পরিচয় হয়েছিল পর্ব ০২-এ (কাজের টুল — VS Code, ব্রাউজার আর DevTools). এবার সেটির গভীরে যাব।

ঝড়ের রাতে পুরো বাড়ি অন্ধকার হলে ভালো বিদ্যুৎ-মিস্ত্রি সব তার খুলে নতুন করে লাগান না। তিনি আগে দেখেন — শুধু এই বাড়ি, না পুরো পাড়া? তারপর মেইন সুইচ, তারপর একেকটি সার্কিট। যেটি বন্ধ করলে সমস্যা থামে, সমস্যা সেখানেই। CSS-এর বাগেও তাই: আগে সমস্যার জায়গা ছোট করে আনুন, তারপর ঠিক সেখানে হাত দিন।

নিচের ডায়াগ্রামে রুমানার বাগটি নিয়েই ছয়টি ধাপ দেখুন। “পরে” চাপুন:

  1. আবার ঘটানreproduceকখন, কোথায়
  2. আলাদা করুনisolateছোট করুন
  3. দেখুনinspectDevTools
  4. অনুমানhypothesizeএকটি কারণ
  5. সারানfixএকটি বদল
  6. যাচাইverifyসব জায়গায়
  1. আবার ঘটান (reproduce). “মাঝে মাঝে হয়” বাগ ধরা যায় না। কোন মাপে, কোন ব্রাউজারে, কোন কাজের পরে হয় — খুঁজে বের করুন, যাতে চাইলেই বাগটি দেখাতে পারেন। এখানে device toolbar-এ 360px চওড়া করতেই প্রতিবার ঘটছে।
  2. আলাদা করুন (isolate). পাতা থেকে অংশ সরিয়ে সরিয়ে (DevTools-এ element বেছে Delete চাপলেই হয়) দেখুন কোনটি সরালে বাগ থামে। শেষে যে ছোট্ট কোডে বাগটি তখনো ঘটে, তাকে বলে minimal reproduction — সাহায্য চাইতে হলে এটিই পাঠাবেন।
  3. দেখুন (inspect). এবার অপরাধী element-টি বেছে Styles আর Computed পড়ুন। মাপগুলো সংখ্যায় দেখুন — “মনে হয় চওড়া” নয়, “ডান কিনারা 400px-এ, যেখানে জায়গা 360px”.
  4. একটি কারণ অনুমান করুন (hypothesize). সংখ্যা দেখে একটি নির্দিষ্ট, যাচাইযোগ্য কারণ বলুন: “100vw আর বাঁ margin মিলে চওড়া হচ্ছে।” একসাথে পাঁচটি সম্ভাব্য কারণ নয় — একটি।
  5. একটি বদল (fix). আগে DevTools-এই বদলে দেখুন (declaration-এর টিক তুলে বা মান বদলে)। কাজ করলে তবেই নিজের ফাইলে লিখুন। একসাথে একটির বেশি বদলালে বোঝা যায় না কোনটি আসলে সারাল।
  6. যাচাই (verify). যে মাপে বাগ ছিল শুধু সেখানে নয় — বড়-ছোট সব মাপে, অন্য ব্রাউজারে আর আসল ফোনে দেখুন, আর আগে যা ঠিক ছিল তা ভাঙেনি তো? overflow-x: hidden-এর মতো “চাপা দেওয়া” সমাধান এই ধাপেই ধরা পড়ে।
মূল ধারণা

বাগ সারানো মানে কারণ সরানো, লক্ষণ ঢাকা নয়। !important, z-index: 99999, overflow: hidden — এগুলো প্রায়ই লক্ষণ ঢাকে। কারণ জানা থাকলে এগুলোর দরকারই পড়ে না।

এই কোর্সের প্রিভিউর ভেতরে DevTools

এই পর্বের প্রতিটি লাইভ এডিটরে ইচ্ছে করে একটি করে বাগ রাখা হয়েছে। প্রিভিউটি আসলে পাতার ভেতরে বসানো আলাদা একটি ছোট পাতা (iframe). তবু DevTools সেখানে পুরোপুরি কাজ করে:

  1. প্রিভিউর ভেতরে যে জিনিসটি দেখতে চান, তার ওপর right-click করে Inspect (Chrome বা Edge-এ বাংলায় “পরিদর্শন করুন”) চাপুন। Elements প্যানেল সরাসরি সেই element-এ খুলবে — ওপরে দেখবেন <iframe> আর তার ভেতরে #document.
  2. Console-এ প্রিভিউর ভেতরের জিনিস নিয়ে কাজ করতে চাইলে Console-এর ওপরের “top” লেখা ড্রপডাউন থেকে iframe-টি বেছে নিন; নইলে আপনার কমান্ড বাইরের লেসন-পাতায় চলবে।
  3. এডিটরের কোড বদলালে প্রিভিউ নতুন করে তৈরি হয় — DevTools-এ করা পরীক্ষামূলক বদল তখন মুছে যায়। তাই আগে DevTools-এ খুঁজুন, কারণ বুঝলে তারপর এডিটরে সমাধান লিখুন।

ফোনে পড়ছেন? ফোনের ব্রাউজারে DevTools নেই। সমস্যা নেই — প্রতিটি এডিটরের নিচের ব্যাখ্যায় বাগের সমাধানও লেখা আছে, আর CSS-এর ভেতরে মন্তব্য করে রাখা “debug aid” লাইনগুলো চালু করে কিছুটা DevTools-এর কাজ এডিটরেই করা যায়।

২ · Elements প্যানেল — জীবন্ত HTML, জোর করে আনা state আর “সবকিছুতে outline”

Elements প্যানেলে যা দেখেন, তা আপনার HTML ফাইল নয় — ব্রাউজার ফাইলটি পড়ে যে DOM গাছ বানিয়েছে, সেটির এই মুহূর্তের অবস্থা। তাই এখানে বদলালে পাতাও সাথে সাথে বদলায়, কিন্তু ফাইলে কিছু লেখা হয় না। পর্ব ০২-এ লেখা বদলানো দেখেছেন; debugging-এ আরও কয়েকটি কাজ রোজ লাগে:

কী করতে চানকীভাবে (Chrome/Edge)debugging-এ কাজে লাগে যখন
attribute বদলানো বা যোগattribute-এ ডাবল-ক্লিক; নতুন যোগ করতে ট্যাগের নামে right-click → Add attributeclass, hidden, alt, aria-* বদলে ফল দেখতে
পুরো অংশ HTML হিসেবে লেখাelement বেছে F2 বা right-click → Edit as HTMLএকটি div-কে button করে দেখতে, বা ভেতরের কাঠামো বদলাতে
element সরানো বা লুকানোDelete চাপলে মুছে যায়; H চাপলে লুকায় (জায়গা থাকে)কোন অংশ বাগ ঘটাচ্ছে — আলাদা করার ধাপে
ক্রম বদলানোট্যাগ টেনে অন্য জায়গায় ফেলুনDOM-এর ক্রম বদলালে লেআউট বা Tab-এর ক্রম কী হয়
selector দিয়ে খোঁজাElements-এ Ctrl+F, তারপর .card > img লিখুনএকটি selector আসলে কয়টি element ধরে
Console-এ ধরাবেছে নেওয়া element Console-এ $0$0.getBoundingClientRect() দিয়ে আসল মাপ

Elements গাছে কিছু ট্যাগের পাশে ছোট ব্যাজ দেখবেন — flex, grid, scroll. এগুলোতে চাপলে পাতার ওপর সেই লেআউটের নকশা আঁকা হয় (অংশ ৫)। আর JavaScript কোনো element বদলে দিচ্ছে কি না জানতে, right-click → Break on → subtree modifications দিলে বদলের মুহূর্তে কোড থেমে যায় — DOM আর JavaScript-এর মিলন নিয়ে বিস্তারিত পর্ব ৫২-এ।

যে বাগ শুধু hover-এ দেখা যায় — :hov

সমস্যা: মেনুর ড্রপডাউন বা কার্ডের hover-রং শুধু মাউস ওপরে থাকলে দেখা যায়। কিন্তু মাউস নিয়ে DevTools-এ যেতেই hover চলে যায়, বাগও উধাও। সমাধান হলো state জোর করে আনা — force element state. Styles প্যানের ওপরের :hov বোতামে চাপলে কয়েকটি টিকবক্স আসে: :active, :hover, :focus, :visited, :focus-within, :focus-visible আর :target. টিক দিলে মাউস ছাড়াই element-টি সেই অবস্থায় আটকে থাকে। পাশের .cls বোতাম দিয়ে একটি class যোগ বা বন্ধ করা যায় — JavaScript যে .open বা .active class দেয়, তা হাতে দিয়ে দেখতে।

<style>
  body { font-family: sans-serif; }
  .card { width: 220px; padding: 12px; border: 1px solid #cbd5e1;
          border-radius: 10px; }
  .card h3 { margin: 0 0 4px; font-size: 17px; }
  .card button { font: inherit; padding: 6px 12px; border: 0;
                 border-radius: 6px; background: #2563eb; color: white; }
  .card:hover { background: #eff6ff; }
  .card:hover button { background: white; }   /* বাগ লুকিয়ে আছে এখানে */
</style>

<div class="card">
  <h3>মিনিকেট চাল — ৫ কেজি</h3>
  <p>৳৪২০</p>
  <button type="button">কার্টে নিন</button>
</div>

বাগ খুঁজুন: কার্ডের ওপর মাউস নিন — নীল “কার্টে নিন” বোতামটি সাদা পটভূমিতে সাদা লেখা হয়ে প্রায় অদৃশ্য। এবার কার্ডে right-click → Inspect, Elements-এ div.card বাছুন, :hov-এ :hover-এ টিক দিন, তারপর বোতামটি বাছুন: Styles-এ দেখবেন .card:hover button নিয়মটি background: white দিয়েছে, কিন্তু color: white আগের নিয়ম থেকেই রয়ে গেছে। চেষ্টা করুন: (১) সেই লাইনে color: #2563eb; যোগ করুন। (২) Tab দিয়ে বোতামে আসুন — hover-এর রং আসে না; .card:hover-এর পাশে .card:focus-within লিখলে কি-বোর্ডেও একই চেহারা পাওয়া যায় (পর্ব ৩৪)।

“সবকিছুতে outline” — চোখে বাক্স দেখার কৌশল

CSS-এ প্রতিটি element আসলে একটি বাক্স (পর্ব ১৯)। কিন্তু বাক্সের সীমানা চোখে দেখা যায় না, তাই কোনটি কতটা জায়গা নিচ্ছে বোঝা কঠিন। পুরোনো, কিন্তু আজও খুব কাজের কৌশল:

/* debug aid — কাজ শেষে অবশ্যই মুছবেন */
* { outline: 1px solid red; }

/* নেস্টিং-এর গভীরতা বোঝার জন্য: যত ভেতরে, তত গাঢ় */
* { background: rgb(255 0 0 / 0.06); }

এখানে border নয়, outline কেন? কারণ border box model-এর অংশ — প্রতিটি বাক্সে ২px করে বাড়লে লেআউট নিজেই বদলে যায়, আর আপনি যে বাগ খুঁজছেন সেটি সরে যেতে পারে। outline কোনো জায়গা নেয় না, শুধু ওপরে আঁকা হয়। নিচের এডিটরে এই কৌশলটি মন্তব্য করে রাখা আছে:

<style>
  body { font-family: sans-serif; }
  .wrap { max-width: 300px; border: 2px dashed #94a3b8; }
  .offer { width: 100%; padding: 16px; border: 4px solid #f59e0b;
           background: #fef3c7; }
  .offer h3 { margin: 0 0 4px; }
  .offer p { margin: 0; }

  /* debug aid — নিচের লাইনের মন্তব্য-চিহ্ন সরিয়ে দেখুন */
  /* * { outline: 1px solid red; } */
</style>

<div class="wrap">
  <div class="offer">
    <h3>পূজার অফার</h3>
    <p>সব শাড়িতে ১৫% ছাড়</p>
  </div>
  <p>ডেলিভারি সারা দেশে।</p>
</div>

বাগ খুঁজুন: হলুদ অফার-বাক্সটি ধূসর ডটেড বাক্সের ডান দিক দিয়ে প্রায় ৪০px বেরিয়ে গেছে। Inspect করে .offer বাছুন, Computed ট্যাবের ওপরের box model ছবিটি দেখুন: content 300 চওড়া, তার সাথে দুই পাশে 16 padding আর 4 border — মোট 340. কারণ width: 100% শুধু content-এর মাপ (content-box). চেষ্টা করুন: (১) debug aid লাইনটির /* আর */ মুছুন — সব বাক্সের সীমানা লাল দাগে দেখা যাবে। (২) .offer-এ box-sizing: border-box; যোগ করুন, অথবা width: 100% পুরোটাই মুছে দিন — block এমনিতেই পুরো চওড়া নেয়, padding ভেতরের দিকে বসে (box-sizing, পর্ব ১৯)।

৩ · Styles প্যান — কাটা দাগ, হলুদ ত্রিভুজ আর “এর কোনো প্রভাব নেই”

Elements-এ একটি element বাছলে পাশের Styles প্যান সেই element-এ লাগা সব CSS নিয়ম দেখায় — সবচেয়ে শক্তিশালী নিয়ম সবার ওপরে, তারপর ক্রমে দুর্বলগুলো, একদম নিচে উত্তরাধিকারে (inheritance) আসা নিয়ম আর ব্রাউজারের নিজের user agent stylesheet. প্রতিটি নিয়মের ডানে লেখা থাকে কোন ফাইলের কোন লাইন — চাপলে সেখানে নিয়ে যায়। এই প্যানের সংকেতগুলো পড়তে জানলেই অর্ধেক CSS-বাগ ধরা যায়:

কাটা দাগoverridden — অন্য নিয়ম জিতেছে
#menu a {                    style.css:2
    color: #1e3a8a;
}
.sale {                      style.css:5
    color: white;             ← হেরে গেছে, ওপরের নিয়মের কাছে
    background: #dc2626;
}
হলুদ ত্রিভুজinvalid — ব্রাউজার বোঝেনি
.btn {
    margin-left: 8 px;  ⚠      ← Invalid property value
    colr: red;  ⚠              ← Unknown property name
    border-radius: 6px;
}
ধূসর লেখা আর ⓘinactive — লেখা ঠিক, প্রভাব নেই
.box {
    justify-content: center;  ⓘ
}
ⓘ The display: block property prevents
  justify-content from having an effect.
  Try setting display: flex or grid.
টিকবক্সএকটি লাইন সাময়িক বন্ধ
.offer {
  ☑ width: 100%;
  ☐ padding: 16px;        ← টিক তুলে দিলে বন্ধ, আবার দিলে চালু
  ☑ border: 4px solid #f59e0b;
  + নতুন লাইন লিখতে বন্ধনীর শেষে ক্লিক
}
Color pickerরঙের বর্গে ক্লিক
color: ■ #94a3b8
┌──────────────────────────────┐
│ Contrast ratio   2.56  ⚠        │
│ AA   4.5   ✘    AAA   7.0   ✘ │
│ ─── এই রেখার ওপারের রং পাস ─── │
└──────────────────────────────┘
Box model editorসংখ্যায় ডাবল-ক্লিক করে বদলান
margin          –
 ┌ border        4 ────────────┐
 │ ┌ padding    16 ──────────┐ │
 │ │      300 × 58          │ │
 │ └─────────────────────────┘ │
 └─────────────────────────────┘
  1. কাটা দাগ = overridden. লাইনটি সঠিক, ব্রাউজার বুঝেছেও, কিন্তু একই element-এ একই property-র জন্য আরেকটি নিয়ম জিতেছে — বেশি specificity, পরে লেখা, বা !important (পর্ব ১৮-এর cascade). কে জিতল দেখতে ওপরের দিকে একই property খুঁজুন।
  2. হলুদ ত্রিভুজ = invalid. ব্রাউজার লাইনটিই বোঝেনি: property-র বানান ভুল (colr), নয়তো মান ভুল (8 px — সংখ্যা আর একক আলাদা করা যায় না)। CSS-এর নিয়ম হলো, না-বোঝা লাইন চুপচাপ বাদ দেওয়া; কোনো error কোথাও দেখায় না — এই ত্রিভুজই একমাত্র সংকেত।
  3. ধূসর আর ⓘ = inactive CSS. লাইনটি নির্ভুল, জিতেওছে, কিন্তু এই প্রসঙ্গে কোনো প্রভাব ফেলে না — যেমন flex container ছাড়া justify-content, inline element-এ width, static element-এ z-index. ⓘ-এর ওপর মাউস রাখলে ব্রাউজার কারণ ও সমাধান বলে দেয় (লেখাটি মোটামুটি এমনই, ব্রাউজারভেদে একটু আলাদা)।
  4. টিকবক্স দিয়ে বন্ধ-চালু. প্রতিটি লাইনের বাঁয়ে মাউস নিলে টিকবক্স আসে। একটি একটি করে বন্ধ করে দেখুন কোনটি সমস্যা ঘটাচ্ছে — আলাদা করার ধাপের সবচেয়ে দ্রুত উপায়। মানে ক্লিক করে বদলান; সংখ্যার মানে ↑/↓ চাপলে ১ করে, Shift-সহ ১০ করে বাড়ে-কমে।
  5. Color picker আর contrast. রঙের ছোট বর্গে চাপলে color picker খোলে। লেখার রঙের বেলায় সেখানে পটভূমির সাথে contrast ratio আর AA/AAA পাস-ফেল দেখায় (পর্ব ৪৫); একটি রেখা দেখায় কোন দিকে গেলে রং পাস করবে। #94a3b8 সাদায় মাত্র ২.৫৬:১ — সাধারণ লেখার জন্য ফেল।
  6. Box model editor. Styles-এর নিচে (আর Computed-এর ওপরে) element-এর বাক্সের ছবি: margin, border, padding, content-এর আসল মাপ। ছবির কোনো অংশে মাউস রাখলে পাতায় সেই অংশ রঙিন হয়; সংখ্যায় ডাবল-ক্লিক করে সরাসরি বদলানো যায়। “বাক্সটা এত বড় কেন” প্রশ্নের উত্তর প্রায়ই এখানেই।

এবার নিজে খুঁজে দেখুন। নিচের মেনুতে “অফার” বোতামটি লাল পটভূমিতে সাদা লেখা হওয়ার কথা, আর দুই বোতামের মাঝে একটু ফাঁক থাকার কথা। দুটির কোনোটিই ঠিকমতো হচ্ছে না:

body { font-family: sans-serif; }
#menu a { color: #1e3a8a; text-decoration: none; padding: 6px 10px; }
.btn { border: 1px solid #94a3b8; border-radius: 6px; }

/* “অফার” লাল-সাদা হওয়ার কথা */
.sale { color: white; background: #dc2626; }

/* বোতামের মাঝে ফাঁক */
.btn + .btn { margin-left: 8 px; }

বাগ খুঁজুন: “অফার” লাল হয়েছে, কিন্তু লেখা গাঢ় নীল — লালে নীল, পড়া কঠিন; আর বোতাম দুটি গায়ে গায়ে লাগানো। “অফার” Inspect করুন: .sale-এর color: white কাটা দাগে, কারণ #menu a-তে id আছে (specificity 1,0,1 বনাম 0,1,0). আর margin-left: 8 px-এর পাশে হলুদ ত্রিভুজ — invalid, তাই বাদ। চেষ্টা করুন: (১) 8 px-কে 8px করুন। (২) রঙের জন্য specificity-র যুদ্ধে না নেমে প্রথম নিয়মটির selector :where(#menu) a করুন — :where()-এর specificity শূন্য, তাই .sale জিতবে।

এখন inactive CSS. নিচে সবুজ “নতুন” ব্যাজটি 80px চওড়া আর 28px উঁচু হওয়ার কথা, আর ধূসর বাক্সের লেখা মাঝখানে থাকার কথা:

body { font-family: sans-serif; }
.badge { width: 80px; height: 28px; text-align: center;
         background: #16a34a; color: white; border-radius: 99px; }

.box  { justify-content: center; border: 1px solid #cbd5e1;
        padding: 8px; background: #f8fafc; }
.note { z-index: 5; margin: 0; }

বাগ খুঁজুন: ব্যাজটি লেখার মাপেই ছোট, আর বাক্সের লেখা বাঁ দিকে। Inspect করলে width, height, justify-content আর z-index — চারটিই ধূসর, পাশে ⓘ: span inline, তাই প্রস্থ-উচ্চতা মানে না; .box flex নয়; .note-এর position static. কোনো লাইন invalid নয়, কাটাও নয় — শুধু অকার্যকর। চেষ্টা করুন: (১) .badge-এ display: inline-block; দিন — মাপ বসবে; লেখা মাঝখানে আনতে line-height: 28px;. (২) .box-এ display: flex; দিন — ⓘ চলে যাবে, লেখা মাঝখানে।

৪ · Computed — শেষ পর্যন্ত কোন মান বসল, আর কে বসাল

Styles প্যান দেখায় কী কী লেখা আছে; Computed ট্যাব দেখায় শেষে কী হলো। দশটি নিয়ম মিলে একটি color ঠিক হলে Styles-এ দশটিই পাবেন, Computed-এ একটিই — যেটি সত্যিই পাতায় বসেছে, তার computed value (প্রায়ই px বা rgb()-তে রূপান্তরিত)। বড় প্রজেক্টে নিয়মের ভিড়ে হারিয়ে না গিয়ে উল্টো দিক থেকে খোঁজার পথ এটিই:

Computedশুধু যা বদলানো হয়েছে
Filter [ color      ]   ☐ Show all   ☐ Group
▸ color            rgb(30, 58, 138)
▸ display          inline
▸ padding-top      6px
▸ text-decoration  none
▾ colorকে কে চেষ্টা করেছিল
▾ color   rgb(30, 58, 138)
    #1e3a8a        #menu a              style.css:2  ← জিতেছে
    white          .sale                style.css:5
    -webkit-link   a:-webkit-any-link   user agent stylesheet
☑ Show allউত্তরাধিকার আর ডিফল্টও
  font-family      sans-serif      ← body থেকে উত্তরাধিকার
  font-size        16px            ← কেউ লেখেনি, ডিফল্ট
  line-height      normal
  margin-left      0px             ← “8 px” invalid ছিল, তাই 0
Rendered FontsComputed-এর একদম নিচে
Rendered Fonts
  Nirmala UI — Local file (4 glyphs)
← বাংলা অক্ষর এঁকেছে Windows-এর নিজের ফন্ট
  1. Filter-এ property-র নাম লিখুন. Computed ডিফল্টভাবে শুধু সেই property দেখায় যাতে কোনো নিয়ম কিছু লিখেছে। color লিখলেই তালিকা ছোট হয়ে যায়; ডানের মানটিই পাতায় বসা আসল মান।
  2. ত্রিভুজে চেপে খুলুন. এবার দেখা যায় এই property-র জন্য কোন কোন নিয়ম চেষ্টা করেছিল — বিজয়ী ওপরে, হেরে যাওয়াগুলো কাটা দাগে, সাথে ফাইল আর লাইন নম্বর। লিংকে চাপলে সরাসরি সেই নিয়মে চলে যাবেন। “এই লাল রং কোথা থেকে এলো?” প্রশ্নের দ্রুততম উত্তর।
  3. Show all. টিক দিলে এমন property-ও আসে যা কেউ লেখেনি — উত্তরাধিকারে বা ডিফল্ট মানে বসেছে। invalid লাইন বাদ পড়ায় কী মান বসেছে (margin-left: 0px), বা ফন্ট কোথা থেকে এলো — এখানে ধরা পড়ে। Group টিক দিলে layout, text, appearance — এভাবে ভাগ করে দেখায়।
  4. Rendered Fonts. Chrome বা Edge-এ Computed-এর একদম নিচে লেখা থাকে কোন ফন্ট দিয়ে আসলে কয়টি অক্ষর (glyph) আঁকা হয়েছে। CSS-এ যা-ই লিখুন, সত্যটা এখানে — বাংলার জন্য এটি সবচেয়ে কাজের যাচাই (অংশ ৫)।

Computed-এর ওপরের box model ছবি আর পাতায় element-এর ওপর মাউস রাখলে আসা রঙিন ছায়া (নীল content, সবুজ padding, হলুদ-কমলা margin) মিলিয়ে একটি বিখ্যাত বাগ ধরা যায় — margin collapse. নিচের সবুজ hero অংশের ওপরে একটি সাদা ফাঁক আছে, যা কেউ লেখেনি:

<style>
  body { margin: 0; font-family: sans-serif; background: #f1f5f9; }
  .hero { background: #0f766e; color: white; padding: 0 16px; }
  .hero h1 { margin-top: 40px; font-size: 22px; }
  .hero p { margin-bottom: 0; padding-bottom: 16px; }
</style>

<div class="hero">
  <h1>রাজশাহীর আম — সরাসরি বাগান থেকে</h1>
  <p>অর্ডার নেওয়া হচ্ছে জুন থেকে</p>
</div>
<p style="padding: 0 16px">সবুজ অংশের ওপরের ফাঁকটি কোথা থেকে এলো?</p>

বাগ খুঁজুন: সবুজ অংশটি প্রিভিউর একেবারে ওপর থেকে শুরু হওয়ার কথা, কিন্তু ওপরে ৪০px ধূসর ফাঁক। Inspect করে h1-এর ওপর মাউস রাখুন: কমলা margin-টি সবুজ বাক্সের বাইরে আঁকা। .hero-র ওপরে padding বা border নেই, তাই সন্তানের margin বাবা-মায়ের margin-এর সাথে মিশে বাইরে চলে গেছে। খেয়াল করুন, পাশের padding: 0 16px এটি আটকায় না — শুধু ওপর-নিচের padding আটকায়। চেষ্টা করুন: (১) .hero-তে display: flow-root; দিন — নতুন BFC, margin ভেতরে থাকে। (২) অথবা h1-এর margin-top মুছে .hero-তে padding-top: 24px দিন।

৫ · Layout, Fonts আর Accessibility — overlay, আসল ফন্ট আর accessible name

Layout প্যান — grid আর flex চোখে দেখা

Styles আর Computed-এর পাশেই Layout ট্যাব। সেখানে পাতার সব grid আর flex container-এর তালিকা থাকে, প্রতিটির পাশে টিকবক্স। টিক দিলে পাতার ওপর grid overlay আঁকা হয় — লাইন নম্বর, track-এর মাপ, area-র নাম (এগুলোও আলাদা টিকে চালু করা যায়)। Flex overlay-এ container-এর সীমানা, item-গুলোর জায়গা আর ফাঁকা জায়গা (free space) ডোরাকাটা দাগে দেখা যায়। Elements গাছে grid বা flex ব্যাজে চাপলেও একই কাজ হয়। Styles-এ display: flex-এর পাশের ছোট আইকনে চাপলে একটি flexbox editor খোলে — justify-content, align-items-এর মান ছবিতে চেপে বদলানো যায়।

overlay সবচেয়ে কাজে লাগে যখন কোনো item তার জায়গার চেয়ে বড় হয়ে বাইরে বেরিয়ে যায়। নিচের অর্ডার-সারিতে লম্বা লিংকটি “…” দিয়ে কেটে যাওয়ার কথা, আর দাম ডানে বাক্সের ভেতরে থাকার কথা:

body { font-family: sans-serif; }
.item { display: flex; gap: 10px; align-items: center; width: 300px;
        border: 2px solid #64748b; border-radius: 8px; padding: 8px; }
.pic  { flex: none; width: 40px; height: 40px; border-radius: 50%;
        background: #e0f2fe; display: grid; place-items: center; }
.text { flex: 1; }
.link { margin: 2px 0 0; color: #475569; font-size: 13px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.price { flex: none; font-weight: bold; }

বাগ খুঁজুন: লিংকটি কাটেনি, পুরোটা দেখাচ্ছে, আর দাম “৳১,২৫০” বাক্সের ডান সীমানার বাইরে চলে গেছে। Inspect করে .item-এর flex ব্যাজে চাপুন — overlay-তে দেখবেন .text item-টি container-এর চেয়েও চওড়া। কারণ flex item-এর ডিফল্ট min-width: auto: item তার ভেতরের সবচেয়ে লম্বা না-ভাঙা লেখার চেয়ে ছোট হতে রাজি নয় (automatic minimum size, পর্ব ২৫)। Styles-এ এটি কোথাও লেখা নেই, তাই চোখে পড়ে না। চেষ্টা করুন: .text-এ min-width: 0; যোগ করুন — লিংক “…” দিয়ে কাটবে, দাম ভেতরে ফিরবে। grid-এ একই সমস্যার সমাধান minmax(0, 1fr).

Fonts — বাংলা লেখা আসলে কোন ফন্টে আঁকা হলো

পর্ব ১৪ আর ২১-এ দেখেছেন, CSS-এ font-family: "Hind Siliguri", sans-serif লেখা মানে অনুরোধ, নিশ্চয়তা নয়। ফন্ট ফাইল না এলে, বা ফন্টে বাংলা অক্ষর না থাকলে ব্রাউজার চুপচাপ পরের ফন্টে চলে যায় — font fallback. পাতা দেখতে মোটামুটি ঠিকই লাগে, তাই ভুলটা চোখ এড়িয়ে যায়। ধরার উপায় একটাই: বাংলা লেখার একটি element বেছে Computed-এর নিচের Rendered Fonts দেখা।

Rendered Fonts-এ যা দেখলেনঅর্থকী করবেন
আপনার ওয়েব ফন্ট — Network resourceফন্ট ফাইল এসেছে, বাংলা অক্ষর সেটিতেই আঁকাকিছু না — ঠিক আছে
আপনার ফন্ট লাতিন অক্ষরে, কিন্তু বাংলা অক্ষর Nirmala UI বা Vrinda-তে (Windows)ফন্টে বাংলা নেই, বা unicode-range-এ বাংলা অংশ বাদবাংলা-সমর্থিত ফন্ট বা সঠিক subset নিন
শুধু সিস্টেম ফন্ট, ওয়েব ফন্টের নামই নেইফন্ট ফাইল আসেনিNetwork-এ Font ফিল্টারে 404 বা CORS খুঁজুন (অংশ ৭)
যুক্তাক্ষর ভেঙে হসন্ত দেখা যাচ্ছে, বা ফাঁকা বাক্সফন্টে দরকারি glyph বা shaping-এর নিয়ম নেই; বাক্স মানে tofuপূর্ণ OpenType বাংলা ফন্ট ব্যবহার করুন

Rendering ট্যাবের Disable local fonts চালু করলে কম্পিউটারে ইনস্টল করা ফন্টগুলো বাদ পড়ে — দেখা যায় যে ক্রেতার কম্পিউটারে ফন্টটি নেই, তার কাছে পাতা কেমন দেখায়। Firefox-এর Inspector-এ আলাদা একটি Fonts প্যান আছে, যা ব্যবহৃত ফন্ট দেখায় আর variable font-এর axis টেনে বদলাতে দেয়।

Accessibility প্যান — ব্রাউজার screen reader-কে কী বলছে

Elements-এর পাশের Accessibility ট্যাবে বেছে নেওয়া element-এর accessible name, role, আর ARIA attribute দেখায় — অর্থাৎ accessibility tree-তে element-টি কেমন। শুধু আইকন দেওয়া বোতামের name ফাঁকা থাকলে এখানেই ধরা পড়ে; name কোথা থেকে এলো (লেখা, aria-label, alt, label) সেটাও লেখা থাকে। CSS-এর জন্য বিশেষ জরুরি: display: none আর visibility: hidden জিনিস tree থেকে বাদ যায়, আর content দিয়ে বসানো লেখা অনেক সময় name-এ ঢুকে যায় — দুটোই এখানে যাচাই করা যায় (পর্ব ১২, ৪৫)।

৬ · Changes, Rendering আর device toolbar — বদল ধরে রাখা আর ব্রাউজারকে ভান করানো

Changes — DevTools-এ কী কী বদলেছেন

Styles-এ দশটি জিনিস বদলে অবশেষে পাতা ঠিক হলো — কিন্তু কোন দশটি? মনে রাখা কঠিন। Changes প্যানেল (DevTools-এ Ctrl+Shift+P চেপে Command Menu খুলে “Show Changes” লিখুন) সব CSS বদল ফাইল ধরে diff আকারে দেখায় — লাল লাইন মুছেছেন, সবুজ লাইন যোগ করেছেন — আর একটি বোতামে সব কপি করা যায়। Firefox-এর Inspector-এও একই নামে একটি প্যান আছে। নিজের প্রজেক্টে চাইলে আরও এক ধাপ: Sources প্যানেলের Workspace-এ প্রজেক্ট ফোল্ডারটি যোগ করলে DevTools-এর বদল সরাসরি ফাইলে সেভ হয়; আর Local Overrides দিয়ে অন্যের সাইটের CSS ফাইল নিজের কম্পিউটারে বদলে, রিলোডের পরও সেই বদল দেখা যায় — লাইভ সাইটে হাত না দিয়েই সমাধান পরীক্ষা।

Rendering ট্যাব — যা চোখে দেখা যায় না, তা দেখানো

Command Menu-তে “Show Rendering” লিখলে নিচের drawer-এ Rendering ট্যাব খোলে। এখানে দুই ধরনের সুবিধা: ব্রাউজারের আঁকার কাজ চোখে দেখানো, আর ব্যবহারকারীর সেটিং বা পরিস্থিতির ভান করা। এই কোর্সের প্রিভিউর ক্ষেত্রেও খাটে — অনুকরণ পুরো ট্যাবের ওপর কাজ করে, iframe-সহ:

Paint flashing Layout Shift Regions media: print prefers-color-scheme prefers-reduced-motion vision deficiency
  1. Paint flashing. যে অংশ নতুন করে আঁকা (paint) হয়, সেখানে সবুজ ঝলক। স্ক্রল করলে পুরো পাতা সবুজ হলে বুঝবেন অকারণে বেশি আঁকা হচ্ছে — jank-এর একটি কারণ। পাশে Layer borders দেখায় কোন অংশ আলাদা compositor layer-এ।
  2. Layout Shift Regions. লোডের সময় যেসব অংশ হঠাৎ সরে যায়, সেগুলো রঙিন হয় — ছবির মাপ না দেওয়া, দেরিতে আসা ফন্ট বা বিজ্ঞাপনের জায়গা না রাখা। এটিই layout shift, যার মাপ CLS (পর্ব ৪৯)।
  3. Emulate CSS media type: print. প্রিন্ট বোতাম না চেপেই প্রিন্টের CSS দিয়ে পাতা দেখা — Elements আর Styles সব স্বাভাবিকভাবে কাজ করে, তাই প্রিন্টের বাগ সাধারণ বাগের মতোই খোঁজা যায়। অনলাইন দোকানের রসিদ বা ভর্তির ফর্মের প্রিন্ট পরীক্ষায় কাজে লাগে।
  4. prefers-color-scheme. নিজের কম্পিউটারের থিম না বদলেই light বা dark-এর ভান। dark mode-এ লেখা সাদা হলো কিন্তু কোনো বাক্সের পটভূমি সাদাই রইল — এমন বাগ এভাবে মিনিটে ধরা যায় (পর্ব ৩৬)। একই জায়গায় prefers-contrast, forced-colors আর color-gamut-এর ভানও আছে।
  5. prefers-reduced-motion. reduce বেছে নিন, তারপর পাতা ঘুরে দেখুন — slider, parallax, বড় অ্যানিমেশন সত্যিই থামল বা কমল কি না (পর্ব ৩৯, ৪৫)।
  6. Emulate vision deficiencies. ঝাপসা দৃষ্টি, কম contrast-এর দৃষ্টি, কয়েক ধরনের বর্ণান্ধতা আর পুরো সাদা-কালো দৃষ্টির অনুকরণ। “লাল মানে ভুল, সবুজ মানে ঠিক” — শুধু রঙে অর্থ বোঝানো হয়েছে কি না, এক নজরে বোঝা যায়।

Device toolbar — মাপ, DPR আর স্পর্শ

পর্ব ০২ আর ৩০-এ device toolbar দেখেছেন। debugging-এ এর কয়েকটি লুকানো সুবিধা মনে রাখুন। ওপরের তিন-বিন্দু মেনু থেকে Show media queries চালু করলে প্রস্থের ওপর রঙিন দাগ আসে — প্রতিটি দাগ আপনার CSS-এর একটি media query-র breakpoint; চাপলে ঠিক সেই প্রস্থে চলে যায়। Add device pixel ratio দিয়ে DPR ১, ২ বা ৩ বেছে দেখা যায় srcset কোন ছবি নিচ্ছে (পর্ব ৩২)। device type “Mobile” করলে মাউসের তীর গোল স্পর্শ-বিন্দু হয়ে যায় আর (hover: none), (pointer: coarse) media query সত্য হয়। সাথে Network-এর গতি কমানো যায় (throttling). তবে এগুলো সবই অনুকরণ: আসল ফোনের ব্রাউজার, ফন্ট, প্রসেসরের গতি আর আঙুলের মাপ আলাদা — শেষ পরীক্ষা আসল ফোনে (Android ফোনকে USB দিয়ে যুক্ত করে কম্পিউটারের Chrome-এ chrome://inspect খুললে ফোনের পাতাও DevTools দিয়ে দেখা যায়)।

৭ · Network, Coverage, Performance আর Lighthouse — লোড আর গতির বাগ

কিছু বাগ CSS-এর লেখায় নয়, ফাইল আসার পথে। “আমার কম্পিউটারে তো ঠিক দেখায়!” — এই কথার পেছনে প্রায়ই থাকে না-আসা ফাইল বা পুরোনো ক্যাশ। Network প্যানেল খুলে পাতা রিলোড দিন, তারপর ফিল্টার বোতাম থেকে CSS, Font বা Img বেছে নিন:

  • লাল সারি, status 404: ফাইলটি পাওয়া যায়নি (404) — প্রায় সবসময় path বা নামের বানান, বড়-ছোট হাতের অক্ষর (Linux সার্ভারে Style.css আর style.css আলাদা) — পর্ব ০৫। CSS ফাইল না এলে পুরো পাতা সাদামাটা; ফন্ট না এলে নীরবে fallback.
  • Initiator কলাম: কোন ফাইল কোন ফাইলকে ডেকেছে। ছবিটি HTML থেকে, না CSS-এর background-image থেকে — ভুল path খুঁজতে কাজে লাগে, কারণ CSS-এর ভেতরের relative path CSS ফাইলের অবস্থান থেকে গোনা হয়, HTML-এর নয়।
  • অন্য ডোমেইনের ফন্ট আটকে গেছে: ফন্ট ফাইল অন্য origin থেকে আনতে হলে সার্ভারকে CORS-এর অনুমতি দিতে হয়; না দিলে Console-এ CORS error আর ফন্ট বাদ।
  • Size কলামে (memory cache) বা (disk cache): ফাইল সার্ভার থেকে নয়, ব্রাউজারের cache থেকে এসেছে। নতুন CSS আপলোড করেও পুরোনো চেহারা দেখলে এটাই কারণ। DevTools খোলা অবস্থায় Disable cache-এ টিক দিন; সাইটে স্থায়ী সমাধান হলো ফাইলের নামে version, যেমন style.css?v=2 (পর্ব ১৬)।
  • render-blocking: <head>-এর CSS ফাইল না আসা পর্যন্ত ব্রাউজার পাতা আঁকে না — তাই বড় বা ধীর CSS মানে দেরিতে প্রথম দৃশ্য (render-blocking). Network-এর waterfall-এ কোন ফাইল আগে এসে বাকিদের আটকে রাখছে, দেখা যায়; Lighthouse আর Performance প্যানেল এগুলো আলাদা করে চিহ্নিত করে।

Coverage — কতটা CSS আসলে ব্যবহার হলো

Command Menu-তে “Show Coverage” লিখে রিলোড বোতাম চাপলে Coverage প্রতিটি CSS আর JS ফাইলের পাশে একটি দাগ দেখায় — কতটা ব্যবহার হয়েছে আর কতটা হয়নি। ফাইলে চাপলে Sources-এ প্রতিটি নিয়মের পাশে সবুজ (ব্যবহৃত) বা লাল (অব্যবহৃত) দাগ। বড় framework পুরোটা এনে দশ ভাগের এক ভাগ ব্যবহার করলে এখানে স্পষ্ট হয়ে যায়। কিন্তু সাবধান: “অব্যবহৃত” মানে এই পাতায়, এই মুহূর্ত পর্যন্ত — hover, খোলা মেনু, অন্য মাপের media query বা অন্য পাতার নিয়মও লাল দেখায়। মুছে ফেলার আগে ভাবনার প্রশ্ন ৩ পড়ুন।

Performance — ঝাঁকুনি কোথা থেকে (পর্ব ৩৮-এর পুনরালোচনা)

অ্যানিমেশন বা স্ক্রল ঝাঁকুনি দিলে Performance প্যানেলে রেকর্ড করুন। পর্ব ৩৮-এ দেখেছিলেন: প্রতিটি ফ্রেমে style হিসাব → layout → paint → composite. রেকর্ডের আগে গিয়ার আইকন থেকে CPU ৪ বা ৬ গুণ ধীর করে দিন — কম দামের ফোনের মতো। রেকর্ডে বেগুনি Layout বা সবুজ Paint প্রতি ফ্রেমে বারবার দেখলে বুঝবেন width বা top-এর মতো property অ্যানিমেট হচ্ছে — transform আর opacity-তে বদলান। লাল কোণ-চিহ্ন দেওয়া লম্বা কাজ (long task) মানে মূল থ্রেড আটকে ছিল। আলাদা একটি সারিতে layout shift-গুলোও চিহ্নিত থাকে।

Lighthouse — এক ক্লিকে পরীক্ষা, কিন্তু শেষ কথা নয়

Lighthouse ট্যাবে Performance, Accessibility, Best Practices আর SEO বেছে “Analyze page load” চাপলে একটি রিপোর্ট আসে — প্রতিটি সমস্যার পাশে কোন element বা ফাইল দায়ী, আর কী করতে হবে। কিন্তু এটি একটি নির্দিষ্ট যন্ত্রে, নির্দিষ্ট গতির একটি পরীক্ষা; স্কোর প্রতিবার একটু ওঠানামা করে, আর যন্ত্র যা মাপতে পারে না (কি-বোর্ডে ব্যবহার, পড়ার ক্রম) তা দেখে না। বিস্তারিত পর্ব ৪৯-এ।

আরও গভীরে: Chrome DevTools নিজেই একটি ওয়েব অ্যাপ — HTML, CSS আর JavaScript-এ লেখা। এটি ব্রাউজারের ইঞ্জিনের সাথে কথা বলে Chrome DevTools Protocol (CDP) নামের একটি বার্তা-ব্যবস্থায়: “এই node-এর styles দাও”, “এই element-কে :hover অবস্থায় রাখো”, “print media-র ভান করো” — প্রতিটি বোতাম আসলে একটি CDP কমান্ড। Puppeteer আর Playwright-এর মতো স্বয়ংক্রিয় টেস্টিং টুল একই প্রোটোকল ব্যবহার করে, আর Lighthouse-ও পাতা পরীক্ষা করে এর মাধ্যমেই। সব ব্রাউজারে কাজ করে এমন একটি মানসম্মত বিকল্প হিসেবে W3C-তে WebDriver BiDi তৈরি হচ্ছে।

৮ · Firefox-এর বিশেষ টুল — যেখানে অন্যরা অনুসরণ করেছে

পর্ব ০২-এ বলা হয়েছিল, অন্তত দুটি ভিন্ন engine-এ পরীক্ষা করুন। debugging-এর জন্যও Firefox রাখার আলাদা কারণ আছে — CSS লেআউট বোঝার কয়েকটি টুলে Firefox বহুদিন এগিয়ে ছিল, আর কয়েকটি ধারণা Firefox-ই প্রথম এনেছে:

Grid Inspector

CSS Grid ব্রাউজারে আসার সময় থেকেই Firefox-এর grid overlay ছিল সবচেয়ে বিস্তারিত — লাইন নম্বর (ঋণাত্মকসহ), area-র নাম, একসাথে কয়েকটি grid আলাদা রঙে, আর Layout প্যানে grid-এর ছোট মানচিত্র। পরে Chrome-ও প্রায় একই সুবিধা যোগ করেছে।

Inspector → Layout

Flexbox Inspector

একটি flex item বাছলে Firefox দেখায় সেটি কীভাবে আজকের মাপে এলো: শুরুর মাপ (flex-basis), কতটা বাড়ল বা কমল, কোন min/max-এ আটকাল, আর চূড়ান্ত মাপ। “item-টি ছোট হচ্ছে না কেন” প্রশ্নের সবচেয়ে পরিষ্কার উত্তর।

Inspector → Layout → Flex Item

Inactive CSS

“এই property এখানে প্রভাব ফেলে না, কারণ…” — এই ধারণাটি Firefox ২০১৯ সালে চালু করে। ধূসর লেখা আর ⓘ-এর ব্যাখ্যা নতুনদের জন্য বিরাট সাহায্য ছিল; পরে Chrome ও Edge-ও একই ধরনের ইঙ্গিত যোগ করেছে।

Inspector → Rules

overflow ব্যাজ

Firefox-এর markup view-এ স্ক্রল হয় এমন element-এর পাশে scroll ব্যাজ দেখায়, আর ভেতরের যে element-টি বাইরে উপচে স্ক্রল তৈরি করছে, তার পাশে overflow ব্যাজ — অপরাধীকে সরাসরি দেখিয়ে দেয়।

Inspector → HTML

Firefox-এ নাম একটু আলাদা: Elements-এর বদলে Inspector, Styles-এর বদলে Rules, আর Responsive Design Mode খোলে Ctrl+Shift+M দিয়ে। Safari-র Web Inspector-ও grid ও flex overlay দেয়, আর iPhone-এর Safari-তে পাতা debug করার একমাত্র পথ — Mac-এর Safari-তে iPhone যুক্ত করে। বাগ একটি টুলে বোঝা না গেলে অন্যটিতে খুলুন।

৯ · প্রচলিত বাগ — চেনা মুখ, চেনা সমাধান

অভিজ্ঞ ফ্রন্ট-এন্ড ডেভেলপাররা বেশিরভাগ বাগ প্রথম দেখাতেই চেনেন, কারণ একই ছয়-সাতটি কারণ বারবার ফিরে আসে। নিচের টেবিলটি হাতের কাছে রাখুন:

লক্ষণআসল কারণDevTools-এ যেভাবে ধরবেনসমাধান
বাক্সের ওপরে অজানা ফাঁক; সন্তানের margin বাইরেmargin collapse — বাবা-মায়ের ওপর-নিচে padding/border নেইসন্তানের ওপর মাউস: কমলা margin বাবা-মায়ের বাইরেবাবা-মায়ে display: flow-root বা ওপরের padding; flex/grid-এর gap
ডেস্কটপে নিচে অকারণ horizontal scrollbarwidth: 100vw — vw-তে উল্লম্ব scrollbar-এর প্রস্থও ধরা (viewport units)Computed-এ width দেখুন; “outline” কৌশল; Firefox-এর overflow ব্যাজwidth: 100% বা width-ই না দেওয়া; পূর্ণ-প্রস্থ অংশে grid-এর full-bleed কৌশল
flex/grid-এ লম্বা লেখা বা URL পাশের জিনিস ঠেলে দেয়, ellipsis কাজ করে নাflex item-এর min-width: autoflex overlay-তে item container-এর চেয়ে চওড়া; Firefox-এর Flex Item মাপmin-width: 0; grid-এ minmax(0, 1fr); লেখায় overflow-wrap: anywhere
z-index: 9999 দিয়েও ড্রপডাউন নিচেকোনো পূর্বপুরুষ নিজেই একটি stacking context, যার z-index কমStyles-এ পূর্বপুরুষদের z-index, transform, opacity, filter খুঁজুন; Edge-এর 3D Viewstacking context-টির নিজের z-index বাড়ানো, বা কাঠামো বদল; অপ্রয়োজনীয় z-index সরানো
position: sticky আটকে থাকে নাtop দেওয়া নেই; কোনো পূর্বপুরুষে overflow: hidden/auto; বা বাবা-মা element-টির সমান উঁচুপূর্বপুরুষ ধরে ধরে overflow দেখুন; Elements-এ scroll ব্যাজtop: 0 দিন; overflow: hidden-এর বদলে overflow: clip; sticky-কে লম্বা পাত্রে রাখুন
ছবির নিচে কয়েক px সরু ফাঁকimg inline, লেখার baseline-এ বসে; নিচে অক্ষরের লেজের জায়গা ফাঁকা থাকেছবির পাত্রের উচ্চতা ছবির চেয়ে বেশি; box model-এ পার্থক্যimg { display: block; } বা vertical-align: middle

এর মধ্যে সবচেয়ে বেশি সময় নষ্ট করে z-index. পর্ব ২৪-এ দেখেছেন, z-index কাজ করে একই stacking context-এর ভেতরে; ভিন্ন context-এর সদস্যরা পরস্পরের সাথে তুলনাই হয় না — পুরো context একটি দল হিসেবে ওপরে-নিচে যায়। নিচের পাতায় সাদা ড্রপডাউনটি হলুদ ব্যানারের ওপরে থাকার কথা:

<style>
  body { margin: 0; font-family: sans-serif; min-height: 240px; }
  header { position: sticky; top: 0; z-index: 1;
           background: #1e293b; color: white; padding: 10px 16px; }
  .menu { position: relative; display: inline-block; }
  .drop { position: absolute; top: 100%; left: 0; z-index: 9999;
          width: 150px; margin: 6px 0 0; padding: 8px 12px 8px 28px;
          background: white; color: #111; border: 1px solid #94a3b8; }
  .banner { position: relative; z-index: 2; margin: 12px 0 0;
            padding: 24px 16px; background: #fde68a; }
</style>

<header>
  <div class="menu">ক্যাটাগরি ▾
    <ul class="drop"><li>শাড়ি</li><li>পাঞ্জাবি</li><li>থ্রি-পিস</li></ul>
  </div>
</header>
<p class="banner">শীতের অফার — সব চাদরে ২০% ছাড়</p>

বাগ খুঁজুন: ড্রপডাউনের তালিকার প্রায় পুরোটা হলুদ ব্যানারের নিচে ঢাকা পড়েছে, অথচ তার z-index ৯৯৯৯. Inspect করে ul.drop থেকে ওপরের দিকে পূর্বপুরুষ ধরে উঠুন: header-এ position: sticky আর z-index: 1 — এটি একটি stacking context. ৯৯৯৯ শুধু header-এর ভেতরে গোনা হয়; বাইরে পুরো header-এর মান ১, আর ব্যানারের ২. চেষ্টা করুন: (১) header-এর z-index ১০ করুন — ড্রপডাউন ওপরে আসবে, অথচ ৯৯৯৯-এর দরকারই ছিল না; .drop-এ z-index: 1 দিলেও চলবে। (২) অথবা .banner-এর z-index: 2 মুছে দিন — ব্যানারের z-index-এর কোনো প্রয়োজনই ছিল না।

Microsoft Edge-এর DevTools-এ 3D View নামে একটি প্যানেল আছে, যার Z-index অংশে পাতার stacking context-গুলো ত্রিমাত্রিক স্তূপের মতো আলাদা করে দেখা যায় — কোন দল কোন দলের ওপরে, এক নজরে।

শেষে একটি ছোট JavaScript “debug aid” — পাতার কোন element ডান দিকে পাতার বাইরে বেরিয়েছে, খুঁজে লাল দাগ দিয়ে দেয়। রুমানার বাগের মতো horizontal scroll-এর অপরাধী খুঁজতে নিজের পাতার Console-এ পেস্ট করেও চালানো যায়:

(function find() {
  if (!document.body.offsetWidth) return setTimeout(find, 50);
  var W = document.documentElement.clientWidth;   // দৃশ্যমান প্রস্থ
  var n = 0;
  document.querySelectorAll('body *').forEach(function (el) {
    var r = el.getBoundingClientRect();
    if (r.right > W + 1) {                          // ডানে বাইরে গেছে
      n++;
      el.style.outline = '2px solid red';
      console.log('বাইরে গেছে: <' + el.tagName.toLowerCase() + '> — ' +
                  Math.round(r.right - W) + 'px বেশি');
    }
  });
  console.log(n ? n + 'টি element পাওয়া গেল' : 'কোনো overflow নেই');
})();

ব্যানারটি 100vw চওড়া, তার ওপর ৩০px বাঁ margin — তাই দৃশ্যমান প্রস্থের চেয়ে অন্তত ৩০px বেশি; কোডটি তাকে লাল দাগে চিহ্নিত করে নিচে কতটা বেশি, লিখে দেয়। চেষ্টা করুন: (১) কোডের দ্বিতীয় লাইনের ঠিক পরে document.querySelector('div').style.width = 'auto'; যোগ করুন — এবার উত্তর আসবে “কোনো overflow নেই”। (২) নিজের যেকোনো পাতায় DevTools-এর Console-এ পুরো কোডটি পেস্ট করে Enter চাপুন।

পরীক্ষা ও ইন্টারভিউতে — বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে:

  • একটি CSS নিয়ম কাজ করছে না — কীভাবে খুঁজবেন? — Inspect করে Styles-এ দেখি লাইনটি কাটা (অন্য নিয়ম জিতেছে), হলুদ ত্রিভুজ (invalid), না ধূসর (inactive); তারপর Computed-এ শেষ মান আর উৎস।
  • z-index কাজ না করার দুটি কারণ? — element positioned নয় (flex/grid item ছাড়া), অথবা কোনো পূর্বপুরুষের stacking context-এ আটকা।
  • flex item ছোট হচ্ছে না কেন? — ডিফল্ট min-width: auto; সমাধান min-width: 0.
  • hover-এ দেখা যায় এমন জিনিস কীভাবে inspect করবেন? — Styles-এর :hov থেকে :hover force করে।
  • debug করতে border-এর বদলে outline কেন? — outline জায়গা নেয় না, তাই লেআউট বদলায় না।

১০ · AI-এর যুগে — AI-কে বাগ দেখানোর আগে নিজে দেখুন

“CSS কাজ করছে না, ঠিক করে দাও” লিখে পুরো ফাইল পেস্ট করলে AI অনুমান করে — কারণ সে আপনার পাতা দেখতে পায় না, Computed মান জানে না, কোন নিয়ম জিতেছে জানে না। ফলে উত্তর আসে লক্ষণ ঢাকার ধাঁচে। অথচ DevTools থেকে দুই লাইনের তথ্য দিলে একই AI প্রায়ই সঠিক কারণ বলে দেয়। নিয়ম তাই: আগে DevTools, তারপর AI — আর AI-এর উত্তরও DevTools-এ যাচাই।

CSS-বাগ সারাতে AI সাধারণত যেসব ভুল করে

AI-এর পরামর্শসমস্যাআসলে যা দেখা উচিত
!important লাগিয়ে দিনspecificity-র যুদ্ধ আরও বাড়ে; পরে আরেকটি !important লাগেComputed-এ কোন নিয়ম জিতছে, কেন; :where() বা @layer (পর্ব ১৮, ৩৫)
z-index: 99999stacking context-এর বাইরে সংখ্যা অর্থহীনপূর্বপুরুষদের stacking context
body { overflow-x: hidden }overflow লুকায়, কাটা অংশ থেকে যায়; অনেক সময় sticky ভেঙে দেয়কোন element বাইরে যাচ্ছে (outline কৌশল, overflow ব্যাজ)
আরেকটি div দিয়ে মুড়ে দিনdiv-soup বাড়ে, মূল কারণ থেকেই যায়Layout overlay-তে item-এর আসল মাপ
পুরোনো hack: -webkit- prefix, float, clearfixআজকের ব্রাউজারে অপ্রয়োজনীয় বা ক্ষতিকরMDN আর Can I use-এ বর্তমান সমর্থন
Bangla ফন্ট “ঠিক আছে” বলে ধরে নেওয়াfallback ফন্টে আঁকা হলেও AI জানে নাRendered Fonts

AI-কে প্রশ্ন করার আগে DevTools থেকে তথ্য তুলে নিন, তারপর নিচের কাঠামোয় লিখুন। শেষ শর্তটি খেয়াল করুন — “কারণ আগে, সমাধান পরে”, আর “চাপা দেওয়া” সমাধান নিষেধ:

তুমি একজন অভিজ্ঞ CSS ডেভেলপার। আমার পাতায় একটি বাগ আছে, DevTools থেকে যা পেয়েছি তা দিচ্ছি: লক্ষণ: 360px চওড়া পর্দায় "অর্ডার" সারির দাম বাক্সের ডানে বেরিয়ে যায়; লিংকে ellipsis হয় না। element: div.text (একটি flex item, container: div.item, display: flex, width: 300px) Computed: div.text-এর width 512px; min-width auto; flex 1 1 0% Styles-এ কোনো কাটা দাগ বা হলুদ ত্রিভুজ নেই। সংশ্লিষ্ট CSS: [এখানে শুধু .item, .text, .link-এর নিয়ম পেস্ট করো] ১. আগে সহজ বাংলায় মূল কারণ বলো — কোন CSS নিয়ম বা ডিফল্ট মান এর জন্য দায়ী। ২. তারপর সবচেয়ে ছোট সমাধানটি দাও (শুধু যে লাইন বদলাতে হবে)। ৩. !important, z-index বাড়ানো, overflow: hidden দিয়ে ঢেকে দেওয়া বা নতুন div যোগ — এগুলো চলবে না। ৪. বলো DevTools-এ কোন জিনিস দেখে আমি নিশ্চিত হব যে সমাধানটি কাজ করেছে।

AI-এর দেওয়া সমাধান হাতে পেলে — যাচাইয়ের চেকলিস্ট

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।

প্র ০১এলোমেলোভাবে CSS বদলে দেখাও তো একরকম পদ্ধতি — তাহলে ছয় ধাপের নিয়ম মানার দরকার কী?

এলোমেলো বদল কখনো কখনো কাজ করে, আর সেটাই এর বিপদ। একসাথে তিনটি লাইন বদলে বাগ চলে গেলে আপনি জানেন না কোনটি সারাল, বাকি দুটি নতুন কী ভাঙল, আর একই বাগ পরের মাসে ফিরে এলে আবার শূন্য থেকে শুরু। পদ্ধতির মূল শক্তি হলো প্রতিটি পরীক্ষা থেকে কিছু শেখা।

এই চিন্তা বিজ্ঞানের পদ্ধতি থেকেই আসা — পর্যবেক্ষণ, অনুমান (hypothesis), এমন পরীক্ষা যা অনুমানকে ভুল প্রমাণ করতে পারে, তারপর সিদ্ধান্ত। “একবারে একটি বদল” নিয়মটি আসলে নিয়ন্ত্রিত পরীক্ষার নিয়ম: একটি জিনিস বদলালে ফলের পার্থক্য সেই জিনিসেরই।

“আলাদা করার” ধাপের একটি শক্তিশালী রূপ হলো অর্ধেক-অর্ধেক খোঁজা (bisection). ২০০০ লাইনের CSS ফাইলে কোথাও বাগ — অর্ধেক নিয়ম বন্ধ করুন; বাগ গেলে অপরাধী সেই অর্ধেকে, নইলে বাকি অর্ধেকে। প্রতি ধাপে জায়গা অর্ধেক হয়, তাই এগারো-বারো ধাপেই একটি লাইনে পৌঁছানো যায়। Git-এর git bisect কমান্ড ঠিক এই কাজ করে কয়েকশো commit-এর মধ্যে কোনটিতে বাগ ঢুকল, তা খুঁজতে (পর্ব ৫৩)।

minimal reproduction বানানোরও দুটি বাড়তি লাভ। প্রথমত, বানাতে বানাতেই অনেক সময় কারণ চোখে পড়ে যায় — প্রোগ্রামারদের মধ্যে প্রচলিত “rubber duck debugging”-এর মতো, যেখানে একটি খেলনা হাঁসকে সমস্যাটি ধাপে ধাপে বোঝাতে গিয়েই উত্তর মেলে। দ্বিতীয়ত, ব্রাউজারের বাগ রিপোর্ট, Stack Overflow বা সহকর্মীর কাছে সাহায্য চাইতে গেলে ছোট, স্বয়ংসম্পূর্ণ উদাহরণই সবচেয়ে দ্রুত উত্তর আনে; Chromium বা Mozilla-র বাগ-ট্র্যাকারেও ছোট টেস্ট-কেস চাওয়া হয়।

মূল উপলব্ধি: পদ্ধতি ধীর মনে হয়, কিন্তু প্রতিটি ধাপ খোঁজার জায়গা ছোট করে — তাই শেষ পর্যন্ত এটিই দ্রুততম, আর প্রতিবার আপনি কিছু শিখে বেরোন।

প্র ০২ব্রাউজারের ভেতরেই debugger থাকা আজ স্বাভাবিক — কিন্তু এটি এলো কীভাবে, আর এর পেছনের নকশা কী শেখায়?

ওয়েবের প্রথম দিকে debugging মানে ছিল JavaScript-এ alert() বসিয়ে দেখা, আর CSS-এর ক্ষেত্রে রঙিন border দিয়ে অনুমান করা। পাতা “View Source” করা যেত, কিন্তু ব্রাউজার সেটি পড়ে কী বানাল, কোন CSS নিয়ম জিতল — দেখার উপায় ছিল না।

বড় পরিবর্তন আসে Firebug দিয়ে — Joe Hewitt-এর তৈরি একটি Firefox extension, ২০০৬ সালের দিকে প্রকাশিত। জীবন্ত DOM গাছ, প্রতিটি element-এর CSS নিয়ম, সরাসরি বদলানোর সুবিধা, নেটওয়ার্ক অনুরোধের তালিকা আর একটি console — আজকের DevTools-এর প্রায় পুরো ধারণাটিই এখানে একসাথে আসে। ফ্রন্ট-এন্ড ডেভেলপারদের কাছে এটি এতটাই অপরিহার্য হয়ে ওঠে যে ব্রাউজার-নির্মাতারা নিজেরাই এমন টুল বানাতে শুরু করেন: WebKit-এর Web Inspector (যা থেকে Chrome DevTools বেড়ে ওঠে), Internet Explorer-এর Developer Tools, পরে Firefox-এর নিজের DevTools. Firefox নিজের টুল পরিপক্ব করার পর Firebug-এর আলাদা উন্নয়ন বন্ধ হয়ে যায়, ২০১৭ সালের দিকে।

ব্রাউজারের ভেতরে টুল থাকার আসল সুবিধা হলো এটি ইঞ্জিনের ভেতরের তথ্য পায় — cascade-এর ফল, computed value, লেআউটের মাপ, accessibility tree, কোন ফন্টে কোন অক্ষর আঁকা। বাইরের কোনো টুল এগুলো অনুমানই করতে পারত। “inactive CSS”-এর মতো ইঙ্গিত সম্ভব হয় কারণ টুলটি জানে element-টির display আসলে কী।

নকশার দিক থেকে আরও আকর্ষণীয় হলো protocol-এর ভাবনা: ইন্টারফেস আর ইঞ্জিন আলাদা, মাঝখানে একটি বার্তা-ব্যবস্থা (CDP). তাই একই DevTools দিয়ে USB-তে যুক্ত ফোনের পাতা দেখা যায়, আর Puppeteer, Playwright বা Lighthouse মানুষের বদলে কোড দিয়ে একই কাজ করাতে পারে।

মূল উপলব্ধি: একটি ভালো টুল প্রায়ই পুরো পেশার কাজের ধরন বদলে দেয় — আর “ইন্টারফেস আর ইঞ্জিনের মাঝখানে একটি পরিষ্কার protocol” নকশাটি একটি টুলকে বহু টুলের ভিত্তিতে পরিণত করে।

প্র ০৩Coverage বলছে CSS-এর ৭০% অব্যবহৃত। সেই ৭০% মুছে দেওয়া কি ঠিক সিদ্ধান্ত?

প্রায় কখনোই সরাসরি নয়। Coverage যা মাপে তা খুব সংকীর্ণ: এই পাতায়, এখন পর্যন্ত, যে অবস্থাগুলো ঘটেছে — তাতে কোন নিয়ম কোনো element-এ মিলেছে। লাল দেখানো নিয়মের মধ্যে থাকতে পারে:

  • অন্য অবস্থা: :hover, :focus-visible, খোলা মেনু, ভুল দেখানো ফর্মের স্টাইল, dark mode, প্রিন্ট।
  • অন্য মাপ: ফোন বা বড় পর্দার media query — আপনি যে মাপে দেখছেন, তার বাইরের নিয়ম।
  • অন্য পাতা: একটি style.css পুরো সাইটের জন্য হলে চেকআউট পাতার নিয়ম হোম পাতায় অব্যবহৃত দেখাবেই।
  • JavaScript-এর যোগ করা class: .is-open, .toast-error — কোড চালু না হওয়া পর্যন্ত কোথাও নেই।

তাহলে Coverage কী কাজে লাগে? তিনটি জিনিস। প্রথমত, বড় অপচয় চেনা: পুরো একটি framework বা icon library এনে সামান্য ব্যবহার — এখানে বড় লাভ। দ্বিতীয়ত, critical CSS-এর চিন্তা: প্রথম দৃশ্যের জন্য যতটুকু লাগে, সেটুকু আগে, বাকিটা পরে — পর্ব ৪৯-এ এর কৌশল। তৃতীয়ত, পুরোনো, ভুলে যাওয়া নিয়ম খোঁজার একটি সূত্র — তবে মোছার আগে সাইট জুড়ে সেই class খুঁজে দেখতে হয়।

স্বয়ংক্রিয়ভাবে অব্যবহৃত CSS মুছে দেওয়ার টুলও আছে (PurgeCSS-এর মতো; Tailwind CSS-ও build-এর সময় শুধু ব্যবহৃত class রাখে — পর্ব ৫১)। এগুলো ফাইলের লেখায় class-এর নাম খোঁজে, তাই 'btn-' + color-এর মতো জোড়া দিয়ে বানানো নাম চিনতে না পেরে মুছে ফেলতে পারে — প্রোডাকশনে হঠাৎ একটি বোতামের রং উধাও।

মূল উপলব্ধি: প্রতিটি মাপকাঠি একটি নির্দিষ্ট প্রশ্নের উত্তর দেয়। Coverage-এর প্রশ্ন “এই মুহূর্তে কী লাগল”, “কী কখনোই লাগবে না” নয় — সংখ্যা পড়ার আগে বুঝুন সংখ্যাটি কী মাপছে।

প্র ০৪Lighthouse-এ সব ১০০ এসেছে। তাহলে কি পাতাটি দ্রুত আর সবার জন্য ব্যবহারযোগ্য — কাজ শেষ?

না। Lighthouse একটি ল্যাব পরীক্ষা: আপনার কম্পিউটারে, একটি নির্দিষ্ট অনুকরণ করা ফোনের মাপে, কৃত্রিমভাবে ধীর করা নেটওয়ার্ক আর CPU-তে, একবার পাতা লোড করে মাপা। এতে তিনটি সীমা আছে।

১. ল্যাব বনাম মাঠ: আসল ব্যবহারকারীরা নানা ফোনে, নানা নেটওয়ার্কে পাতা খোলেন — ঢাকার ফাইবার সংযোগ আর গ্রামের দুর্বল মোবাইল ডেটা এক নয়। Google আসল Chrome ব্যবহারকারীদের থেকে (যাঁরা অনুমতি দিয়েছেন) পাওয়া মাপ জমা করে Chrome UX Report-এ; PageSpeed Insights সেই “field data” আর Lighthouse-এর “lab data” পাশাপাশি দেখায়। দুটি প্রায়ই মেলে না। সার্চ র‍্যাংকিংয়ে Core Web Vitals-এর মূল্যায়ন হয় মাঠের তথ্য দিয়ে।

২. শুধু লোড: সাধারণ Lighthouse রিপোর্ট পাতা খোলার মুহূর্ত মাপে। কিন্তু বোতাম চাপার পর সাড়া কত দ্রুত (INP), স্ক্রলের সময় ঝাঁকুনি — ব্যবহার করতে করতে যা ঘটে, তা মূল রিপোর্টে আসে না; এর জন্য Performance প্যানেলে রেকর্ড বা আসল ব্যবহারকারীর মাপ দরকার।

৩. যন্ত্র যা মাপতে পারে না: Accessibility স্কোর ভেতরে axe-core-এর মতো নিয়ম চালায় — contrast, নামহীন বোতাম, ভুল ARIA. কিন্তু alt লেখাটি অর্থবহ কি না, কি-বোর্ডে পুরো কেনাকাটা করা যায় কি না, focus ঢাকা পড়ে কি না — এগুলো মানুষকেই পরীক্ষা করতে হয়। অ্যাক্সেসিবিলিটি বিশেষজ্ঞরা প্রায়ই মনে করিয়ে দেন, স্বয়ংক্রিয় পরীক্ষা সব সমস্যার একটি অংশই ধরতে পারে।

মূল উপলব্ধি: Lighthouse একটি ভালো স্বাস্থ্য-পরীক্ষা, রোগমুক্তির সনদ নয়। স্কোরকে লক্ষ্য বানালে মানুষ স্কোরের জন্য কাজ করে, ব্যবহারকারীর জন্য নয় — সংখ্যা হলো প্রশ্ন খোঁজার সূত্র।

প্র ০৫DevTools-এ ফোনের মাপ, dark mode, বর্ণান্ধতা — সবই অনুকরণ করা যায়। তাহলে আসল ফোন আর আসল মানুষ দিয়ে পরীক্ষার দরকার কেন?

কারণ অনুকরণ শুধু সেটুকুই বদলায়, যা DevTools-কে বলা হয়েছে; বাকি সব আপনার কম্পিউটারের মতোই থাকে।

  • ইঞ্জিন একই থাকে: device toolbar-এ “iPhone” বেছে নিলেও পাতা চলে আপনার কম্পিউটারের Chrome-এর Blink ইঞ্জিনে। iPhone-এর সব ব্রাউজার Apple-এর WebKit ব্যবহার করে আসছে; Safari-র নিজস্ব আচরণ বা বাগ এতে ধরা পড়ে না।
  • ফন্ট একই থাকে: Windows-এ বাংলা লেখা fallback-এ Nirmala UI-তে আঁকা হলে device toolbar-এও তাই — অথচ ক্রেতার Android ফোনে Noto Sans Bengali, iPhone-এ অন্য ফন্ট। প্রতিটি বাংলা ফন্টের প্রস্থ ও উচ্চতা আলাদা, তাই একটি শিরোনাম কম্পিউটারে এক লাইনে ধরলেও ফোনে দুই লাইনে ভাঙতে পারে। ওয়েব ফন্ট ব্যবহার করলে এই পার্থক্য কমে — আর Rendered Fonts দিয়ে নিশ্চিত হওয়া যায় যে সেটিই আঁকছে।
  • হাত আর চোখ: মাউসের ক্লিক আঙুলের স্পর্শ নয় — বুড়ো আঙুলে ছোট বোতাম চাপা, রোদে স্ক্রিন পড়া, এক হাতে ফোন ধরা। বর্ণান্ধতার অনুকরণ রঙের পার্থক্য দেখায়, কিন্তু একজন screen reader ব্যবহারকারী বা কম দৃষ্টির মানুষ আসলে কীভাবে পাতা চালান, তা দেখায় না।

তাই পেশাদার দলগুলো স্তরে স্তরে পরীক্ষা করে: দ্রুত চক্রে DevTools-এর অনুকরণ, তারপর কয়েকটি আসল ফোন (USB-তে যুক্ত করে Chrome-এর chrome://inspect বা Mac-এর Safari দিয়ে সেই ফোনের পাতাই DevTools-এ দেখা যায়), দরকারে অনলাইন device-lab সেবা, আর সম্ভব হলে আসল ব্যবহারকারীদের নিয়ে ছোট usability পরীক্ষা। বাংলাদেশের বাজারের জন্য অন্তত একটি সাশ্রয়ী দামের Android ফোনে পরীক্ষা খুবই কাজের।

মূল উপলব্ধি: অনুকরণ প্রশ্ন খুঁজতে দ্রুত, উত্তর নিশ্চিত করতে আসল জিনিস। যেটি অনুকরণ করছেন, সেটির কোন অংশ আসলে বদলাচ্ছে না — সেটা জানা থাকলেই টুলটি ঠিকভাবে ব্যবহার করা যায়।

অনুশীলন

বেশিরভাগ কাজ DevTools খুলে দেখার — কম্পিউটারের Chrome, Edge বা Firefox-এ করুন।

  1. এই পাতার বাংলা ফন্ট: এই লেসন-পাতার যেকোনো বাংলা অনুচ্ছেদে right-click → Inspect করুন। Computed ট্যাবের নিচে Rendered Fonts-এ কী দেখলেন? এবার Rendering ট্যাবে “Disable local fonts” চালু করে আবার দেখুন।

    ফন্ট ঠিকমতো এলে দেখবেন একটি ওয়েব ফন্ট (যেমন Anek Bangla) — Network resource, আর বাংলা অক্ষরের glyph সংখ্যা তার পাশেই। Font ফাইল আটকে গেলে (নেটওয়ার্ক ধীর, extension আটকেছে) Windows-এ Nirmala UI-র মতো সিস্টেম ফন্টের নাম আসবে। “Disable local fonts” চালু করলে কম্পিউটারে ইনস্টল করা ফন্ট বাদ পড়ে; ওয়েব ফন্ট তবুও থাকলে বুঝবেন পাতা সত্যিই নিজের ফন্ট নিয়ে আসছে। যদি কোনো অংশে ফন্টের নাম বদলে যায়, সেখানে CSS-এর font-family ভিন্ন বা ফন্টে সেই অক্ষর নেই।

  2. Coverage পড়ুন: আপনার পছন্দের যেকোনো বাংলা সংবাদ বা দোকানের সাইট খুলে Coverage চালান, পাতা রিলোড দিন। CSS ফাইলগুলোর কত শতাংশ অব্যবহৃত? এবার মেনু খুলুন, পাতা স্ক্রল করুন, প্রস্থ ছোট করুন — সংখ্যা কেমন বদলায়?

    সাধারণত অনেক বড় অংশ লাল দেখাবে — বিশেষ করে framework ব্যবহার করা সাইটে। মেনু খোলা, hover আর প্রস্থ বদলানোর সাথে সাথে অব্যবহৃত অংশ কিছুটা কমবে, কারণ নতুন অবস্থা আর media query-র নিয়ম কাজে লাগছে। এ থেকেই বোঝা যায় Coverage-এর লাল মানে “এখন পর্যন্ত লাগেনি”, “কখনো লাগবে না” নয় (ভাবনার প্রশ্ন ৩)। বড় লাল অংশ যদি একটি পুরো library-র হয়, সেটিই আসল উন্নতির জায়গা।

  3. Sticky কেন আটকায় না: নিচের কোডে .bar স্ক্রলের সময় ওপরে আটকে থাকার কথা, কিন্তু থাকে না। ছয় ধাপের পদ্ধতিতে কারণ খুঁজুন (দুটি কারণ আছে) — নিজের ফাইলে বা এই পর্বের যেকোনো HTML এডিটরে পেস্ট করে চালান।
    <div style="height: 160px; overflow: auto; border: 1px solid #999">
      <div class="card" style="overflow: hidden">
        <div class="bar" style="position: sticky; background: gold">মেনু</div>
        <p style="height: 600px">লম্বা লেখা …</p>
      </div>
    </div>

    কারণ ১: top দেওয়া নেই — sticky-কে বলতে হয় কোন দূরত্বে আটকাবে; না বললে এটি সাধারণ relative-এর মতো আচরণ করে। কারণ ২: .card-এ overflow: hidden — sticky তার সবচেয়ে কাছের scroll container-এর সাপেক্ষে আটকায়, আর overflow: hidden দেওয়া .card নিজেই একটি scroll container হয়ে গেছে, যেটি নিজে স্ক্রল করে না। তাই বাইরের বাক্স স্ক্রল করলেও sticky কিছু টের পায় না। সমাধান: .bar-এ top: 0 যোগ করুন, আর .card-এর overflow: hidden মুছুন বা overflow: clip করুন (clip কাটে, কিন্তু scroll container বানায় না)। DevTools-এ ধরার উপায়: .bar থেকে ওপরের দিকে প্রতিটি পূর্বপুরুষের Computed-এ overflow দেখা।

  4. AI-কে দুইভাবে জিজ্ঞেস করুন: অংশ ৫-এর ellipsis-বাগের CSS নিয়ে যেকোনো AI-কে প্রথমে শুধু লিখুন “ellipsis কাজ করছে না, ঠিক করো”। তারপর নতুন কথোপকথনে অংশ ১০-এর prompt-টি (Computed-এর তথ্যসহ) দিন। দুটি উত্তর তুলনা করুন।

    প্রথম ক্ষেত্রে AI প্রায়ই .link-এ display: block, width: 200px-এর মতো নির্দিষ্ট প্রস্থ, বা আবার white-space: nowrap; overflow: hidden; text-overflow: ellipsis লিখতে বলে — যা আগে থেকেই আছে। দ্বিতীয় ক্ষেত্রে “flex item, min-width auto, width 512px” তথ্য পেয়ে সাধারণত সরাসরি min-width: 0 বলে, আর কারণটিও ঠিক ব্যাখ্যা করে। শিক্ষা: AI-এর উত্তরের মান আপনার দেওয়া তথ্যের মানের ওপর নির্ভর করে, আর সেই তথ্য আসে DevTools থেকে। যেকোনো উত্তর DevTools-এ লিখে যাচাই না করে ফাইলে নেবেন না।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি CSS-বাগ সারানোর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. 🔁 বাগটি প্রতিবার ঘটানোর উপায় খুঁজে বের করা
  2. ✂️ অংশ সরিয়ে সরিয়ে দায়ী element আলাদা করা
  3. 🔍 Styles আর Computed-এ মাপ ও নিয়ম দেখা
  4. 💡 সংখ্যা দেখে একটি নির্দিষ্ট কারণ অনুমান করা
  5. 🔧 একটিমাত্র বদল — আগে DevTools-এ, তারপর ফাইলে
  6. ✅ সব মাপে, অন্য ব্রাউজারে আর আসল ফোনে যাচাই

DevTools-এর Styles প্যানে একটি CSS লাইন কাটা দাগ দেওয়া, কিন্তু পাশে কোনো সতর্কচিহ্ন নেই। এর অর্থ কী?

  • ব্রাউজার লাইনটির বানান বোঝেনি
  • একই property-র জন্য অন্য একটি নিয়ম জিতেছে
  • লাইনটি সঠিক, কিন্তু এই element-এ এর কোনো প্রভাব নেই
  • CSS ফাইলটি সার্ভার থেকে আসেনি

একটি মেনুর ড্রপডাউন শুধু মাউস ওপরে রাখলে দেখা যায়; inspect করতে মাউস সরালেই হারিয়ে যায়। সবচেয়ে ভালো উপায় কোনটি?

  • CSS থেকে :hover মুছে ড্রপডাউন সবসময় দেখানো
  • মাউস রেখে স্ক্রিনশট নিয়ে সেটি দেখে অনুমান করা
  • DevTools-এর :hov থেকে element-টির :hover অবস্থা force করা
  • device toolbar চালু করে ফোনের মাপে দেখা

একটি ড্রপডাউনে position: absolute; z-index: 9999 দেওয়া, তবু সেটি নিচের একটি ব্যানারের নিচে ঢাকা পড়ে। সবচেয়ে সম্ভাব্য কারণ কী?

  • কোনো পূর্বপুরুষ নিজেই একটি stacking context, যার z-index ব্যানারের চেয়ে কম
  • z-index-এর সর্বোচ্চ মান ৯৯৯৯-এর কম
  • absolute element-এ z-index কাজ করে না
  • ব্যানারটি HTML-এ পরে এসেছে, তাই সবসময় ওপরে থাকবে

একটি flex সারির ভেতরের লেখায় white-space: nowrap; overflow: hidden; text-overflow: ellipsis দেওয়া, তবু লেখা কাটে না আর পাশের দাম সারির বাইরে চলে যায়। কোন একটি লাইন যোগ করলে সমাধান হবে?

  • লেখার element-এ আবার text-overflow: ellipsis
  • flex container-এ flex-wrap: wrap
  • flex container-এ overflow: hidden
  • লেখা ধারণকারী flex item-এ min-width: 0

CSS-এ বাক্সগুলোর সীমানা চোখে দেখতে debugging-এর সময় * { border: 1px solid red }-এর বদলে * { outline: 1px solid red } লেখা ভালো কেন?

  • outline-এর রং বেশি উজ্জ্বল দেখায়
  • outline কোনো জায়গা নেয় না, তাই লেআউট বদলায় না
  • border পুরোনো ব্রাউজারে কাজ করে না
  • outline শুধু DevTools খোলা থাকলে দেখা যায়

DevTools-এর Coverage প্যানেল দেখাচ্ছে একটি সাইটের style.css-এর ৬৫% অব্যবহৃত। সবচেয়ে সঠিক সিদ্ধান্ত কোনটি?

  • লাল দেখানো সব নিয়ম সাথে সাথে মুছে দেওয়া
  • Coverage-এর সংখ্যা অর্থহীন, তাই উপেক্ষা করা
  • অন্য অবস্থা, মাপ ও পাতাগুলোতে ব্যবহার যাচাই করে তারপর সিদ্ধান্ত নেওয়া
  • পুরো CSS JavaScript দিয়ে লোড করা

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. Debugging-এর ছয় ধাপ: আবার ঘটান → আলাদা করুন → দেখুন → অনুমান → একটি বদল → যাচাই; কারণ সরান, লক্ষণ ঢাকবেন না।
  2. Styles-এ কাটা দাগ = অন্য নিয়ম জিতেছে, হলুদ ত্রিভুজ = invalid, ধূসর ও ⓘ = inactive; hover-এর বাগে :hov.
  3. Computed বলে শেষ মান আর কে বসাল; Layout-এর overlay, Rendered Fonts (বাংলার fallback) আর Accessibility প্যান বাকিটা।
  4. Rendering-এ print, dark mode, reduced motion আর বর্ণান্ধতার ভান; লোডের সমস্যায় Network, Coverage, Performance আর Lighthouse — কিন্তু শেষ পরীক্ষা আসল ফোনে।
  5. চেনা বাগ: margin collapse, 100vw, min-width: auto, stacking context, sticky, ছবির নিচে ফাঁক — আর debug করতে * { outline: 1px solid red }.

পরের পর্বে: নিজের ব্রাউজারে বাগ ধরতে শিখলেন। কিন্তু অন্যের ব্রাউজারে যদি একটি নতুন CSS ফিচার না-ই থাকে? Can I use, Baseline, @supports আর progressive enhancement দিয়ে সব ব্রাউজারে নির্ভরযোগ্য পাতা।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান