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

ওয়েব পাতার তিন স্তর — HTML, CSS আর JavaScript কে কী করে

The Web Mental Model — HTML Structure, CSS Presentation, JavaScript Behaviour

Taught in Bangla, this lesson builds a mental model of a web page as three layers: HTML for structure, CSS for presentation and JavaScript for behaviour. It walks through what happens after you type a URL, how scripts load with defer, async and type=module, progressive enhancement, client versus server code, and using DevTools to see each layer.

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

  • একটি ওয়েব পাতায় HTML, CSS আর JavaScript-এর আলাদা আলাদা দায়িত্ব
  • ঠিকানা লিখে Enter চাপার পর থেকে পর্দায় ছবি আসা পর্যন্ত ব্রাউজার কী কী করে
  • HTML থেকে DOM tree কীভাবে তৈরি হয়, আর একটি ক্লিক কীভাবে পাতা বদলায়
  • Script পাতায় আনার উপায় — defer, async, type="module" — আর কোনটি কখন
  • কোন কোড ব্রাউজারে চলে, কোনটি সার্ভারে — আর AI-এর লেখা front-end কোড যাচাইয়ের চেকলিস্ট

১ · একটি পাতা, তিনটি স্তর

ধরুন আপনি একটি অনলাইন দোকানে জামদানি শাড়ি খুঁজছেন। পাতায় একটি ছবি, শাড়ির নাম, দাম আর একটি সবুজ বোতাম — “কার্টে যোগ করুন”। বোতাম চাপলেই উপরের কোণে কার্টের সংখ্যা ০ থেকে ১ হয়ে গেল। খুব সাধারণ দৃশ্য। কিন্তু এই এক টুকরো পাতার পেছনে তিনটি আলাদা ভাষা তিনটি আলাদা কাজ করছে।

HTML — কাঠামো ও অর্থ

“এটি একটি শিরোনাম, এটি দাম, এটি একটি বোতাম।” জিনিসগুলো কী, আর কোনটি কার ভেতরে — সেটা বলে HTML.

কী আছে

CSS — চেহারা

“বোতামটি সবুজ, কোণগুলো গোল, দাম বড় অক্ষরে, মোবাইলে কার্ড পুরো চওড়া।” দেখতে কেমন — সেটা বলে CSS.

কেমন দেখায়

JavaScript — আচরণ

“বোতাম চাপলে সংখ্যা এক বাড়াও, সার্ভারকে জানাও, বোতামের লেখা বদলাও।” কিছু করলে কী ঘটে — সেটা বলে JavaScript.

কী ঘটে

ঢাকার একটি রিকশার কথা ভাবুন। লোহার ফ্রেম, সিট, চাকা, হুড — এগুলো কাঠামো; এগুলো ছাড়া রিকশাই হয় না (HTML). তারপর রঙিন রিকশা-চিত্র, ঝালর, প্লাস্টিকের ফুল — রিকশা দেখতে কেমন, তা ঠিক করে এগুলো (CSS). আর প্যাডেল, চেইন, ব্রেক, ঘণ্টি — চালক কিছু করলে রিকশা সাড়া দেয় এগুলো দিয়ে (JavaScript). রং বদলাতে ফ্রেম ভাঙতে হয় না, আর ঘণ্টি বদলালে রিকশা-চিত্র নষ্ট হয় না। এই আলাদা থাকাটাই আসল শক্তি।

এই ভাগটা কোনো নিছক নিয়ম নয়, একটি প্রকৌশল-সিদ্ধান্ত। একই HTML-এর ওপর আলাদা CSS বসিয়ে মোবাইল, ডেস্কটপ আর প্রিন্টের জন্য আলাদা চেহারা দেওয়া যায়। দৃষ্টিপ্রতিবন্ধী একজন ব্যবহারকারীর screen reader CSS দেখে না, HTML-এর অর্থ পড়ে শোনায়। Google-এর মতো search engine-ও প্রধানত HTML-এর কাঠামো থেকে বোঝে পাতাটা কী নিয়ে। আর JavaScript কোনো কারণে লোড না হলেও (ধীর নেটওয়ার্ক, পুরোনো ফোন) পাতার লেখাটুকু অন্তত পড়া যায়।

মূল ধারণা

কাঠামো (structure), চেহারা (presentation) আর আচরণ (behaviour) — তিনটি আলাদা দায়িত্ব, তিনটি আলাদা ভাষা। এই ভাগকে বলে separation of concerns. পুরো front-end কাজের ভিত্তি এটাই — React বা Vue-র মতো framework শিখলেও (পর্ব ৫৪) ভেতরে এই তিনটিই কাজ করে।

তিনটি স্তর একসাথে জন্মায়নি। ১৯৮৯ সালে CERN-এ Tim Berners-Lee World Wide Web-এর প্রস্তাব দেন, আর ১৯৯০–৯১ সালে প্রথম ওয়েব সার্ভার, প্রথম ব্রাউজার আর HTML তৈরি হয়। ১৯৯৪ সালে CERN-এই Håkon Wium Lie CSS-এর প্রস্তাব দেন; প্রথম CSS standard আসে ১৯৯৬ সালে। আর ১৯৯৫ সালে Netscape-এ Brendan Eich মাত্র কয়েক দিনে JavaScript-এর প্রথম রূপ বানান। অর্থাৎ ওয়েব শুরু হয়েছিল শুধু লেখা আর link দিয়ে; চেহারা আর আচরণ পরে আলাদা স্তর হিসেবে যোগ হয়েছে।

২ · URL লিখে Enter চাপলে কী ঘটে

“ঠিকানা লিখলাম, পাতা এলো” — বাইরে থেকে এটুকুই দেখা যায়। ভেতরে এক সেকেন্ডেরও কম সময়ে অনেকগুলো ধাপ পার হয়। এই পথটা চেনা থাকলে পরে বুঝবেন পাতা ধীর কেন, ছবি আগে আসে কেন, আর JavaScript-এর একটি লাইন কেন পুরো পাতা আটকে দিতে পারে। নিচে “পরে” চেপে ধাপে ধাপে দেখুন (সহজ করে দেখানো; আসল ব্রাউজার অনেক ধাপ একসাথে করে):

  1. DNSনাম → IP
  2. অনুরোধGET
  3. উত্তরHTML
  4. DOMparse
  5. CSSOMCSS rules
  6. Render treeDOM+CSSOM
  7. Layoutx, y, w, h
  8. Paintpixels
ঠিকানা ভাঙা ও DNSনাম থেকে নম্বর
https://shop.example.com/saree
scheme = https   host = shop.example.com   path = /saree

DNS: shop.example.com → 203.0.113.25
HTTP অনুরোধসংযোগ, তারপর চাওয়া
TCP/QUIC সংযোগ + TLS (https-এর তালা)
GET /saree HTTP/1.1
Host: shop.example.com
Accept: text/html
HTTP উত্তরসার্ভার পাঠাল লেখা — শুধু লেখা
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

<!doctype html>
<html lang="bn"> … </html>
HTML parse → DOMপড়তে পড়তে আরও ফাইল চাওয়া
<link rel="stylesheet" href="style.css">   → নতুন অনুরোধ
<script src="app.js" defer></script>  → নতুন অনুরোধ
<img src="saree.jpg" alt="…">          → নতুন অনুরোধ
ট্যাগগুলো object হয়ে গাছে বসছে …
CSS parse → CSSOMকোন নিয়ম কার ওপর
.card       { border: 1px solid #ddd; padding: 16px; }
.card h2    { font-size: 20px; }
.price      { color: #b91c1c; font-weight: 700; }
.hidden     { display: none; }
Render treeশুধু যা দেখা যাবে
body
└─ article.card   { border, padding }
   ├─ h2          { 20px }
   ├─ p.price     { লাল, মোটা }
   └─ button
head, script, display:none — বাদ
Layoutপ্রতিটি বাক্সের মাপ ও জায়গা
article.card  x=16  y=72   w=328  h=412
h2            x=33  y=89   w=294  h=28
p.price       x=33  y=125  w=294  h=24
button        x=33  y=420  w=160  h=44
Paint ও compositeপর্দায় ছবি
১. প্রতিটি বাক্সের রং, লেখা, border, ছবি আঁকা (paint)
২. আলাদা স্তর (layer) জুড়ে চূড়ান্ত ছবি — প্রায়ই GPU দিয়ে (composite)
→ প্রথমবার কিছু দেখা গেল
  1. নাম থেকে নম্বর। কম্পিউটার নাম দিয়ে নয়, IP ঠিকানা দিয়ে একে অন্যকে খোঁজে। তাই ব্রাউজার আগে DNS-কে জিজ্ঞেস করে “shop.example.com কোন ঠিকানায়?” — ঠিক যেন ফোনবুকে নাম দেখে নম্বর বের করা। উত্তর আগে থেকে cache-এ থাকলে এই ধাপে প্রায় কোনো সময়ই লাগে না।
  2. সংযোগ আর অনুরোধ। সার্ভারের সাথে সংযোগ হয়, https হলে এনক্রিপশনের হাত মেলানোও (TLS) হয়। তারপর ব্রাউজার HTTP ভাষায় একটি অনুরোধ পাঠায়: “/saree পাতাটি দাও।”
  3. উত্তর এলো — শুধু লেখা। সার্ভার পাঠায় status (200 OK মানে সফল, 404 মানে নেই) আর HTML লেখা। খেয়াল করুন, এখনো কোনো রং, কোনো ছবি নেই — শুধু অক্ষরের একটি স্রোত।
  4. HTML পড়ে গাছ বানানো। ব্রাউজারের parser লেখা পড়তে পড়তে প্রতিটি ট্যাগকে একটি object বানিয়ে গাছে বসায় — এটাই DOM. পড়ার পথে CSS, JavaScript আর ছবির ঠিকানা পেলে সেগুলো আনতে আলাদা অনুরোধ পাঠায়। সাধারণ <script> পেলে পড়া থামিয়ে আগে সেটি নামায় ও চালায় — অংশ ৬-এ এর সমাধান দেখব।
  5. CSS পড়ে নিয়মের তালিকা। CSS ফাইলও parse হয়ে আরেকটি গঠন হয় — CSSOM. CSS না আসা পর্যন্ত ব্রাউজার সাধারণত কিছু আঁকে না; নইলে আগে সাদামাটা পাতা দেখিয়ে হঠাৎ বদলে যেত।
  6. দুটি মিলিয়ে render tree. DOM থেকে শুধু যেগুলো দেখা যাবে, সেগুলো নিয়ে প্রতিটির ওপর মানানসই CSS নিয়ম বসানো হয় — এটি render tree. <head>, <script> আর display: none দেওয়া জিনিস এখানে থাকে না।
  7. Layout — কে কোথায়, কত বড়। পর্দার চওড়া জেনে ব্রাউজার প্রতিটি বাক্সের সঠিক অবস্থান ও মাপ হিসাব করে। একে layout (বা reflow) বলে। ফোন ঘোরালে চওড়া বদলায়, তাই layout আবার হয়।
  8. Paint আর composite. এবার আসল আঁকা — রং, লেখা, ছবি পিক্সেলে বসে (paint). আলাদা আলাদা স্তর থাকলে শেষে সেগুলো জোড়া লাগে (composite). পর্দায় প্রথম কিছু দেখা গেল। পরে JavaScript DOM বদলালে ধাপ ৬–৮-এর কিছু অংশ আবার ঘটে।
DNS → অনুরোধ → HTML → DOM + CSSOM → render tree → layout → paint → composite

এই ধাপগুলো মুখস্থের বিষয় নয়, চিন্তার মানচিত্র। পাতা ধীর হলে প্রশ্ন করুন: সময়টা কোথায় যাচ্ছে — নেটওয়ার্কে (ধাপ ১–৩), না পড়া ও হিসাবে (৪–৭), না আঁকায় (৮)? পর্ব ৫৩-এ DevTools দিয়ে ঠিক এটাই মাপব।

৩ · HTML — জিনিসটা “কী”, সেটা বলা

HTML-এর মূল একক হলো element. একটি element সাধারণত শুরুর ট্যাগ, ভেতরের জিনিস আর শেষের ট্যাগ নিয়ে তৈরি — যেমন <h2>জামদানি শাড়ি</h2>. শুরুর ট্যাগের ভেতরে বাড়তি তথ্য দেওয়া যায় attribute দিয়ে — class="card", href="/cart", alt="লাল জামদানি". Element-এর ভেতরে element বসে, তাই পুরো পাতাটা আসলে একটি নেস্টেড কাঠামো।

আমাদের দোকানের পণ্য-কার্ডের HTML দেখতে এমন হতে পারে:

<article class="card">
  <img src="saree.jpg" alt="লাল-সোনালি জামদানি শাড়ি" width="300" height="300">
  <h2>জামদানি শাড়ি</h2>
  <p class="price">৳ ৪,৫০০</p>
  <button type="button" class="add-btn">কার্টে যোগ করুন</button>
</article>

খেয়াল করুন, এখানে রঙের কোনো কথা নেই, “ক্লিক করলে কী হবে” তারও কোনো কথা নেই। আছে শুধু অর্থ: এটি একটি স্বাধীন লেখা-খণ্ড (article), একটি ছবি যার বর্ণনা আছে, একটি শিরোনাম, একটি অনুচ্ছেদ আর একটি বোতাম।

Semantic HTML — সঠিক ট্যাগ, সঠিক অর্থ

সব কিছুই <div> দিয়ে বানানো যায়, আর CSS দিয়ে দেখতে হুবহু এক রকমও করা যায়। তাহলে আলাদা ট্যাগের দরকার কী? কারণ ব্রাউজার, screen reader আর search engine ট্যাগের নাম থেকেই অর্থ বোঝে। অর্থপূর্ণ ট্যাগ ব্যবহারকে বলে semantic HTML.

ট্যাগঅর্থবিনা খরচে যা পাওয়া যায়
<header>, <footer>পাতা বা অংশের মাথা ও পাscreen reader-এ “banner”, “contentinfo” হিসেবে ঘোষণা
<nav>মূল link-এর তালিকাএক চাপে মেনুতে লাফ দেওয়া যায়
<main>পাতার মূল বিষয়“সরাসরি মূল লেখায় যান” সুবিধা
<button>চাপলে কিছু ঘটেTab দিয়ে পৌঁছানো, Enter/Space-এ চাপা, “button” বলে ঘোষণা
<a href>অন্য পাতায় যাওয়ানতুন ট্যাবে খোলা, ঠিকানা কপি, search engine-এর অনুসরণ
<form>, <label>, <input>তথ্য নেওয়াlabel চাপলে ঘরে কার্সর, Enter-এ জমা, ফোনে ঠিক কিবোর্ড

<div class="btn">কার্টে যোগ করুন</div> মাউসে চমৎকার কাজ করতে পারে। কিন্তু কিবোর্ড ব্যবহারকারী Tab চেপে সেখানে পৌঁছাতেই পারবেন না, আর screen reader সেটিকে বোতাম বলে চিনবে না। এটা ঠিক করতে tabindex, role, কিবোর্ড event — অনেক কিছু হাতে লিখতে হয়। অথচ <button> লিখলেই সব বিনা খরচে মেলে। এই সবার-জন্য-ব্যবহারযোগ্যতাকে বলে accessibility (সংক্ষেপে a11y).

HTML লেখা থেকে DOM tree

ব্রাউজার HTML ফাইলটা লেখা হিসেবে রেখে দেয় না। পড়তে পড়তে প্রতিটি element-কে একটি object বানায় — প্রতিটির নিজস্ব property (যেমন className, textContent) আর method থাকে — এবং কে কার ভেতরে, সেই অনুযায়ী একটি গাছে সাজায়। এই গাছের প্রতিটি বিন্দুকে বলে node. নিচে বাঁ দিকের HTML থেকে ডান দিকে গাছ কীভাবে বড় হয়, দেখুন:

1<!doctype html>2<html lang="bn">3<head><title>দোকান</title></head>4<body>5  <article class="card">6    <h2>জামদানি শাড়ি</h2>7    <button>কার্টে যোগ করুন</button>8  </article>9</body>10</html>
DOMশিকড়
document
DOMপ্রথম element
document
└─ html  lang="bn"
DOMhead শাখা
document
└─ html
   └─ head
      └─ title
         └─ "দোকান"  (text node)
DOMbody শাখা
document
└─ html
   ├─ head
   │  └─ title ─ "দোকান"
   └─ body
DOMকার্ড আর শিরোনাম
document
└─ html
   ├─ head ─ title ─ "দোকান"
   └─ body
      └─ article.card
         └─ h2 ─ "জামদানি শাড়ি"
DOMসম্পূর্ণ গাছ
document
└─ html
   ├─ head ─ title ─ "দোকান"
   └─ body
      └─ article.card
         ├─ h2 ─ "জামদানি শাড়ি"
         └─ button ─ "কার্টে যোগ করুন"
  1. শিকড় — document. পড়া শুরুর আগেই একটি document object তৈরি থাকে। পুরো গাছের মাথা এটাই, আর JavaScript-এ আপনি একে document নামেই পাবেন। <!doctype html> লাইনটি ব্রাউজারকে বলে “আধুনিক নিয়মে পড়ো”।
  2. <html> হলো প্রথম element. এর lang="bn" attribute-টিও object-এর সাথে জমা থাকে। Screen reader এটা দেখেই বাংলা উচ্চারণ বেছে নেয়।
  3. head শাখা। head-এর ভেতরে title, আর তার ভেতরে “দোকান” লেখাটি। লেখাও আলাদা একটি node — text node. অর্থাৎ DOM-এ শুধু element নয়, লেখাও গাছের পাতা হিসেবে থাকে।
  4. body শাখা শুরু। body হলো head-এর ভাই (sibling) — দুজনেই html-এর সন্তান। পর্দায় যা দেখবেন, সব এই শাখার নিচে।
  5. কার্ড আর তার শিরোনাম। article-এর class="card" থাকায় গাছে একে article.card লেখা হলো — CSS selector-এর মতোই। এর ভেতরে h2 আর তার লেখা।
  6. গাছ সম্পূর্ণ। button যোগ হলো, শেষের ট্যাগগুলো শাখা বন্ধ করল। এখন JavaScript বলতে পারে document.querySelector('.card button') — “কার্ডের ভেতরের বোতামটি দাও” — এবং সেই object-এর লেখা বা class বদলাতে পারে। (আসল DOM-এ লাইনের মাঝের ফাঁকা জায়গাও ছোট ছোট text node হয়; সরল রাখতে এখানে দেখাইনি।)
মূল ধারণা

JavaScript কখনো HTML ফাইল বদলায় না — বদলায় মেমরিতে থাকা DOM. তাই DevTools-এর Elements ট্যাবে যা দেখেন, সেটা আসল ফাইল নয়, এই মুহূর্তের জীবন্ত গাছ। পাতা reload করলে আবার ফাইল থেকে নতুন গাছ তৈরি হয়। DOM-এর পুরো গল্প — খোঁজা, বদলানো, নতুন node বানানো — পর্ব ৩৭-এ।

৪ · CSS — দেখতে “কেমন”, সেটা বলা

CSS-এর প্রতিটি নিয়মের দুটি অংশ: কাকে (selector) আর কী রকম (property: মান)। Selector-ই HTML আর CSS-এর মধ্যে সংযোগ:

/* ১. type selector — সব বোতাম */
button { font: inherit; padding: 8px 16px; border-radius: 8px; }

/* ২. class selector — নির্দিষ্ট দলের জিনিস */
.card  { border: 1px solid #ddd; padding: 16px; max-width: 320px; }
.price { color: #b91c1c; font-weight: 700; }

/* ৩. অবস্থা বোঝানো class — JavaScript যোগ বা বাদ দেবে */
.card.in-cart { border-color: #16a34a; background: #f0fdf4; }

Cascade — একাধিক নিয়ম মিললে কে জেতে

CSS-এর পুরো নাম Cascading Style Sheets. একই element-এর ওপর কয়েকটি নিয়ম মিলতে পারে — ব্রাউজারের নিজের নিয়ম, আপনার নিয়ম, কখনো ব্যবহারকারীর নিজের সেটিং। কোনটি জিতবে, তা ঠিক করার নিয়মকে বলে cascade. সরল করে তিনটি ধাপে ভাবুন:

  1. উৎস ও গুরুত্ব: আপনার stylesheet ব্রাউজারের ডিফল্টকে হারায়; !important সাধারণ নিয়মকে হারায় (কিন্তু এটা শেষ অস্ত্র, অভ্যাস নয়)।
  2. নির্দিষ্টতা (specificity): id selector (#cart) > class selector (.card) > ট্যাগ selector (button). .card.in-cart-এ দুটি class, তাই শুধু .card-এর চেয়ে বেশি নির্দিষ্ট।
  3. ক্রম: সব সমান হলে যে নিয়ম পরে লেখা, সে জেতে।

Box model — প্রতিটি element একটি বাক্স

পর্দায় প্রতিটি element আসলে একটি আয়তক্ষেত্র। Layout ধাপে ব্রাউজার এই বাক্সগুলোর মাপই হিসাব করে। বাক্সের চারটি স্তর — ভেতর থেকে বাইরে — মিলে box model:

┌──────────── margin (বাইরের ফাঁকা জায়গা) ────────────┐
│  ┌───────── border (সীমারেখা) ──────────────────┐   │
│  │  ┌────── padding (ভেতরের ফাঁকা) ──────────┐  │   │
│  │  │         content (লেখা / ছবি)          │  │   │
│  │  └───────────────────────────────────────┘  │   │
│  └─────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────┘

ডিফল্টে width শুধু content-এর মাপ; তার সাথে padding আর border যোগ হয়ে বাক্স বড় হয়ে যায় — নতুনদের লেআউট ভাঙার এক নম্বর কারণ। তাই প্রায় সব আধুনিক প্রজেক্টে শুরুতেই box-sizing: border-box লেখা হয়, যাতে width border পর্যন্ত পুরো বাক্সের মাপ বোঝায়।

Class — CSS আর JavaScript-এর মধ্যে সেতু

উপরের তৃতীয় নিয়মটি আবার দেখুন: .card.in-cart. এই class HTML-এ শুরুতে নেই। ব্যবহারকারী বোতাম চাপলে JavaScript শুধু বলবে card.classList.add('in-cart') — রং, border, background কী হবে তা CSS আগেই ঠিক করে রেখেছে। JavaScript “কী অবস্থা” জানায়, CSS ঠিক করে “সেই অবস্থায় দেখতে কেমন”। এতে ডিজাইনার JavaScript না ছুঁয়েই রং বদলাতে পারেন, আর প্রোগ্রামার CSS না ছুঁয়েই আচরণ বদলাতে পারেন।

৫ · JavaScript — কিছু করলে “কী ঘটে”, সেটা বলা

ব্রাউজারে JavaScript-এর কাজকে তিন ভাগে ভাবা যায়:

  • সাড়া দেওয়া: ক্লিক, টাইপ, স্ক্রল, ফর্ম জমা — এগুলো সবই event. JavaScript আগে থেকে বলে রাখে “এই event ঘটলে এই function চালাও” — একে বলে event listener.
  • পাতা বদলানো: DOM-এর লেখা, class, attribute বদলানো; নতুন element যোগ বা পুরোনো element সরানো।
  • সার্ভারের সাথে কথা বলা: পাতা reload না করেই তথ্য আনা বা পাঠানো — যেমন কার্টে যোগ হওয়ার খবর সার্ভারে জানানো (fetch, পর্ব ৩৫)।

একটি ক্লিকের পুরো যাত্রাটা ধাপে ধাপে দেখি। ব্যবহারকারী “কার্টে যোগ করুন” চাপলেন:

  1. ক্লিকpointerব্যবহারকারী
  2. Eventclickব্রাউজার
  3. Handler() => {…}JavaScript
  4. DOM বদলclassListJavaScript
  5. Re-renderpaintব্রাউজার
ব্রাউজারকোন বাক্সের ওপর চাপ পড়ল?
pointer at (112, 441)
layout-এর হিসাব থেকে খোঁজ: → button.add-btn
ব্রাউজারevent object তৈরি
{ type: "click", target: button.add-btn, clientX: 112, clientY: 441, … }
→ এই বোতামে কারা কান পেতে আছে?
app.jsআগে থেকে রেজিস্টার করা function চলছে
button.addEventListener('click', () => {
  count += 1;
  …
});
DOMদুটি জিনিস বদলাল
span#count     textContent: "0" → "1"
article.card   className:   "card" → "card in-cart"
ব্রাউজারপরের frame-এ
style আবার হিসাব → (দরকার হলে) layout → paint → composite
সবুজ border, কার্টে ১টি
  1. ব্যবহারকারী চাপলেন। ব্রাউজার জানে চাপটা পর্দার কোন বিন্দুতে। Layout ধাপে হিসাব করা বাক্সগুলো দেখে সে খুঁজে বের করে বিন্দুটি কোন element-এর ওপর — এখানে বোতামটি।
  2. Event তৈরি ও পাঠানো। ব্রাউজার একটি click event object বানায় — কী ঘটল, কোথায়, কোন element-এ। তারপর দেখে এই element (আর তার পূর্বপুরুষদের) ওপর কোনো listener আছে কি না। Event কীভাবে গাছ বেয়ে ওপরে ওঠে (bubbling), সেটা পর্ব ৩৮-এ।
  3. Handler চলে। আগে থেকে addEventListener দিয়ে রেজিস্টার করা function এখন চলে। ব্রাউজারের পাতায় JavaScript একটি মূল thread-এ চলে — handler চলার সময় পাতা অন্য কাজ করতে পারে না। তাই handler ছোট ও দ্রুত হওয়া চাই।
  4. DOM বদলায়। Handler কাউন্টারের লেখা বদলায় আর কার্ডে in-cart class যোগ করে। এখনো পর্দায় কিছু বদলায়নি — শুধু মেমরির গাছে বদল হয়েছে।
  5. ব্রাউজার আবার আঁকে। Handler শেষ হলে ব্রাউজার দেখে কী কী বদলেছে, নতুন CSS নিয়ম মেলায়, দরকার হলে layout আবার করে, তারপর paint আর composite. সাধারণ ৬০Hz পর্দায় এক frame মানে প্রায় ১৬ মিলিসেকেন্ড — এর মধ্যে কাজ শেষ হলে ব্যবহারকারীর কাছে সাড়াটা তাৎক্ষণিক লাগে।

এবার একই জিনিস আসল কোডে। নিচের কোডের ওপরে একটি ছোট পাতা (HTML + CSS) দেখাবে; JavaScript বোতামে listener বসাবে, তারপর দুবার button.click() ডেকে ব্যবহারকারীর ক্লিকের অনুকরণ করবে। চালানোর পর নিজেও বোতামটি চেপে দেখুন:

const card = document.querySelector('.card');
const button = document.querySelector('#add');
const countEl = document.querySelector('#count');
let count = 0;

button.addEventListener('click', () => {
  count += 1;
  countEl.textContent = count;           // লেখা বদলাও
  card.classList.add('in-cart');         // অবস্থা জানাও, চেহারা CSS-এর
  button.textContent = 'আরও একটি যোগ করুন';
  console.log(`ক্লিক → count = ${count}, class = "${card.className}"`);
});

console.log('শুরুতে:', countEl.textContent, card.className);
button.click();   // ব্যবহারকারীর ক্লিকের অনুকরণ
button.click();
console.log('বোতামের লেখা:', button.textContent);

আউটপুট চার লাইন: শুরুতে: 0 card, তারপর দুটি ক্লিকে count = 1 ও count = 2, দুবারই class = "card in-cart", শেষে বোতামের লেখা: আরও একটি যোগ করুন. তিনটি জিনিস খেয়াল করুন। (১) JavaScript প্রথমে querySelector দিয়ে DOM থেকে object খুঁজে নিয়েছে — CSS-এর মতোই selector দিয়ে। (২) সবুজ রঙের কোনো উল্লেখ JavaScript-এ নেই; সে শুধু class যোগ করেছে, রং দিয়েছে <style>-এর .card.in-cart নিয়ম। (৩) classList.add দ্বিতীয়বার একই class আর যোগ করে না — তাই class দুবারই একই। HTML ফাইল কোথাও বদলায়নি; বদলেছে শুধু DOM.

C/C++/Python/Java জানলে

Java-র Swing/JavaFX, Python-এর Tkinter বা C++-এর Qt-এ বোতাম, লেবেল সবই কোডে বানাতে হয়, আর কাঠামো-চেহারা-আচরণ প্রায়ই এক ফাইলে মিশে থাকে। ওয়েবে কাঠামো (HTML) আর চেহারা (CSS) আলাদা ঘোষণামূলক ভাষায় লেখা হয়; JavaScript শুধু আচরণ যোগ করে। তবে মূল ধারণা একই — event-driven প্রোগ্রাম: Swing-এর addActionListener আর JavaScript-এর addEventListener প্রায় যমজ। সার্ভারের দিকটা আপনার পরিচিত ভাষাতেও লেখা যায় — দেখুন Python কোর্সের ওয়েব ব্যাকএন্ড — FastAPI-র শুরু বা Java কোর্সের Spring Boot দিয়ে REST API. এগুলোর কোনোটি না জানলে বাক্সটি বাদ দিয়ে এগোতে পারেন।

৬ · JavaScript পাতায় আসে কীভাবে — script, defer, async, module

JavaScript পাতায় আনতে লাগে <script> ট্যাগ। কোড সরাসরি ট্যাগের ভেতরে লেখা যায় (inline), তবে প্রায় সবসময় আলাদা ফাইলে রেখে src দিয়ে আনা ভালো — ব্রাউজার ফাইলটা cache করে রাখতে পারে, আর HTML পরিষ্কার থাকে।

<head>
  <link rel="stylesheet" href="style.css">
  <!-- আধুনিক ডিফল্ট: HTML পড়া আটকায় না, পড়া শেষে ক্রম মেনে চলে -->
  <script src="app.js" defer></script>
  <!-- module: import/export ব্যবহার করা যায়, নিজে থেকেই defer-এর মতো -->
  <script type="module" src="main.js"></script>
  <!-- স্বাধীন ছোট script (যেমন পরিসংখ্যান): যখন নামবে তখনই চলবে -->
  <script src="analytics.js" async></script>
</head>

এই attribute-গুলোর পার্থক্য সময়ের ছবিতে সবচেয়ে ভালো বোঝা যায়। নিচে = মানে HTML পড়া চলছে, . মানে পড়া থেমে আছে, d মানে script নামছে (download), R মানে script চলছে (run):

<script src> — head-এ, কোনো attribute নেইparser-blocking
HTML    ====.........==========
app.js      ddddddRRR
            ↑ পড়া থামল — নামা ও চলা শেষ হওয়া পর্যন্ত
<script src> — body-র একদম শেষেপুরোনো সমাধান
HTML    ===================
app.js                     ddddddRRR
        পাতা আগে দেখা যায়, কিন্তু script দেরিতে শুরু
<script src async>নামলেই চলে
HTML    =========...=======
app.js      dddddRRR
        পাশাপাশি নামে; নামা শেষ হলেই চলে — ক্রমের নিশ্চয়তা নেই
<script src defer>পড়া শেষে, ক্রম মেনে
HTML    ===================
app.js      dddddd         RRR
                           ↑ HTML পড়া শেষ, DOMContentLoaded-এর ঠিক আগে
<script type="module" src>ডিফল্টেই defer
HTML    ===================
main.js     ddd            RRR
 └ cart.js     ddd   (import করা ফাইলও আগে নামে)
  1. সাধারণ <script src>, head-এ। Parser এটা পেলেই থেমে যায় — কারণ script হয়তো document.write দিয়ে HTML-ই বদলে দেবে, তাই আগে চালিয়ে দেখতে হয়। ধীর নেটওয়ার্কে ব্যবহারকারী এই সময় সাদা পাতা দেখেন। তার ওপর script তখন নিচের element খুঁজলে পায় না, কারণ সেগুলো এখনো DOM-এ ঢোকেনি — নতুনদের “null” error-এর খুব পরিচিত কারণ।
  2. Body-র একদম শেষে। বহু বছর এটাই ছিল প্রচলিত সমাধান: আগে সব HTML পড়া হোক, তারপর script. পাতা আগে দেখা যায়, আর script চলার সময় সব element তৈরি থাকে। অসুবিধা — script নামা শুরুই হয় দেরিতে। আধুনিক ব্রাউজার HTML-এ আগেভাগে চোখ বুলিয়ে কিছু ফাইল আগে নামাতে শুরু করে, তবু দেরি পুরোপুরি যায় না।
  3. async. Script পাশাপাশি নামে, HTML পড়া চলতে থাকে। কিন্তু নামা শেষ হওয়ামাত্র চলে — তখন পড়া একটু থামে। একাধিক async script থাকলে যেটা আগে নামবে সেটা আগে চলবে, ক্রমের ঠিক নেই। তাই এটা স্বাধীন script-এর জন্য (যেমন পরিসংখ্যান, বিজ্ঞাপন), যা অন্য script বা DOM-এর ওপর নির্ভর করে না।
  4. defer. পাশাপাশি নামে, কিন্তু চলে HTML পড়া শেষ হলে — আর লেখার ক্রম মেনেই। পুরো DOM তৈরি থাকে, পাতাও আটকায় না। নিজের অ্যাপের script-এর জন্য এটাই সাধারণ পছন্দ। মনে রাখুন, defer শুধু src থাকা script-এ কাজ করে।
  5. type="module". আধুনিক JavaScript module (পর্ব ৪৫)। ডিফল্টেই defer-এর মতো আচরণ করে, import করা ফাইলগুলোও আগেভাগে নামে, আর ভেতরের কোড নিজে থেকেই strict mode-এ চলে। নতুন প্রজেক্টে এটাই সবচেয়ে প্রচলিত।
উপায়HTML পড়া থামায়?কখন চলেক্রম ঠিক থাকে?
সাধারণ <script src>হ্যাঁপাওয়ামাত্রহ্যাঁ
asyncশুধু চলার সময়টুকুনামা শেষ হলেইনা
deferনাHTML পড়া শেষেহ্যাঁ
type="module"নাHTML পড়া শেষে (ডিফল্টে)হ্যাঁ

৭ · আগে পাতা কাজ করুক — progressive enhancement

তিন স্তর আলাদা রাখার সবচেয়ে বড় সুফল একটি দর্শনে: progressive enhancement. মূল কথা — আগে এমন HTML লিখুন যা একাই কাজ করে; তার ওপর CSS দিয়ে সুন্দর করুন; সবশেষে JavaScript দিয়ে অভিজ্ঞতা আরও ভালো করুন। JavaScript ব্যর্থ হলে পাতা ভেঙে পড়বে না, শুধু একটু কম আরামদায়ক হবে।

মেট্রো রেলের স্টেশনে চলন্ত সিঁড়ি (escalator) আছে, পাশে সাধারণ সিঁড়িও আছে। বিদ্যুৎ গেলে চলন্ত সিঁড়ি থেমে যায়, কিন্তু যাত্রীরা হেঁটেই প্ল্যাটফর্মে পৌঁছান। সাধারণ সিঁড়ি হলো HTML, চলন্ত সিঁড়ি JavaScript. শুধু চলন্ত সিঁড়ি বানালে লোডশেডিংয়ে পুরো স্টেশনই বন্ধ।

একটি বাস্তব উদাহরণ — বাংলাদেশি মোবাইল নম্বর নেওয়ার ফর্ম। HTML-এর <form> নিজেই সার্ভারে তথ্য পাঠাতে পারে; JavaScript না থাকলেও কাজ চলে। JavaScript যোগ করলে টাইপ করার সাথে সাথেই ভুল দেখানো যায় — সার্ভারে যাওয়ার আগেই। নিচের কোডে নম্বর যাচাইয়ের নিয়ম: ঐচ্ছিক +88/88, তারপর 01, তারপর ৩ থেকে ৯-এর একটি অঙ্ক, তারপর আরও ৮টি অঙ্ক। (/…/ চিহ্নের ভেতরের নিয়মকে বলে regular expression — পর্ব ৩০-এ শিখবেন; এখন শুধু ভূমিকাটা দেখুন।)

const input = document.querySelector('#phone');
const msg = document.querySelector('#msg');
const BD_MOBILE = /^(?:\+?88)?01[3-9]\d{8}$/;

function check() {
  const value = input.value.replace(/[\s-]/g, '');   // ফাঁকা ও ড্যাশ বাদ
  const ok = BD_MOBILE.test(value);
  input.classList.toggle('ok', ok);
  input.classList.toggle('bad', !ok);
  input.setAttribute('aria-invalid', String(!ok));
  msg.textContent = ok ? 'নম্বর ঠিক আছে' : '১১ অঙ্কের নম্বর দিন, যেমন 01712345678';
  return ok;
}

input.addEventListener('input', check);   // প্রতিটি অক্ষর টাইপের পর

for (const v of ['01712345678', '0171234567', '+8801912-345678', '01212345678']) {
  input.value = v;                               // টাইপের অনুকরণ
  input.dispatchEvent(new Event('input'));
  console.log(v, '→', input.getAttribute('aria-invalid') === 'false');
}

আউটপুট: 01712345678 → true, 0171234567 → false (একটি অঙ্ক কম), +8801912-345678 → true (দেশের কোড আর ড্যাশ মেনে নেওয়া হলো), 01212345678 → false (012 দিয়ে কোনো মোবাইল নম্বর হয় না)। শেষ নম্বরটি ঘরে থেকে যায় বলে border লাল দেখায়। এবার ঘরে নিজে টাইপ করে দেখুন। লক্ষ করুন: (১) <label for> আর aria-describedby থাকায় screen reader ঘরের নাম আর ভুলের বার্তা দুটোই পড়ে শোনাবে; (২) রং এসেছে CSS-এর .ok/.bad class থেকে; (৩) aria-invalid দিয়ে অবস্থাটা সহায়ক প্রযুক্তিকেও জানানো হলো। Form আর validation-এর পুরো গল্প পর্ব ৩৯-এ।

Browser-এর যাচাই সুবিধার জন্য, নিরাপত্তার জন্য নয়। ব্রাউজারের JavaScript ব্যবহারকারীর কম্পিউটারে চলে — তিনি চাইলে DevTools দিয়ে বন্ধ করতে বা বদলাতে পারেন, কিংবা ব্রাউজার ছাড়াই সরাসরি সার্ভারে অনুরোধ পাঠাতে পারেন। তাই একই যাচাই সার্ভারেও আবার করতে হয়। নিরাপত্তার এই নীতিগুলো পর্ব ৪৩-এ বিস্তারিত।

Progressive enhancement-এর উল্টো চরম হলো এমন পাতা, যার HTML-এ প্রায় কিছুই নেই — শুধু একটি খালি <div id="app">, আর পুরো পাতা JavaScript পরে বানায়। একে প্রায়ই SPA (single-page application) বলা হয়। Gmail বা বড় ড্যাশবোর্ডের মতো অ্যাপে এর যুক্তি আছে, কিন্তু সাধারণ দোকান বা খবরের পাতায় এতে প্রথম দেখা দেরি হয় — বিশেষ করে কম দামি ফোনে আর ধীর নেটওয়ার্কে। ভাবনার প্রশ্ন ০৪-এ এই বিতর্কটা খুঁটিয়ে দেখব।

৮ · কোন কোড কোথায় চলে — client, server আর DevTools

ওয়েব অ্যাপের কোড দুই জায়গায় চলে। ব্যবহারকারীর ব্রাউজার হলো client; আর যে কম্পিউটার অনুরোধের উত্তর দেয়, সেটা server. HTML, CSS আর ব্রাউজারের JavaScript client-এ চলে। ডেটাবেস, পাসওয়ার্ড যাচাই, পেমেন্ট, গোপন চাবি (API key) — এসব থাকে server-এ।

প্রশ্নClient (ব্রাউজার)Server
কোথায় চলেব্যবহারকারীর ফোন বা কম্পিউটারেকোম্পানির নিয়ন্ত্রিত কম্পিউটারে
কোড কে দেখতে পায়যে কেউ (DevTools-এ খোলা যায়)শুধু মালিক
ভালো কাজতাৎক্ষণিক সাড়া, animation, ফর্মে আগাম যাচাইডেটা জমা, নিয়ম প্রয়োগ, চূড়ান্ত যাচাই
ভাষাHTML, CSS, JavaScript (আর WebAssembly)যেকোনো — JavaScript (Node.js), Python, Java, PHP, Go…
কখনো রাখবেন নাগোপন চাবি, দামের চূড়ান্ত হিসাব—

JavaScript-এর বিশেষত্ব হলো এটি দুই দিকেই চলে। ২০০৯ সালে আসা Node.js ব্রাউজারের বাইরে, সার্ভারে JavaScript চালানোর সুযোগ দেয়। মডিউল ৭-এ (পর্ব ৪৯ থেকে) Node.js দিয়ে ফাইল, server আর ডেটাবেস নিয়ে কাজ করব। তবে মনে রাখুন, Node.js-এ DOM নেই — document শুধু ব্রাউজারের জিনিস। আবার ব্রাউজারের JavaScript ব্যবহারকারীর ফাইল ইচ্ছেমতো পড়তে পারে না; নিরাপত্তার জন্য সে একটি ঘেরা জায়গায় (sandbox) চলে।

DevTools — তিন স্তর চোখে দেখার যন্ত্র

প্রতিটি আধুনিক ব্রাউজারে তৈরি থাকে DevTools — Chrome বা Edge-এ F12 বা Ctrl+Shift+I চাপলেই খোলে। এই পর্বের প্রতিটি ধারণা সেখানে চোখে দেখা যায়:

Elements

জীবন্ত DOM tree, আর ডান পাশে প্রতিটি element-এর ওপর কোন CSS নিয়ম জিতেছে, কোনটি কাটা পড়েছে (cascade!), আর box model-এর মাপ।

HTML + CSS

Console

console.log-এর আউটপুট, error, আর সরাসরি JavaScript লিখে চালানোর জায়গা — document.title লিখে Enter চেপে দেখুন।

JavaScript

Network

পাতা খুলতে কোন কোন ফাইল এলো, কত বড়, কত সময়, status কত (200, 404…) — অংশ ২-এর ধাপ ২–৪ চোখের সামনে।

HTTP

DevTools খোলা আর ব্যবহারের হাতে-কলমে নির্দেশনা আসছে পরের পর্বে (পর্ব ০৩)।

পরীক্ষা ও ইন্টারভিউতে

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

  • HTML, CSS আর JavaScript-এর ভূমিকা কী? — HTML কাঠামো ও অর্থ, CSS চেহারা, JavaScript আচরণ ও ইন্টারঅ্যাকশন।
  • DOM কী? — HTML থেকে ব্রাউজারের বানানো object-এর গাছ, যেটা JavaScript পড়তে ও বদলাতে পারে; HTML ফাইল নিজে বদলায় না।
  • defer আর async-এর পার্থক্য? — দুটোই পাশাপাশি নামে; defer HTML পড়া শেষে ক্রম মেনে চলে, async নামামাত্র চলে, ক্রমের নিশ্চয়তা নেই।
  • Semantic HTML কেন জরুরি? — accessibility (screen reader, কিবোর্ড), SEO আর পড়তে সহজ কোডের জন্য।
  • Client-side validation থাকলে server-side লাগে কেন? — client-এর কোড ব্যবহারকারী বদলাতে বা এড়াতে পারেন; নির্ভরযোগ্য যাচাই হয় শুধু server-এ।

৯ · AI-এর যুগে — “চলে” আর “ঠিক আছে” এক জিনিস নয়

AI-কে “একটা প্রোডাক্ট কার্ড বানিয়ে দাও” বললে কয়েক সেকেন্ডে দেখতে সুন্দর কিছু পাবেন। কিন্তু ভেতরে তাকালে প্রায়ই দেখা যায় তিন স্তর গুলিয়ে গেছে। মাউস দিয়ে চালিয়ে দেখলে সব ঠিক লাগে — সমস্যা ধরা পড়ে কিবোর্ডে, screen reader-এ, ধীর নেটওয়ার্কে, অথবা ছয় মাস পরে কোড বদলাতে গিয়ে।

AI প্রায়ই যা দেয়সমস্যাভালো বিকল্প
সব কিছু <div> দিয়ে — “div-স্যুপ”অর্থ নেই; screen reader ও search engine কিছু বোঝে নাheader, main, article, button, nav
<div onclick="…">কিবোর্ডে পৌঁছানো যায় না; HTML-এ আচরণ মিশে গেছে<button> + আলাদা ফাইলে addEventListener
প্রতিটি ট্যাগে style="…"এক রং বদলাতে ৫০ জায়গায় হাত; cascade-এ জেতাও কঠিনCSS ফাইলে class-ভিত্তিক নিয়ম
JavaScript দিয়ে element.style.color = …চেহারার সিদ্ধান্ত JavaScript-এ ঢুকে গেছেclassList.add('in-cart')
<img>-এ alt নেই, input-এ label নেইদৃষ্টিপ্রতিবন্ধী ব্যবহারকারীর কাছে অর্থহীনঅর্থপূর্ণ alt, <label for>
head-এ attribute ছাড়া <script>পাতা আটকায়; element খুঁজলে nulldefer বা type="module"
যাচাই শুধু ব্রাউজারেসহজেই এড়ানো যায়server-এও একই যাচাই

AI-কে ভালো front-end কোড লেখাতে চাইলে তিন স্তরের নিয়ম প্রম্পটেই বলে দিন। নিচের প্রম্পটটি কপি করে নিজের প্রয়োজনমতো বদলে নিন:

একটি অনলাইন দোকানের প্রোডাক্ট কার্ড বানাও (ছবি, নাম, দাম, "কার্টে যোগ করুন" বোতাম, কার্টের কাউন্টার)। নিয়মগুলো মানবে: ১. HTML, CSS আর JavaScript তিনটি আলাদা ফাইলে দাও (index.html, style.css, app.js). ২. semantic ট্যাগ ব্যবহার করো — article, h2, button; কোথাও div-এ onclick দেবে না। ৩. কোনো inline style বা onclick attribute থাকবে না; JavaScript শুধু class যোগ/বাদ করবে, রং CSS-এ। ৪. script ট্যাগে defer বা type="module" দাও। ৫. ছবিতে অর্থপূর্ণ alt, কাউন্টার বদলালে screen reader যেন জানতে পারে (aria-live). ৬. JavaScript বন্ধ থাকলেও কার্ডের লেখা ও দাম যেন পড়া যায়। শেষে প্রতিটি নিয়ম কোথায় মেনেছ, এক লাইনে করে বলো।

AI-এর লেখা front-end কোড হাতে পেলে — যাচাইয়ের চেকলিস্ট

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

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলো আপনাকে ট্যাগ-লেখক থেকে ওয়েব-চিন্তক বানাবে।

প্র ০১World Wide Web কেন জন্মেছিল, আর প্রথম ওয়েব পাতা থেকে আজকের ওয়েবের নকশায় কী রয়ে গেছে?

১৯৮৯ সালের মার্চে সুইজারল্যান্ডের CERN গবেষণাগারে কর্মরত ব্রিটিশ বিজ্ঞানী Tim Berners-Lee একটি প্রস্তাব লেখেন — “Information Management: A Proposal”. সমস্যাটা খুব মানবিক ছিল: হাজারো বিজ্ঞানী আসেন-যান, আলাদা আলাদা কম্পিউটারে আলাদা ফরম্যাটে তথ্য রাখেন, আর একজনের কাজ আরেকজন খুঁজে পান না। তাঁর বস Mike Sendall প্রস্তাবের ওপর লিখেছিলেন “Vague but exciting” — অস্পষ্ট, কিন্তু রোমাঞ্চকর।

১৯৯০ সালের শেষ নাগাদ Berners-Lee একটি NeXT কম্পিউটারে তিনটি মূল জিনিস তৈরি করেন, যা আজও ওয়েবের হৃদয়: HTML (পাতা লেখার ভাষা), HTTP (পাতা চাওয়া ও পাঠানোর নিয়ম) আর URL (প্রতিটি জিনিসের একটি অনন্য ঠিকানা)। সাথে প্রথম ওয়েব সার্ভার আর প্রথম ব্রাউজার — যার নাম ছিল “WorldWideWeb”, আর যেটা দিয়ে পাতা পড়ার সাথে লেখাও যেত। সহকর্মী Robert Cailliau এই প্রকল্পে বড় ভূমিকা রাখেন। ১৯৯১ সালে প্রথম ওয়েবসাইট info.cern.ch সবার জন্য খুলে দেওয়া হয়; সেখানে লেখা ছিল ওয়েব কী আর কীভাবে নিজের সার্ভার বানাতে হয়। ১৯৯৩ সালে CERN ওয়েবের সফটওয়্যার সবার জন্য বিনামূল্যে ব্যবহারের অনুমতি দেয় — কোনো লাইসেন্স ফি নেই। ওয়েবের বিস্ফোরণের পেছনে এই সিদ্ধান্তটি বড় কারণ।

আজকের নকশায় কী রয়ে গেছে? প্রায় সবকিছুর বীজ। প্রথম HTML-এ ট্যাগ ছিল অল্প কয়েকটি, আর সেগুলো ছিল অর্থের ট্যাগ — শিরোনাম, অনুচ্ছেদ, তালিকা, link. চেহারার কোনো নির্দেশ ছিল না; ব্রাউজার নিজের মতো দেখাত। এই “অর্থ আগে” চিন্তাই আজকের semantic HTML. URL আর HTTP-র মূল ধারণাও বদলায়নি — এই পর্বের অংশ ২-এর GET /saree অনুরোধ ১৯৯১ সালের অনুরোধের সরাসরি বংশধর। আর একটি দর্শন: ওয়েব কেন্দ্রীয় অনুমতি ছাড়াই যে কাউকে পাতা বানাতে ও link দিতে দেয়।

মূল উপলব্ধি: ওয়েব শুরু হয়েছিল তথ্য ভাগাভাগির জন্য, অর্থপূর্ণ কাঠামো আর সবার জন্য খোলা নিয়ম দিয়ে। চেহারা আর আচরণ পরে এসেছে — তাই HTML-কে “সাজানোর জিনিস” না ভেবে “অর্থের ভিত্তি” ভাবাই ওয়েবের আসল চরিত্রের সাথে মেলে।

প্র ০২CSS আসার আগে ওয়েব পাতা কীভাবে সাজানো হতো, আর চেহারাকে কাঠামো থেকে আলাদা করা কেন এত বড় সিদ্ধান্ত ছিল?

১৯৯৩ সালে Mosaic ব্রাউজার ছবি দেখানো জনপ্রিয় করার পর ওয়েব দ্রুত সাধারণ মানুষের কাছে পৌঁছায়, আর সবাই চাইলেন পাতা দেখতে ছাপা পত্রিকার মতো সুন্দর হোক। কিন্তু HTML-এ চেহারা নিয়ন্ত্রণের কোনো ব্যবস্থা ছিল না। ফলে ব্রাউজার কোম্পানিগুলো নিজেরাই চেহারার ট্যাগ যোগ করতে থাকে — যেমন রং ও অক্ষরের জন্য <font>. ডিজাইনাররা পাতার বিন্যাসের জন্য <table> ব্যবহার শুরু করেন, যদিও table আসলে তথ্যের সারণির জন্য। ফাঁকা জায়গা বানাতে অদৃশ্য এক-পিক্সেলের ছবিও ব্যবহার হতো। ফলাফল: অর্থ আর চেহারা এমনভাবে জট পাকিয়ে গেল যে পুরো সাইটের রং বদলাতে হাজার পাতা হাতে বদলাতে হতো, আর screen reader table-এর জঙ্গলে পথ হারাত।

১৯৯৪ সালের অক্টোবরে CERN-এ কর্মরত নরওয়েজিয়ান Håkon Wium Lie “Cascading HTML Style Sheets” নামে একটি প্রস্তাব প্রকাশ করেন। শিগগিরই Bert Bos তাঁর সাথে যোগ দেন, আর ১৯৯৬ সালের ডিসেম্বরে W3C প্রথম standard — CSS level 1 — প্রকাশ করে। প্রস্তাবের সবচেয়ে মৌলিক ধারণা ছিল “cascade”: পাতার লেখক, ব্যবহারকারী আর ব্রাউজার — তিন পক্ষেরই চেহারা নিয়ে মত থাকতে পারে, আর নিয়মগুলো স্তরে স্তরে মিলে চূড়ান্ত ফল ঠিক হবে। অর্থাৎ শুরু থেকেই ভাবা হয়েছিল, ছোট অক্ষর পড়তে কষ্ট হওয়া একজন ব্যবহারকারী নিজের stylesheet দিয়ে বড় অক্ষর চাইতে পারবেন।

আলাদা করার সুফল কয়েক দিকে। রক্ষণাবেক্ষণ: একটি CSS ফাইল বদলালে পুরো সাইট বদলায়। বিভিন্ন মাধ্যম: একই HTML পর্দায় এক রকম, প্রিন্টে আরেক রকম, ছোট ফোনে আরেক রকম (আজকের responsive design). Accessibility: কাঠামো পরিষ্কার থাকে বলে সহায়ক প্রযুক্তি সহজে পড়ে। গতি: CSS ফাইল একবার নেমে cache-এ থাকে। ২০০৩ সালে Dave Shea-র “CSS Zen Garden” সাইট নাটকীয়ভাবে দেখায়, হুবহু একই HTML-এর ওপর শুধু CSS বদলে সম্পূর্ণ আলাদা ডিজাইন সম্ভব।

মূল উপলব্ধি: “এটা কী” আর “এটা দেখতে কেমন” — দুটি আলাদা প্রশ্ন, আর আলাদা প্রশ্নের উত্তর আলাদা জায়গায় রাখলে সিস্টেম বদলানো সহজ হয়। AI যখন প্রতিটি ট্যাগে inline style দেয়, সে আসলে ১৯৯০-এর দশকের <font>-যুগে ফিরে যায়।

প্র ০৩“Browser wars” কী ছিল, আর web standard (W3C, WHATWG, HTML Living Standard) কেন একজন JavaScript ডেভেলপারের জন্য গুরুত্বপূর্ণ?

১৯৯০-এর দশকের মাঝামাঝি Netscape Navigator আর Microsoft-এর Internet Explorer বাজার দখলের তীব্র লড়াইয়ে নামে — এটাই প্রথম “browser war”. দুই পক্ষই নিজস্ব বৈশিষ্ট্য যোগ করত, যা অন্যটিতে চলত না: Netscape-এর ঝিকমিক করা <blink>, IE-র চলমান লেখার <marquee>. JavaScript-এর ক্ষেত্রেও একই অবস্থা — Netscape-এর JavaScript-এর জবাবে Microsoft আনে নিজের JScript, আর DOM-এর আচরণও আলাদা। ওয়েবসাইটে লেখা থাকত “Best viewed in Netscape” বা “Best viewed in Internet Explorer”; ডেভেলপাররা একই কাজ দুবার লিখতেন।

বিশৃঙ্খলা কমাতে দুটি বড় পদক্ষেপ আসে। ১৯৯৪ সালে Tim Berners-Lee W3C (World Wide Web Consortium) প্রতিষ্ঠা করেন — HTML, CSS-এর standard লেখার জন্য। আর JavaScript-কে Ecma International-এ standard করা হয়; ১৯৯৭ সালে প্রথম ECMAScript প্রকাশিত হয় (তাই আজও ES2015, ES2023 বলা হয়)। ২০০০-এর দশকের শুরুতে IE বাজারের বিশাল অংশ দখল করে উন্নয়ন প্রায় থামিয়ে দেয়; ডেভেলপারদের বছরের পর বছর পুরোনো IE-র জন্য বাড়তি কোড লিখতে হয়।

এরপর আসে দ্বিতীয় অধ্যায়। W3C তখন XHTML 2-এর দিকে যাচ্ছিল, যা পুরোনো পাতার সাথে সামঞ্জস্য ভাঙত। ২০০৪ সালে Apple, Mozilla আর Opera মিলে গড়ে WHATWG, এবং বাস্তব ওয়েবের উপযোগী করে HTML-কে এগিয়ে নেওয়ার কাজ শুরু করে — যেখান থেকে HTML5 আসে (<video>, <canvas>, semantic ট্যাগ, পরিষ্কার parsing নিয়ম)। Firefox (২০০৪) আর Chrome (২০০৮) প্রতিযোগিতা ফেরায়। ২০১৯ সালে W3C আর WHATWG একমত হয় যে HTML আর DOM-এর একক উৎস হবে WHATWG-এর Living Standard — একটি দলিল যা নিয়মিত হালনাগাদ হয়, “HTML6” বলে আলাদা সংস্করণ আর আসে না।

একজন JavaScript ডেভেলপারের জন্য এর মানে বাস্তব: আজ আপনি একবার addEventListener লিখলে Chrome, Firefox, Safari, Edge — সবখানে একই আচরণ পান, কারণ standard-এ নিয়মটা একভাবে লেখা আর ব্রাউজাররা নিয়মিত পরস্পরের সাথে মিলিয়ে পরীক্ষা করে। নতুন কোনো feature ব্যবহারের আগে MDN বা “Can I use”-এ সমর্থন দেখে নেওয়ার অভ্যাসও এই ইতিহাসেরই শিক্ষা।

মূল উপলব্ধি: খোলা standard ছাড়া ওয়েব একটি কোম্পানির সম্পত্তি হয়ে যেত। আপনার লেখা কোড যে বহু বছর পরেও চলবে, তার নিশ্চয়তা কোনো ব্রাউজার কোম্পানি নয়, standard-এর পেছনের সম্মিলিত প্রক্রিয়া।

প্র ০৪Progressive enhancement বনাম single-page application (SPA) — বিতর্কটা কী, আর বাংলাদেশের ব্যবহারকারীদের জন্য কোনটা কখন ভালো?

২০০৩ সালে Steven Champeon আর Nick Finck-এর একটি আলোচনায় “progressive enhancement” শব্দটি জনপ্রিয় হয়। তখনকার প্রচলিত পদ্ধতি ছিল “graceful degradation” — আগে সবচেয়ে আধুনিক ব্রাউজারের জন্য বানাও, তারপর পুরোনো ব্রাউজারে যেন একেবারে ভেঙে না পড়ে সেটা দেখো। Champeon উল্টোটা প্রস্তাব করলেন: আগে সবার জন্য কাজ করা একটি ভিত্তি (HTML), তারপর সামর্থ্য অনুযায়ী স্তর যোগ।

অন্যদিকে ২০০৪ সালে Gmail দেখাল, পাতা reload না করেই ব্রাউজারে ডেস্কটপ-অ্যাপের মতো অভিজ্ঞতা সম্ভব (২০০৫ সালে Jesse James Garrett এই কৌশলের নাম দেন “Ajax”). পরে AngularJS, React, Vue-র মতো framework-এ পুরো পাতা JavaScript দিয়ে ব্রাউজারে বানানো সাধারণ হয়ে যায় — SPA. সুবিধা: একবার লোড হলে নেভিগেশন খুব দ্রুত, জটিল ইন্টারঅ্যাকশন সহজ। অসুবিধা: প্রথমবার বড় JavaScript ফাইল নামা, parse হওয়া আর চলার আগ পর্যন্ত পাতা খালি; search engine-এর জন্য কঠিন; কম দামি ফোনে JavaScript চালাতেই অনেক সময় লাগে।

বাস্তব অভিজ্ঞতা থেকে শিল্প আবার মাঝামাঝি পথে ফিরেছে। ২০১২ সালে Twitter জানায় যে পুরোপুরি ব্রাউজারে-বানানো পাতা থেকে সার্ভারে HTML বানানোয় ফিরে গিয়ে তারা প্রথম tweet দেখানোর সময় অনেক কমিয়েছে। আজকের Next.js, Nuxt, SvelteKit, Astro-র মতো টুল সাধারণত সার্ভারে HTML বানিয়ে পাঠায়, তারপর ব্রাউজারে JavaScript সেটাকে ইন্টারঅ্যাকটিভ করে (hydration) — অর্থাৎ progressive enhancement-এর চিন্তাই নতুন চেহারায়।

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

মূল উপলব্ধি: “SPA ভালো না খারাপ” প্রশ্নটা ভুল; প্রশ্ন হলো “আমার ব্যবহারকারী কে, কোন যন্ত্রে, কোন নেটওয়ার্কে, আর প্রথম কয়েক সেকেন্ডে তাঁর কী দরকার?” উত্তর যা-ই হোক, তিন স্তরের ভাগ বোঝা থাকলে আপনি যেকোনো পথ সচেতনভাবে বেছে নিতে পারবেন।

প্র ০৫Accessibility কি ঐচ্ছিক “ভালো অভ্যাস”, নাকি ব্যবহারকারীর অধিকার? WCAG আর screen reader এখানে কী ভূমিকা রাখে?

১৯৯৭ সালে W3C-র Web Accessibility Initiative চালুর সময় Tim Berners-Lee বলেছিলেন, ওয়েবের শক্তি তার সর্বজনীনতায়, আর প্রতিবন্ধিতা নির্বিশেষে সবার প্রবেশাধিকার এর অপরিহার্য দিক। দৃষ্টিপ্রতিবন্ধী, কম দেখেন, রং আলাদা করতে পারেন না, হাত কাঁপে বলে মাউস ধরতে পারেন না, শুনতে পান না — এমন মানুষ বিপুল সংখ্যায় আছেন। বয়স বাড়লে আমরা প্রায় সবাই কোনো না কোনোভাবে এই দলে যোগ দিই। ভাঙা হাতে কিছুদিন শুধু কিবোর্ড ব্যবহার করতে হলে, বা রোদে ফোনের পর্দা ঝাপসা দেখলে আমরাও সাময়িকভাবে এই অভিজ্ঞতা পাই।

Screen reader হলো এমন সফটওয়্যার, যা পর্দার লেখা পড়ে শোনায় আর কিবোর্ড দিয়ে নেভিগেশন করতে দেয় — Windows-এ বিনামূল্যের NVDA আর বাণিজ্যিক JAWS, Apple যন্ত্রে VoiceOver, Android-এ TalkBack. এগুলো পর্দার ছবি দেখে না; ব্রাউজার DOM থেকে একটি accessibility tree বানায় — কোনটা বোতাম, কোনটা শিরোনাম, কোন ঘরের নাম কী — আর screen reader সেটাই পড়ে। তাই <button> আর <div> দেখতে এক হলেও screen reader-এর কাছে দুটি সম্পূর্ণ আলাদা জিনিস।

নিয়ম লেখা আছে WCAG (Web Content Accessibility Guidelines)-এ। প্রথম সংস্করণ ১৯৯৯ সালে, WCAG 2.0 ২০০৮ সালে, 2.1 ২০১৮ সালে আর 2.2 ২০২৩ সালে। এর চারটি মূলনীতি: তথ্য বোধগম্য (perceivable — যেমন ছবির alt লেখা, যথেষ্ট রঙের বৈপরীত্য), চালনাযোগ্য (operable — শুধু কিবোর্ডেও সব করা যায়), বোঝার যোগ্য (understandable — পরিষ্কার ভুলের বার্তা) আর শক্তপোক্ত (robust — বিভিন্ন সহায়ক প্রযুক্তিতে চলে)। অনেক দেশে এখন আইনেও এটা বাধ্যতামূলক: যুক্তরাষ্ট্রে প্রতিবন্ধী অধিকার আইনের অধীনে ওয়েবসাইট নিয়ে মামলা হয়েছে, আর ইউরোপীয় ইউনিয়নের European Accessibility Act ২০২৫ সাল থেকে অনেক ডিজিটাল সেবায় কার্যকর। জাতিসংঘের প্রতিবন্ধী ব্যক্তিদের অধিকার সনদেও তথ্যে প্রবেশাধিকারকে অধিকার হিসেবে স্বীকার করা হয়েছে, আর বাংলাদেশেরও প্রতিবন্ধী ব্যক্তির অধিকার ও সুরক্ষা আইন (২০১৩) আছে।

প্রকৌশলীর চোখে সবচেয়ে বড় শিক্ষা: accessibility-র বেশিরভাগই বিনা খরচে আসে, যদি শুরু থেকে semantic HTML লেখেন। পরে “ঠিক করতে” গেলে খরচ বহুগুণ। আর সুবিধা সবার — label থাকা ফর্ম সবার জন্য সহজ, ভালো বৈপরীত্য রোদে সবার জন্য পড়ার যোগ্য, পরিষ্কার শিরোনাম-কাঠামো search engine-ও পছন্দ করে।

মূল উপলব্ধি: Accessibility কোনো আলাদা feature নয়, সঠিক HTML-এর স্বাভাবিক ফল। যে পাতা সবাই ব্যবহার করতে পারে না, সেটা আসলে অসম্পূর্ণ পাতা।

অনুশীলন

এগুলোর বেশিরভাগে কোড লিখতে হবে না — ব্রাউজার খুলে দেখা আর ভাবাই আসল কাজ।

  1. জীবন্ত DOM বদলান: যেকোনো ওয়েবসাইট খুলে F12 চাপুন, Elements ট্যাবে একটি শিরোনামের লেখায় double-click করে বদলে দিন। পাতায় কী দেখলেন? এবার পাতা reload করুন — কী হলো, আর কেন?

    লেখা বদলানোর সাথে সাথে পাতায় নতুন লেখা দেখা যায় — কারণ আপনি DOM বদলেছেন, আর ব্রাউজার DOM দেখেই আঁকে। Reload করলে আবার আগের লেখা ফিরে আসে, কারণ ব্রাউজার সার্ভার থেকে HTML নতুন করে এনে নতুন DOM বানায়। আপনার বদল ছিল শুধু নিজের কম্পিউটারের মেমরিতে — সার্ভারের ফাইলে নয়। এ কারণেই কেউ DevTools দিয়ে “ব্যাংক ব্যালান্স” বদলে স্ক্রিনশট দিলে তার কোনো মূল্য নেই।

  2. Network ট্যাবে পাতার যাত্রা: DevTools-এর Network ট্যাব খোলা রেখে একটি পাতা reload করুন। প্রথম অনুরোধটি কোন ধরনের ফাইলের? মোট কয়টি অনুরোধ হলো? কোনোটির status 200 ছাড়া অন্য কিছু আছে কি?

    প্রথম অনুরোধটি প্রায় সবসময় HTML ডকুমেন্ট (Type কলামে “document”) — অংশ ২-এর ধাপ ২–৩। তার পরে আসে CSS, JavaScript, ফন্ট, ছবি — কারণ parser HTML পড়তে পড়তে এগুলোর ঠিকানা খুঁজে পায় (ধাপ ৪)। সাধারণ একটি খবরের সাইটে কয়েক ডজন থেকে শতাধিক অনুরোধ দেখা অস্বাভাবিক নয়, যার অনেকগুলো বিজ্ঞাপন ও পরিসংখ্যানের। 304 মানে “আগের কপিই চলবে” (cache), 404 মানে ফাইল পাওয়া যায়নি, 301/302 মানে অন্য ঠিকানায় পাঠানো হয়েছে। নিচের সারিতে মোট আকার ও সময়ও দেখতে পাবেন।

  3. Div-স্যুপ সারাই করুন: নিচের কোডটি কোন কোন semantic ট্যাগ দিয়ে লেখা উচিত, আর এতে কী কী সমস্যা আছে?
    <div class="top"><div class="menu">…link…</div></div>
    <div class="buy" onclick="addToCart()" style="color:red">কিনুন</div>

    প্রথম লাইন: বাইরের div.top হওয়া উচিত <header>, ভেতরের div.menu হওয়া উচিত <nav> (link-গুলো <a href>-এ, সম্ভব হলে একটি <ul>-এ)। দ্বিতীয় লাইনে তিনটি সমস্যা: (১) div বোতাম নয় — Tab-এ পৌঁছানো যায় না, Enter-এ চলে না; হওয়া উচিত <button type="button" class="buy">. (২) onclick attribute আচরণকে HTML-এ ঢুকিয়েছে; আলাদা JavaScript ফাইলে addEventListener ব্যবহার করুন। (৩) style="color:red" চেহারাকে HTML-এ ঢুকিয়েছে; CSS ফাইলে .buy { color: … } লিখুন।

  4. JavaScript ছাড়া পাতা: Chrome বা Edge-এর DevTools খোলা অবস্থায় Ctrl+Shift+P চেপে “Disable JavaScript” লিখে Enter দিন, তারপর দুটি আলাদা ধরনের সাইট reload করুন — একটি খবরের সাইট আর একটি বড় ওয়েব অ্যাপ (যেমন কোনো ইমেইল বা ম্যাপ সেবা)। কোনটিতে কতটুকু কাজ করে? (শেষে আবার “Enable JavaScript” দিতে ভুলবেন না।)

    অনেক খবরের সাইটে শিরোনাম আর লেখা ঠিকই পড়া যায় — কিছু মেনু, ছবির স্লাইডার বা মন্তব্য অংশ কাজ করে না। এটাই progressive enhancement-এর ফল: মূল কাজ HTML-এ। বড় ওয়েব অ্যাপগুলো প্রায়ই প্রায় খালি পাতা বা “JavaScript চালু করুন” বার্তা দেখায় — কারণ তাদের পুরো পাতা ব্রাউজারে JavaScript দিয়ে বানানো হয় (SPA). কোনটি ঠিক, তা নির্ভর করে সাইটের কাজের ওপর — ভাবনার প্রশ্ন ০৪ দেখুন। এই পরীক্ষাটি নিজের বানানো সাইটে নিয়মিত করা একটি ভালো অভ্যাস।

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

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

ক্রমঠিকানা লিখে Enter চাপার পর ব্রাউজারের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. 🔎 DNS থেকে সার্ভারের IP ঠিকানা জানা
  2. 📨 সার্ভারে HTTP অনুরোধ পাঠানো
  3. 🌳 HTML উত্তর পড়ে DOM তৈরি (সাথে CSS থেকে CSSOM)
  4. 🧩 DOM আর CSSOM মিলিয়ে render tree
  5. 📐 Layout — প্রতিটি বাক্সের মাপ ও অবস্থান হিসাব
  6. 🖼️ Paint ও composite — পর্দায় পিক্সেল

একটি ওয়েব পাতায় “বোতাম চাপলে কার্টের সংখ্যা বাড়বে” — এই দায়িত্ব কোন স্তরের?

  • HTML
  • CSS
  • JavaScript
  • HTTP

ওয়েব ব্রাউজারের প্রসঙ্গে DOM কী?

  • সার্ভারে রাখা HTML ফাইলটি
  • HTML থেকে ব্রাউজারের বানানো object-এর গাছ, যা JavaScript পড়তে ও বদলাতে পারে
  • CSS নিয়মগুলোর তালিকা
  • JavaScript-এর একটি নতুন সংস্করণ

<script src="app.js" defer></script> লেখা থাকলে app.js কখন চলে?

  • পাওয়ামাত্র, HTML পড়া থামিয়ে
  • নামা শেষ হওয়ামাত্র, ক্রম না মেনে
  • ব্যবহারকারী প্রথমবার ক্লিক করলে
  • HTML পড়া শেষ হলে, লেখার ক্রম মেনে

“কার্টে যোগ করুন”-এর মতো চাপার জিনিসের জন্য কোন markup সবচেয়ে উপযুক্ত?

  • <button type="button"> আর আলাদা JavaScript ফাইলে addEventListener
  • <div onclick="add()">
  • <span style="cursor:pointer">
  • <a> (href ছাড়া)

CSS box model-এ border আর content-এর মাঝের ফাঁকা জায়গাকে কী বলে?

  • margin
  • outline
  • padding
  • gap

একটি ফর্মে মোবাইল নম্বর ব্রাউজারে JavaScript দিয়ে যাচাই করা হয়। তবু সার্ভারে আবার যাচাই করা দরকার কেন?

  • কারণ ব্রাউজারের JavaScript খুব ধীর
  • কারণ client-এর কোড ব্যবহারকারী বন্ধ, বদল বা এড়িয়ে যেতে পারেন
  • কারণ ব্রাউজারে regular expression কাজ করে না
  • দরকার নেই; ব্রাউজারে যাচাই করলেই যথেষ্ট

শব্দকোষ

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

মনে রাখুন

  1. HTML = কী (কাঠামো ও অর্থ), CSS = কেমন দেখায়, JavaScript = কী ঘটে; তিনটি আলাদা রাখাই separation of concerns.
  2. URL থেকে পিক্সেল: DNS → HTTP → HTML → DOM + CSSOM → render tree → layout → paint → composite.
  3. JavaScript বদলায় DOM, HTML ফাইল নয়; class যোগ-বাদ করে অবস্থা জানায়, চেহারা ঠিক করে CSS.
  4. নিজের script-এ defer বা type="module"; স্বাধীন ছোট script-এ async.
  5. আগে HTML-এ কাজ করুক, তারপর JavaScript ভালো করুক; semantic ট্যাগ, কিবোর্ডে পরীক্ষা, আর server-এ চূড়ান্ত যাচাই — AI-এর কোডেও।

পরের পর্বে: আজ জানলেন পাতার ভেতরে কী ঘটে। এবার নিজের কম্পিউটার তৈরি করব — browser console আর DevTools, Node.js ইনস্টল আর VS Code সেটআপ, যাতে প্রতিটি ধারণা নিজের হাতে চালিয়ে দেখতে পারেন।

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

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