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

লেখা ও অর্থবহ ট্যাগ — heading, paragraph আর inline element

Text Semantics — Headings, Paragraphs & Inline Elements

Taught in Bangla, this lesson teaches semantic text markup: choosing tags by meaning rather than looks, building a clean outline with h1 to h6, and using p, br and hr. It contrasts strong, em, b and i, and covers mark, small, del, ins, sub, sup, quotations, abbr, time, address, dfn, code, kbd, samp, var and pre, plus span, content categories versus CSS display, and character references in UTF-8 pages.

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

  • “চেহারা নয়, অর্থ” — কেন এই নীতি অ্যাক্সেসিবিলিটি, সার্চ আর রক্ষণাবেক্ষণের ভিত্তি
  • h1–h6 দিয়ে পেজের পরিষ্কার রূপরেখা বানানো, আর সাধারণ ভুলগুলো চেনা
  • p, br, hr এবং strong, em, b, i, mark, small, s, del, ins, sub, sup — কোনটি কখন
  • উদ্ধৃতি, সংক্ষেপ, সময়, ঠিকানা, সংজ্ঞা আর কোড দেখানোর ট্যাগ
  • block/inline-এর পুরোনো ধারণা বনাম আজকের content category, আর character reference-এর সঠিক ব্যবহার

১ · Semantics — চেহারা নয়, অর্থ

পর্ব ০৩-এ আপনি দেখেছেন, HTML-এর প্রতিটি element লেখার একটি অংশকে ঘিরে রাখে। এবার আসল প্রশ্ন: কোন অংশকে কোন element দিয়ে ঘিরবেন? উত্তরটি এই পুরো কোর্সের সবচেয়ে গুরুত্বপূর্ণ নীতিগুলোর একটি।

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

কিন্তু ওয়েবপেজ শুধু চোখ দিয়ে পড়া হয় না। একজন দৃষ্টিপ্রতিবন্ধী মানুষ পেজটি শোনেন screen reader দিয়ে — একটি সফটওয়্যার, যা পেজের লেখা জোরে পড়ে শোনায়। Google-এর মতো সার্চ ইঞ্জিন পেজ পড়ে একটি প্রোগ্রাম দিয়ে। ব্রাউজারের reader mode, অনুবাদ টুল, এমনকি AI চ্যাটবটও পেজের কাঠামো পড়ে। এদের কেউই “বড় অক্ষর মানে শিরোনাম” আন্দাজ করে না। এরা বিশ্বাস করে শুধু আপনার লেখা ট্যাগকে।

মূল ধারণা

Semantic HTML মানে লেখার প্রতিটি অংশকে সেই element দিয়ে চিহ্নিত করা, যার অর্থ ওই অংশের সাথে মেলে — শিরোনামের জন্য heading, অনুচ্ছেদের জন্য paragraph, গুরুত্বপূর্ণ সতর্কতার জন্য strong. দেখতে কেমন হবে, সেটি পুরোপুরি CSS-এর দায়িত্ব। HTML = বাড়ির কাঠামো, CSS = রং আর সাজ।

নিচের ডায়াগ্রামে একই দেখতে দুটি কোডকে তিন রকম “পাঠক” কীভাবে পড়ে, ধাপে ধাপে দেখুন:

  1. চোখদুটোই একচেহারা দেখে
  2. Screen readerdivশুধু লেখা
  3. Screen readerh1, strongঅর্থসহ
  4. সার্চ ও টুলকাঠামোবিষয় বোঝে
  5. ডেভেলপার৬ মাস পরেকোড পড়ে
দুটি কোড, পর্দায় একই রকমওপরে div, নিচে semantic
<!-- ক) div দিয়ে -->
<div class="big">বন্যা সতর্কতা</div>
<div><span class="red">জরুরি:</span> নদীর পানি বাড়ছে</div>

<!-- খ) অর্থবহ ট্যাগ দিয়ে -->
<h1>বন্যা সতর্কতা</h1>
<p><strong>জরুরি:</strong> নদীর পানি বাড়ছে</p>
Screen reader · কোড (ক)যা শোনা যায়
“বন্যা সতর্কতা। জরুরি: নদীর পানি বাড়ছে।”

Heading-এর তালিকা: (কিছু নেই)
→ ব্যবহারকারী জানেনই না কোনটা শিরোনাম,
  heading ধরে লাফ দেওয়ারও উপায় নেই
Screen reader · কোড (খ)যা শোনা যায়
“heading, level 1, বন্যা সতর্কতা।”
“জরুরি: নদীর পানি বাড়ছে।”

Heading-এর তালিকা:
  ১. বন্যা সতর্কতা
→ এক চাপে শিরোনামে যাওয়া যায়, পেজের গঠন বোঝা যায়
সার্চ ইঞ্জিন, reader mode, অনুবাদ, AIকাঠামো থেকে বোঝে
কোড (ক): “একগাদা div — কোনটা মূল বিষয়, বলা কঠিন”
কোড (খ): “এই পেজের প্রধান শিরোনাম: বন্যা সতর্কতা”

→ reader mode শিরোনাম আলাদা করে দেখায়,
  সার্চ ইঞ্জিন পেজের বিষয় সহজে ধরে
ছয় মাস পরে কোড খুলেরক্ষণাবেক্ষণ
class="big", class="red" — এটা কি শিরোনাম? নাকি শুধু বড় লেখা?
লাল রং বদলে নীল করলে class="red" নামটাই মিথ্যা হয়ে যাবে!

<h1>, <strong> — নাম দেখেই কাজ বোঝা যায়,
রং যা-ই হোক, অর্থ বদলায় না
  1. চোখের কাছে দুটোই এক। CSS দিয়ে দুটোকেই হুবহু একই রকম দেখানো যায় — বড় অক্ষরের শিরোনাম, লাল “জরুরি”। চোখ দিয়ে দেখলে কোনো পার্থক্য নেই। পার্থক্যটা লুকিয়ে আছে কোডের ভেতরে।
  2. Screen reader, কোড (ক)। div আর span-এর কোনো অর্থ নেই, তাই screen reader শুধু লেখাগুলো পরপর পড়ে যায়। “শিরোনাম” বলে কিছু আছে, এটা সে জানে না। ব্যবহারকারী পুরো পেজ শুরু থেকে শুনতে বাধ্য হন।
  3. Screen reader, কোড (খ)। এবার সে ঘোষণা করে “heading, level 1”. বেশিরভাগ screen reader-এ একটি কি চাপলে (যেমন NVDA-তে H) পরের heading-এ লাফানো যায় — যেমন আপনি বইয়ের সূচিপত্র দেখে সরাসরি অধ্যায়ে যান।
  4. সার্চ ইঞ্জিন আর অন্যান্য টুল। প্রোগ্রাম চোখ দিয়ে দেখে না, কাঠামো পড়ে। পরিষ্কার heading থাকলে সে বোঝে পেজটি কী নিয়ে। একে বলে SEO-এর ভিত্তি — যদিও শুধু ট্যাগ বদলালেই র‍্যাঙ্কিং লাফিয়ে উঠবে না, ভালো বিষয়বস্তুই আসল।
  5. আপনি নিজে, ছয় মাস পরে। class="red" নামটি চেহারার বর্ণনা, অর্থের নয়। নকশা বদলালে নামটি ভুল হয়ে যায়। কিন্তু <strong> সবসময় “গুরুত্বপূর্ণ” — রং যা-ই হোক। অর্থবহ কোড পড়া, বদলানো আর দলে কাজ করা সহজ।

তাহলে semantic HTML-এর লাভ চারটি: অ্যাক্সেসিবিলিটি (accessibility — প্রতিবন্ধী মানুষসহ সবাই পেজটি ব্যবহার করতে পারেন), সার্চ ও যন্ত্রের বোঝাপড়া, রক্ষণাবেক্ষণ আর বিনা খরচে পাওয়া সুবিধা — ব্রাউজার নিজে থেকেই heading-কে বড়, strong-কে মোটা করে দেখায়, কোনো CSS না লিখেই।

১৯৯১ সালে Tim Berners-Lee যখন প্রথম HTML ট্যাগের তালিকা প্রকাশ করেন, তাতে H1 থেকে H6 heading আর P অনুচ্ছেদ ছিল — অর্থাৎ শুরু থেকেই HTML ছিল “অর্থ চিহ্নিত করার” ভাষা। কিন্তু ১৯৯০-এর দশকের ব্রাউজার-যুদ্ধে Netscape ও Internet Explorer একের পর এক চেহারার ট্যাগ যোগ করে — <font>, <center>, <blink>. ১৯৯৬ সালে CSS আসার পর ধীরে ধীরে চেহারার দায়িত্ব CSS-কে দেওয়া হয়, আর আজকের HTML Living Standard-এ ওই ট্যাগগুলো obsolete — ব্যবহার করা চলবে না।

২ · Heading — h1 থেকে h6, আর পেজের রূপরেখা

HTML-এ ছয় স্তরের heading আছে: <h1> সবচেয়ে বড় স্তর, <h6> সবচেয়ে ছোট। এখানে “বড়” মানে অক্ষরের আকার নয় — গুরুত্ব আর স্তর। ঠিক যেমন একটি পরীক্ষার খাতায় প্রশ্ন নম্বর ১, তার ভেতরে (ক), (খ), আর (ক)-এর ভেতরে (i), (ii).

একটি পাঠ্যবইয়ের কথা ভাবুন। বইয়ের নাম একটিই (h1). তারপর অধ্যায় (h2), অধ্যায়ের ভেতরে অনুচ্ছেদ-শিরোনাম (h3), তার ভেতরে উপ-শিরোনাম (h4). সূচিপত্রটি এই স্তর দেখেই তৈরি হয়। ওয়েবপেজের heading-গুলো মিলে ঠিক এমন একটি অদৃশ্য সূচিপত্র বানায় — একে বলে পেজের রূপরেখা (outline).

নিচের ডায়াগ্রামে একটি “ঢাকার খাবার গাইড” পেজের রূপরেখা ধাপে ধাপে তৈরি হচ্ছে। চতুর্থ ধাপের ভুলটি খেয়াল করুন — এটি বাস্তবে খুবই প্রচলিত।

রূপরেখাপেজের মূল বিষয়
h1  ঢাকার খাবার গাইড
রূপরেখাপ্রধান ভাগগুলো
h1  ঢাকার খাবার গাইড
├─ h2  পুরান ঢাকা
└─ h2  গুলশান-বনানী
রূপরেখাভাগের ভেতরে উপ-ভাগ
h1  ঢাকার খাবার গাইড
├─ h2  পুরান ঢাকা
│  ├─ h3  কাচ্চি বিরিয়ানি
│  └─ h3  বাকরখানি
└─ h2  গুলশান-বনানী
রূপরেখাভুল: ছোট দেখাতে h4
h1  ঢাকার খাবার গাইড
├─ h2  পুরান ঢাকা
│  ├─ h3  কাচ্চি বিরিয়ানি
│  └─ h3  বাকরখানি
└─ h2  গুলশান-বনানী
      └─ h4  খরচ বাঁচানোর টিপস   ← h3 কোথায়?
রূপরেখাঠিক: h3 + CSS দিয়ে আকার
h1  ঢাকার খাবার গাইড
├─ h2  পুরান ঢাকা
│  ├─ h3  কাচ্চি বিরিয়ানি
│  └─ h3  বাকরখানি
└─ h2  গুলশান-বনানী
   └─ h3  খরচ বাঁচানোর টিপস

/* CSS: আকার ছোট চাইলে */
.tips h3 { font-size: 1rem; }
  1. একটি h1 — পেজের নাম। পেজটি কী নিয়ে, তা এক লাইনে বলে <h1>. সাধারণ নিয়ম: প্রতি পেজে একটি h1, আর সেটি সাধারণত <title>-এর কাছাকাছি কথা বলে।
  2. প্রধান ভাগ — h2. পেজের বড় বড় অংশ। খেয়াল করুন, দুটো h2 একই স্তরে — এরা ভাই-বোন, কেউ কারও ভেতরে নয়।
  3. উপ-ভাগ — h3. “পুরান ঢাকা” অংশের ভেতরে দুটি খাবারের আলাদা আলোচনা। পরের h2 আসা মাত্রই আগের h2-এর ভাগ শেষ — heading নিজেই সীমানা টানে।
  4. প্রচলিত ভুল — লেভেল লাফানো। কেউ চাইলেন “টিপস” শিরোনামটি ছোট দেখাক, তাই সরাসরি <h4> লিখলেন। চোখে ঠিকই লাগে, কিন্তু screen reader ব্যবহারকারী শোনেন level 2-এর পরেই level 4 — তাঁর মনে হয় মাঝখানে কিছু হারিয়ে গেছে। Lighthouse-এর মতো টুলও এটিকে সমস্যা হিসেবে দেখায়।
  5. সমাধান — অর্থ অনুযায়ী লেভেল, আকার CSS-এ। স্তর অনুযায়ী এটি h3. ছোট দেখাতে চাইলে CSS-এ font-size বদলান। আর যদি লেখাটি আসলে কোনো ভাগের শিরোনামই না হয় — শুধু মোটা করে লেখা একটি লাইন — তবে heading নয়, <p><strong> ব্যবহার করুন।

Heading-এর তিনটি সোনালি নিয়ম

  • সাধারণত একটি h1. HTML-এর নিয়মে একাধিক h1 লেখা নিষিদ্ধ নয়, কিন্তু একটি h1 রাখলে পেজের মূল বিষয় সবার কাছে — মানুষ, screen reader, সার্চ ইঞ্জিন — পরিষ্কার থাকে। এটাই আজকের প্রচলিত ভালো অভ্যাস।
  • নিচে নামার সময় লেভেল লাফাবেন না। h2-এর পরে h3, তারপর h4. কিন্তু ওপরে ফেরার সময় লাফানো ঠিক আছে — একটি h4-এর পরেই নতুন h2 আসতে পারে, কারণ তখন নতুন বড় ভাগ শুরু হলো।
  • আকারের জন্য heading নয়, অর্থের জন্য heading. শুধু বড় লেখা চাইলে CSS. আর heading-এর ভেতরে পুরো অনুচ্ছেদ বা বোতাম-লেখা ঢোকাবেন না — heading ছোট, নির্দিষ্ট, বর্ণনামূলক হবে।

WebAIM নামের একটি প্রতিষ্ঠান বহু বছর ধরে screen reader ব্যবহারকারীদের ওপর জরিপ করে আসছে। প্রতিবারই দেখা গেছে, লম্বা পেজে তথ্য খুঁজতে তাঁদের বড় অংশ প্রথমে heading ধরে ধরে লাফান। অর্থাৎ আপনার heading-গুলোই তাঁদের কাছে পেজের নেভিগেশন মেনু।

৩ · Paragraph, লাইন ভাঙা আর বিষয় বদল — p, br, hr

<p> হলো paragraph বা অনুচ্ছেদ — একটি ভাবনা বা বিষয় নিয়ে কয়েকটি বাক্যের দল। ব্রাউজার প্রতিটি অনুচ্ছেদের আগে-পরে কিছু ফাঁকা জায়গা রাখে। এই ফাঁকাটি আসে ব্রাউজারের নিজস্ব ডিফল্ট স্টাইল থেকে, যাকে বলে user-agent stylesheet. CSS দিয়ে এটি যেকোনো সময় বদলানো যায়।

এখানে নতুনদের একটি বড় চমক অপেক্ষা করে। HTML কোডে আপনি যত space বা নতুন লাইনই দিন না কেন, ব্রাউজার সাধারণত সব মিলিয়ে একটি space বানিয়ে ফেলে। একে বলে whitespace collapsing. এজন্যই কোডে Enter চাপলে পর্দায় নতুন লাইন আসে না।

  • <br> — লাইন ভাঙা। যেখানে লাইন ভাঙাটাই বিষয়বস্তুর অংশ, সেখানে: কবিতার চরণ, ডাকের ঠিকানা, গানের লাইন। এটি একটি void element — এর কোনো শেষের ট্যাগ নেই।
  • নতুন অনুচ্ছেদ — নতুন <p>. বিষয় বা ভাবনা বদলালে <br><br> নয়, নতুন <p>. ফাঁকা জায়গা বাড়াতে চাইলে CSS-এর margin (পর্ব ১৯)।
  • <hr> — বিষয় বদলের দাগ। নাম শুনে মনে হয় “horizontal rule” বা আনুভূমিক দাগ, আর ব্রাউজার দেখায়ও দাগ হিসেবে। কিন্তু এর আসল অর্থ thematic break — গল্পে দৃশ্য বদল, বা একই অংশে নতুন প্রসঙ্গ। শুধু সাজানোর দাগ চাইলে CSS-এর border.

নিচের এডিটরে কোড বদলালেই ডানে/নিচে ফল বদলাবে। আগে যেমন আছে তেমন দেখুন, তারপর পরীক্ষা করুন:

<p>এই     লাইনে     অনেক      space,
আর কোডে
নতুন লাইনও আছে — কিন্তু পর্দায় সব মিলে একটি space.</p>

<p>আবার আসিব ফিরে ধানসিড়িটির তীরে — এই বাংলায়<br>
হয়তো মানুষ নয় — হয়তো বা শঙ্খচিল শালিখের বেশে;</p>

<p>সভা শেষে সবাই চা খেয়ে বাড়ি ফিরল।</p>
<hr>
<p>পরদিন সকালে স্টেশনে নতুন খবর এলো।</p>

প্রথম অনুচ্ছেদে কোডের সব বাড়তি space আর Enter মিলে একটি করে space হয়ে গেছে। কবিতায় (জীবনানন্দ দাশ) <br> চরণ দুটিকে আলাদা লাইনে রেখেছে — এখানে লাইন ভাঙাটাই কবিতার অংশ। শেষে <hr> দুটি দৃশ্যের মাঝখানে দাগ টেনেছে। চেষ্টা করুন: কবিতার <br> মুছে দিন — চরণ দুটি এক লাইনে মিশে যাবে। তারপর <hr>-এর বদলে দুটি <br> লিখে দেখুন — দাগ নেই, বিষয় বদলের অর্থও নেই।

পুরোনো টিউটোরিয়ালে প্রায়ই দেখবেন, ফাঁকা জায়গা বানাতে <br><br><br> বা খালি <p></p> লেখা হয়েছে। এটি ভুল অভ্যাস: কিছু screen reader প্রতিটি খালি লাইনে “blank” বলে, মোবাইলে দূরত্ব অনিয়ন্ত্রিত হয়, আর নকশা বদলাতে গেলে প্রতিটি পেজ ঘাঁটতে হয়। দূরত্ব = CSS-এর কাজ।

৪ · জোর আর গুরুত্ব — strong, em, b, i, mark, small, s, del, ins

এবার বাক্যের ভেতরের ছোট ছোট অংশ। এগুলো লেখার প্রবাহ ভাঙে না, লাইনের ভেতরেই বসে — তাই এদের প্রচলিত নাম inline element. নতুনদের সবচেয়ে বেশি গুলিয়ে যায় চারটি ট্যাগে: strong, b, em, i. ব্রাউজারে প্রথম দুটি মোটা, পরের দুটি বাঁকা দেখায়। তাহলে পার্থক্য কোথায়?

ট্যাগঅর্থ (HTML Living Standard অনুযায়ী)বাস্তব উদাহরণ
<strong>গুরুত্ব, গাম্ভীর্য বা জরুরি ভাব“সতর্কতা: OTP কাউকে বলবেন না”
<em>কথার জোর (stress) — জোর বদলালে বাক্যের মানে বদলায়“আমি আজ টাকা পাঠাব” বনাম “আমি আজ টাকা পাঠাব”
<b>বাড়তি গুরুত্ব ছাড়াই নজর টানা লেখারিভিউতে পণ্যের নাম, সারাংশের মূল শব্দ
<i>ভিন্ন সুর বা ভিন্ন ধরনের লেখাবৈজ্ঞানিক নাম, বিদেশি শব্দ, জাহাজের নাম, মনের কথা

ধরুন মা ফোনে বলছেন, “বাজার থেকে ইলিশ আনবি” — জোরটা “ইলিশ”-এ, অর্থাৎ অন্য মাছ নয়। আর বাড়ির দরজায় লেখা “কুকুর হইতে সাবধান” — এটি গুরুত্বপূর্ণ সতর্কতা। প্রথমটি em, দ্বিতীয়টি strong. দুটোকেই আপনি “মোটা” বা “বাঁকা” করে লিখতে পারতেন — কিন্তু কাজ ভিন্ন।

<style>
  /* চেহারা CSS-এর কাজ — strong-কে লাল করলাম, b-কে নয় */
  strong { color: #b91c1c; }
</style>

<p><strong>সতর্কতা:</strong> OTP কাউকে বলবেন না।</p>
<p><b>সতর্কতা:</b> OTP কাউকে বলবেন না।</p>

<p>আমি <em>আজ</em> টাকা পাঠাব। (কবে? আজই, কাল নয়)</p>
<p><em>আমি</em> আজ টাকা পাঠাব। (কে? আমি, অন্য কেউ নয়)</p>

<p>ইলিশের বৈজ্ঞানিক নাম <i lang="la">Tenualosa ilisha</i>.</p>
<p>নতুন ফোন <b>Nokshi X2</b>-এর ব্যাটারি দুই দিন চলে।</p>

CSS ছাড়া strong আর b হুবহু একই রকম মোটা দেখায় — এখানে শুধু strong-কে CSS দিয়ে লাল করা হয়েছে, যাতে বোঝা যায় চেহারা আর অর্থ আলাদা জিনিস। em-এর দুটি লাইনে একই শব্দ, শুধু জোরের জায়গা বদলানোয় প্রশ্নের উত্তরই বদলে গেছে। lang="la" জানায় শব্দটি ল্যাটিন — ভালো screen reader তখন সঠিক উচ্চারণে পড়তে পারে। চেষ্টা করুন: <style> অংশটি পুরো মুছে দিন — প্রথম দুই লাইন আলাদা করা যায় কি? তারপর strong-এর জায়গায় b লিখে রংটা কোথায় যায় দেখুন।

সৎভাবে একটি তথ্য জেনে রাখুন: জনপ্রিয় screen reader-গুলো ডিফল্ট সেটিংয়ে সাধারণত strong বা em-এ গলার স্বর বদলায় না। তাহলে কেন এগুলো? কারণ অর্থটি accessibility tree-তে, reader mode-এ, অনুবাদ টুলে, ব্যবহারকারীর নিজের সেটিংয়ে আর ভবিষ্যতের টুলে পৌঁছায়। তবে জীবন-মরণ তথ্য শুধু মোটা বা লাল রঙের ওপর ছাড়বেন না — শব্দেই লিখুন “সতর্কতা:”, যেমন উপরের উদাহরণে।

আরও কিছু ছোট অর্থের ট্যাগ

ট্যাগঅর্থকখন ব্যবহার করবেন না
<mark>এই প্রসঙ্গে প্রাসঙ্গিক বলে চিহ্নিত — যেমন সার্চের শব্দ হাইলাইটশুধু হলুদ ব্যাকগ্রাউন্ডের জন্য (সেটি CSS)
<small>পাশের মন্তব্য, শর্তাবলি, আইনি ছোট লেখাযেকোনো লেখা ছোট দেখাতে
<s>আর সঠিক বা প্রাসঙ্গিক নয় — যেমন পুরোনো দামডকুমেন্টের সম্পাদনা দেখাতে (সেটি del)
<del> / <ins>ডকুমেন্ট থেকে মুছে ফেলা / নতুন যোগ করা অংশ; datetime ও cite attribute নিতে পারেশুধু দাগ টানার সাজ হিসেবে
<sub> / <sup>নিচে-লেখা / ওপরে-লেখা, যার অর্থ আছে — H2O, x2, footnote নম্বরশুধু লেখা ওপরে-নিচে সরাতে
<u>অ-ব্যাখ্যাত টীকা — যেমন বানান ভুল চিহ্নিত করাসাজ হিসেবে — নিচে দাগ দেখে মানুষ লিংক ভাবে
<p>ঈদ অফার: <s>৳১২০০</s> এখন মাত্র ৳৯৯৯ <small>(ভ্যাটসহ)</small></p>

<p>নোটিশ: সভা হবে
  <del datetime="2026-10-10">রবিবার</del>
  <ins datetime="2026-10-12">সোমবার</ins>, সকাল ১০টায়।</p>

<p>খোঁজা শব্দ “ইলিশ” — পদ্মার <mark>ইলিশ</mark> স্বাদে অনন্য।</p>

<p>পানি H<sub>2</sub>O; পিথাগোরাস: a<sup>2</sup> + b<sup>2</sup> = c<sup>2</sup></p>

পুরোনো দামে দাগ (s), ভ্যাটের কথা ছোট (small), নোটিশের সম্পাদনায় মোছা দিন দাগ কাটা আর নতুন দিন নিচে দাগসহ (del/ins), সার্চের শব্দ হলুদ (mark), আর রসায়ন-গণিতের সংখ্যা নিচে-ওপরে। খেয়াল করুন, datetime পর্দায় দেখা যায় না — এটি যন্ত্রের জন্য রাখা তথ্য। চেষ্টা করুন: <sup> মুছে a2 + b2 লিখে দেখুন — অর্থই বদলে যায়। আর <s>-এর আগে “আগের দাম” শব্দটি যোগ করুন: যাঁরা দাগ দেখতে পান না, তাঁদের জন্য এটাই নিরাপদ উপায়।

৫ · বিশেষ অর্থের inline element — উদ্ধৃতি, সংক্ষেপ, সময়, ঠিকানা, সংজ্ঞা

সংবাদপত্রের একটি প্রতিবেদন ভাবুন। তাতে থাকে প্রকাশের সময়, কারও কথার উদ্ধৃতি, সংক্ষিপ্ত নাম, প্রতিবেদকের যোগাযোগ। HTML-এ এগুলোর প্রতিটির জন্য আলাদা ট্যাগ আছে:

❝ q, blockquote, cite

q = লাইনের ভেতরের ছোট উদ্ধৃতি, ব্রাউজার নিজেই উদ্ধৃতিচিহ্ন বসায়। blockquote = আলাদা অংশ জুড়ে বড় উদ্ধৃতি; উৎসের URL থাকে cite attribute-এ। <cite> element = কোনো রচনার নাম — বই, পত্রিকা, সিনেমা, গান।

“দৈনিক উদাহরণ”, “পথের পাঁচালী”

🕒 time

মানুষের জন্য লেখা থাকে “১৯ অক্টোবর, সকাল ৮টা”, আর datetime attribute-এ যন্ত্রের জন্য 2026-10-19T08:00+06:00. এভাবে লেখা তারিখ machine-readable হয়।

<time datetime="...">

🔤 abbr আর dfn

abbr = সংক্ষেপ, পূর্ণরূপ title-এ। dfn = যেখানে কোনো শব্দের সংজ্ঞা দেওয়া হচ্ছে, সেই শব্দ — প্রথমবার পরিচয় করানোর জায়গা।

<abbr title="...">

📮 address

নিকটতম article বা পুরো পেজের যোগাযোগের তথ্য — লেখক বা প্রতিষ্ঠানের ইমেইল, ফোন। যেকোনো ডাকের ঠিকানার জন্য নয়!

লেখকের যোগাযোগ

এবার সব মিলিয়ে একটি ছোট সংবাদ-প্রতিবেদন। <article> হলো নিজে নিজে সম্পূর্ণ একটি লেখার মোড়ক — এর বিস্তারিত পাবেন পর্ব ১০-এ।

<article>
  <h1>শহরে নতুন বাস রুট চালু</h1>
  <p>প্রকাশ: <time datetime="2026-10-19T08:30+06:00">১৯ অক্টোবর ২০২৬, সকাল ৮:৩০</time></p>
  <p><abbr title="নগর পরিবহন সংস্থা">নপস</abbr> জানিয়েছে, নতুন রুট
     <mark>১ নভেম্বর</mark> থেকে চালু হবে।</p>
  <blockquote cite="https://example.com/press">
    <p>যাত্রীদের সময় বাঁচানোই আমাদের লক্ষ্য।</p>
  </blockquote>
  <p>— সংস্থার মুখপাত্র, <cite>দৈনিক উদাহরণ</cite> পত্রিকাকে</p>
  <p>এক যাত্রী বললেন, <q>এবার অফিসে সময়মতো পৌঁছাব।</q></p>
  <p><small>সময়সূচি পরিবর্তন হতে পারে।</small></p>
  <address>প্রতিবেদক: রিয়া সেন ·
    <a href="mailto:news@example.com">news@example.com</a></address>
</article>

কোনো CSS নেই, তবু ব্রাউজার নিজে থেকেই সাজিয়েছে: blockquote ভেতরে সরে বসেছে, q-এর চারপাশে উদ্ধৃতিচিহ্ন এসেছে, cite আর address বাঁকা, mark হলুদ। abbr-এর ওপর মাউস রাখলে পূর্ণরূপ দেখায় — তবে মোবাইলে মাউস নেই, তাই প্রথমবার পূর্ণরূপ লেখায় লিখে দেওয়াই ভালো। চেষ্টা করুন: <q>-এর ভেতরে নিজে “ ” টাইপ করুন — দুই জোড়া উদ্ধৃতিচিহ্ন হয়ে যাবে। তারপর <article>-এ lang="en" যোগ করে দেখুন উদ্ধৃতিচিহ্নের ধরন বদলায় কি না।

দুটি প্রচলিত ভুল। এক, <cite> দিয়ে মানুষের নাম লেখা — WHATWG HTML-এ cite শুধু রচনার নাম; পুরোনো কিছু নির্দেশিকা মানুষের নামও অনুমতি দিত, তাই বিভ্রান্তি। দুই, শুধু ভেতরে সরানোর জন্য blockquote ব্যবহার — ভেতরে সরানো CSS-এর margin/padding-এর কাজ।

৬ · কোড আর কিবোর্ডের ভাষা — code, kbd, samp, var, pre

টেকনিক্যাল লেখায় — এই কোর্সের মতো — চার রকম “কম্পিউটারি” লেখা আসে। দেখতে সবগুলোই সাধারণত monospace (সব অক্ষর সমান চওড়া) ফন্টে, কিন্তু অর্থ আলাদা:

  • <code> — কোডের টুকরো: element-এর নাম, property, ফাংশন, ফাইলের নাম।
  • <kbd> — ব্যবহারকারী যা চাপবেন বা টাইপ করবেন: Ctrl + S, বা টার্মিনালে লেখা কমান্ড।
  • <samp> — প্রোগ্রাম যা দেখাবে: আউটপুট বা error মেসেজ।
  • <var> — গণিত বা প্রোগ্রামের চলক (variable), যেমন সূত্রে x.
  • <pre> — preformatted text: ভেতরের space আর নতুন লাইন হুবহু থাকে, whitespace collapsing হয় না। কোডের কয়েক লাইন দেখাতে নিয়ম হলো <pre><code>…</code></pre> — pre রাখে গঠন, code বলে “এটি কোড”।
<p>সেভ করতে <kbd>Ctrl</kbd> + <kbd>S</kbd> চাপুন।</p>
<p>Terminal-এ লিখুন <kbd>git --version</kbd>, উত্তর আসবে
   <samp>git version 2.47.0</samp>-এর মতো কিছু।</p>
<p>CSS-এর <code>color</code> property লেখার রং বদলায়।</p>
<p>আয়তক্ষেত্রের ক্ষেত্রফল <var>A</var> = <var>l</var> × <var>w</var></p>

<pre><code>function greet(name) {
    return "Hello, " + name;
}</code></pre>

<p>function greet(name) {
    return "Hello, " + name;
}</p>

প্রথম চার লাইনে kbd, samp, code monospace ফন্টে, আর var বাঁকা। আসল শিক্ষাটা নিচে: একই ফাংশন <pre>-এর ভেতরে তিন লাইনে, সুন্দর indentation-সহ; কিন্তু সাধারণ <p>-এ সব এক লাইনে গলে গেছে। চেষ্টা করুন: <pre>-এর ভেতরে return-এর আগে আরও কয়েকটি space দিন — ঠিক ততটাই সরে যাবে। তারপর <code> ট্যাগ দুটি মুছে দেখুন — চেহারায় পার্থক্য প্রায় নেই, কিন্তু “এটি কোড” তথ্যটি হারাল।

<pre>-এর একটি সূক্ষ্ম নিয়ম: শুরুর ট্যাগের ঠিক পরের একটি নতুন লাইন ব্রাউজার বাদ দেয়, যাতে আপনি <pre> লিখে Enter চেপে কোড শুরু করতে পারেন। আর মনে রাখুন, pre-এর ভেতরেও HTML ট্যাগ কাজ করে — তাই কোডে < থাকলে তাকে character reference দিয়ে লিখতে হয়, যা আমরা অংশ ৮-এ দেখব।

৭ · span, block আর inline — HTML-এর content category বনাম CSS-এর display

এতক্ষণ যত ট্যাগ দেখলেন, সবগুলোর কোনো না কোনো অর্থ আছে। কিন্তু কখনো কখনো আপনার শুধু একটি “হাতল” দরকার — লেখার একটি অংশকে ধরে CSS দিয়ে রং দিতে, বা JavaScript দিয়ে বদলাতে, অথচ সেই অংশের বিশেষ কোনো অর্থ নেই। তখন <span>. এটি HTML-এর অর্থহীন inline মোড়ক — screen reader, সার্চ ইঞ্জিন কারও কাছে কিছু বলে না। লাইনের বাইরে বড় অংশের জন্য একই রকম অর্থহীন মোড়ক হলো <div>.

প্রথমে খুঁজুন: এই অংশের জন্য অর্থবহ ট্যাগ আছে কি?
নেই? তাহলে লাইনের ভেতরে span, বড় অংশে div.

“Block আর inline” — পুরোনো নাম, নতুন ধারণা

অনেক বই ও টিউটোরিয়ালে পড়বেন: HTML element দুই রকম — block-level (নতুন লাইনে শুরু হয়, পুরো প্রস্থ নেয়: p, h1, div) আর inline (লাইনের ভেতরে বসে: span, strong, a). এই ভাগটি এসেছে HTML 4 থেকে, আর চোখে দেখা আচরণ হিসেবে এখনো কাজের।

কিন্তু আজকের HTML দুটি আলাদা প্রশ্নকে আলাদা করেছে:

HTML-এর প্রশ্ন: কোথায় বসতে পারে?

HTML Living Standard element-কে ভাগ করে content category দিয়ে। সবচেয়ে কাজের দুটি: flow content (body-তে বসার মতো প্রায় সব কিছু) আর phrasing content (লেখার লাইনের ভেতরের জিনিস — strong, em, span, code…)। নিয়ম যেমন: <p>-এর ভেতরে শুধু phrasing content বসতে পারে।

গঠনের নিয়ম — CSS বদলায় না

CSS-এর প্রশ্ন: কীভাবে সাজবে?

নতুন লাইনে শুরু হবে কি না, পুরো প্রস্থ নেবে কি না — এটি ঠিক করে CSS-এর display property. ব্রাউজারের ডিফল্ট স্টাইলে p-এর display: block, span-এর display: inline. আপনি CSS দিয়ে যেকোনোটা উল্টে দিতে পারেন।

চেহারার নিয়ম — পর্ব ২৩-এ বিস্তারিত

নিচের CSS এডিটরে HTML স্থির, শুধু CSS বদলাচ্ছেন। দেখুন display বদলালে চেহারা কতটা উল্টে যায়:

p, div {
  outline: 2px dashed #2563eb;
  margin: 8px 0;
}
span, strong {
  background: #fde68a;
}

/* চেহারা উল্টে দিলাম — অর্থ কিন্তু একই রইল */
span { display: block; }
div  { display: inline; }

নীল দাগ দেখাচ্ছে প্রতিটি বাক্স কতটা জায়গা নিয়েছে। span এখন নিজের লাইনে পুরো প্রস্থ নিয়েছে, আর দুটি div পাশাপাশি এক লাইনে বসেছে — একেবারে উল্টো আচরণ! কিন্তু HTML-এর নিয়ম বদলায়নি: span এখনো phrasing content, অর্থহীন; আর p-এর ভেতরে div বসানো এখনো নিষেধ। চেষ্টা করুন: শেষ দুই লাইন মুছে ব্রাউজারের ডিফল্ট আচরণ দেখুন। তারপর strong { display: block; } যোগ করুন।

আরও গভীরে: <p>-এর ভেতরে <div> লিখলে ব্রাউজার error দেখায় না — HTML parser নিয়ম মেনে চুপচাপ মেরামত করে। <div> আসামাত্র সে খোলা <p>-টিকে বন্ধ করে দেয়, আর পরে আসা একাকী </p> থেকে একটি নতুন খালি <p></p> বানায়। ফলে DOM-এ আপনার লেখা কোড আর আসল গঠন আলাদা হয়ে যায় — CSS ও JavaScript হঠাৎ “ভুল” আচরণ করে। এই error-সংশোধনের নিয়মগুলো HTML5-এ প্রথমবার সব ব্রাউজারের জন্য একইভাবে লিখে দেওয়া হয়েছিল; আগে প্রতিটি ব্রাউজার নিজের মতো আন্দাজ করত। আর CSS-এ এখন display: block flow-এর মতো দুই-শব্দের লেখাও আছে (Baseline 2023 থেকে সব প্রধান ব্রাউজারে), যা “বাইরে কেমন বসবে” আর “ভেতরে কীভাবে সাজাবে” আলাদা করে বলে — তবে এক-শব্দের display: block সবখানে চলে, সেটিই যথেষ্ট।

৮ · Character reference — &lt;, &amp;, &nbsp; আর UTF-8-এ সরাসরি বাংলা

একটি সমস্যা ভাবুন। আপনি একটি টিউটোরিয়াল লিখছেন: “অনুচ্ছেদের জন্য <p> ট্যাগ লিখুন।” কিন্তু ব্রাউজার <p> দেখলেই ভাবে এটি আসল ট্যাগ! লেখাটি পর্দা থেকে উধাও হয়, নতুন অনুচ্ছেদ শুরু হয়ে যায়। তাহলে < চিহ্নটি “শুধু চিহ্ন” হিসেবে দেখাবেন কীভাবে?

সমাধান character reference (পুরোনো নাম “HTML entity”) — & দিয়ে শুরু, ; দিয়ে শেষ হওয়া একটি সংকেত, যা ব্রাউজারকে বলে “এখানে এই অক্ষরটি বসাও, ট্যাগ হিসেবে পড়ো না”। নিচের ধাপে প্রতিটি সংকেত দেখুন:

&lt; &gt; &amp; &nbsp; &copy; &#x9F3;
  1. &lt; → < — “less than”, অর্থাৎ ছোট চিহ্ন। লেখার ভেতরে < দেখাতে এটি অবশ্যই লাগে, কারণ এই চিহ্ন দিয়েই ট্যাগ শুরু হয়। “5 < 7” লিখতে কোডে লিখুন 5 &lt; 7.
  2. &gt; → > — “greater than”, বড় চিহ্ন। লেখার ভেতরে > একা থাকলে আসলে সমস্যা হয় না, তবু কোড দেখানোর সময় জোড়ায় লেখাই প্রচলিত — &lt;p&gt;.
  3. &amp; → & — ampersand নিজেই reference শুরু করে, তাই “চা & বিস্কুট” লিখতে &amp; নিরাপদ। URL-এর ভেতরেও (?a=1&amp;b=2) একই নিয়ম। এখান থেকেই বুঝবেন &lt; লেখাটা পর্দায় দেখাতে হলে কোডে লিখতে হয় &amp;lt;!
  4. &nbsp; → ভাঙে না এমন space — non-breaking space (nbsp). দুই শব্দের মাঝে লাইন ভাঙতে দেয় না, collapsing-এও হারায় না: ১০&nbsp;কেজি, ৳&nbsp;৫০০ — যাতে সংখ্যা এক লাইনে, একক পরের লাইনে চলে না যায়। কিন্তু ফাঁকা জায়গা বানাতে পরপর অনেক &nbsp; নয় — সেটি CSS-এর কাজ।
  5. &copy; → © — নাম দিয়ে লেখা (named) reference. HTML-এ এমন দুই হাজারেরও বেশি নাম আছে: &mdash; (—), &times; (×), &hellip; (…)। তবে UTF-8 পেজে © চিহ্নটি সরাসরি টাইপ বা পেস্ট করলেও হুবহু একই ফল।
  6. &#x9F3; → ৳ — সংখ্যা দিয়ে লেখা (numeric) reference: &#x-এর পরে Unicode-এর hex নম্বর, বা &#2547;-এর মতো দশমিক নম্বর। টাকার চিহ্ন ৳ হলো Unicode-এর U+09F3. কিন্তু আজকের UTF-8 পেজে সরাসরি “৳” লেখাই সেরা — পড়তে সহজ, সার্চে খুঁজে পাওয়াও সহজ।
<p>ভুল: অনুচ্ছেদের ট্যাগ হলো <p> — লেখাটা কোথায় গেল?</p>
<p>ঠিক: অনুচ্ছেদের ট্যাগ হলো &lt;p&gt; — এখন দেখা যাচ্ছে।</p>

<pre><code>&lt;p class="offer"&gt;
  চা &amp;amp; বিস্কুট — মাত্র ৳৩০
&lt;/p&gt;</code></pre>

<p>5 &lt; 7 &amp;&amp; 9 &gt; 3</p>
<p>১০&nbsp;কেজি চাল · &copy; ২০২৬ ABCL TECH</p>
<p>টাকা: ৳ (সরাসরি) = &#x9F3; (hex) = &#2547; (দশমিক)</p>

প্রথম লাইনে <p> লেখাটি অদৃশ্য — ব্রাউজার একে নতুন অনুচ্ছেদ ধরে নিয়ে লাইনটিকেই দুই ভাগ করে ফেলেছে। দ্বিতীয় লাইনে &lt;p&gt; ঠিকঠাক চিহ্ন হিসেবে দেখা যাচ্ছে। pre-এর ভেতরের কোডে &amp;amp; পর্দায় হয়েছে &amp; — কোড দেখাতে গেলে এমন “দুই স্তরের” লেখা লাগে। শেষ লাইনে তিনভাবে লেখা টাকার চিহ্ন হুবহু এক। চেষ্টা করুন: &nbsp;-কে সাধারণ space করে প্রিভিউ সরু করে দেখুন — “১০” আর “কেজি” আলাদা লাইনে যেতে পারে। তারপর &copy;-এর ; মুছে দেখুন — পুরোনো পাতার খাতিরে ব্রাউজার কিছু পরিচিত নাম সেমিকোলন ছাড়াও চিনে নেয়, কিন্তু validator একে error ধরে, তাই ; সবসময় লিখুন।

Unicode আর UTF-8 ব্যাপক হওয়ার আগে ওয়েবে বাংলা লেখার কোনো মানসম্মত উপায় ছিল না। অনেক বাংলা ওয়েবসাইট বিশেষ ASCII-ভিত্তিক ফন্ট ব্যবহার করত — আসলে ইংরেজি অক্ষর রাখা হতো, ফন্ট সেগুলোকে বাংলার মতো আঁকত। ফলে সেই ফন্ট না থাকলে পেজ হিজিবিজি দেখাত, আর সার্চ ইঞ্জিন বাংলা শব্দ খুঁজেই পেত না। আজ Unicode-এ বাংলার নিজস্ব ব্লক আছে (U+0980 থেকে U+09FF), আর W3Techs-এর হিসাবে ৯৮ শতাংশেরও বেশি ওয়েবসাইট UTF-8 ব্যবহার করে। বিস্তারিত দেখুন বাংলা টাইপিং ও Unicode পর্বে, আর এই কোর্সের পর্ব ১৪-তে।

আজকের নিয়ম

<meta charset="utf-8"> রাখুন, ফাইল UTF-8-এ সেভ করুন, তারপর বাংলা, ৳, ©, — সব সরাসরি লিখুন। Character reference লাগবে কেবল তিন ক্ষেত্রে: (১) লেখায় < আর &, (২) attribute-এর মানের ভেতরে একই রকম উদ্ধৃতিচিহ্ন (&quot;), (৩) চোখে দেখা যায় না এমন অক্ষর — &nbsp;, বা বাংলায় “র‍্যাব”-এর মতো শব্দে র-ফলার রূপ ঠিক রাখা zero width joiner &zwj;.

পরীক্ষা ও ইন্টারভিউতে — এ ধরনের প্রশ্ন প্রায়ই আসে:

  • <strong> আর <b>-এর পার্থক্য কী? strong গুরুত্ব বা জরুরি ভাব বোঝায়; b বাড়তি গুরুত্ব ছাড়াই নজর টানে। দেখতে এক, অর্থ আলাদা।
  • Semantic HTML কেন জরুরি? অ্যাক্সেসিবিলিটি (screen reader), সার্চ ইঞ্জিনের বোঝাপড়া, রক্ষণাবেক্ষণ সহজ, আর ব্রাউজারের ডিফল্ট আচরণ বিনামূল্যে।
  • Heading-এর ক্রম ভাঙলে কী সমস্যা? পেজের রূপরেখা ভেঙে যায়; screen reader ব্যবহারকারী মনে করেন অংশ হারিয়েছে; Lighthouse-এর অ্যাক্সেসিবিলিটি অডিটে ধরা পড়ে।
  • Block আর inline element কী? পুরোনো ভাগ: নতুন লাইনে শুরু হওয়া বনাম লাইনের ভেতরে বসা। আজ এটি CSS-এর display; HTML ব্যবহার করে content category — flow ও phrasing.
  • HTML-এ “<” কীভাবে দেখাবেন? &lt; (বা &#60;) লিখে।

৯ · AI-এর যুগে — অর্থবহ HTML যাচাইয়ের কৌশল

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

AI-এর লেখা HTML-এ যে ভুলগুলো প্রায়ই থাকে

AI-এর ভুলকেন সমস্যাঠিক উপায়
সব কিছু div আর span দিয়ে (“div soup”)কোনো অর্থ নেই; screen reader-এর কাছে শুধু লেখার স্তূপheading, p, strong, time…
শিরোনাম বানাতে <div class="title"> বা <b>রূপরেখায় heading নেইh1–h6
ছোট দেখাতে h2-এর পরে সরাসরি h5লেভেল লাফানোক্রম ঠিক রেখে CSS-এ font-size
দূরত্বের জন্য <br><br> বা অনেক &nbsp;নকশা ভঙ্গুর, অ্যাক্সেসিবিলিটি খারাপCSS margin/gap
কোডের নমুনায় < escape করেনিনমুনা কোড পর্দায় অদৃশ্য বা পেজ ভেঙে যায়&lt;, &amp;
<center>, <font>, <u> সাজ হিসেবেobsolete বা ভুল অর্থCSS দিয়ে চেহারা

AI-কে কাজ দেওয়ার সময় শর্তগুলো আগেই বলে দিন, আর তাকে নিজের পছন্দের ব্যাখ্যা দিতে বাধ্য করুন — এতে ভুল লুকানোর জায়গা কমে:

একটি বাংলা সংবাদ-প্রতিবেদনের HTML লিখে দাও (শিরোনাম, প্রকাশের সময়, ৩টি অনুচ্ছেদ, একজনের উদ্ধৃতি, প্রতিবেদকের ইমেইল)। শর্ত: ১. শুধু semantic HTML — div বা span ব্যবহার করবে না, যদি অর্থবহ কোনো ট্যাগ থাকে। ২. একটি h1, heading-এর লেভেল লাফাবে না। ৩. সময়ের জন্য time আর datetime, উদ্ধৃতির জন্য blockquote বা q. ৪. কোনো CSS বা inline style দেবে না, br দিয়ে দূরত্ব বানাবে না। ৫. কোডের শেষে একটি তালিকা দাও: প্রতিটি ট্যাগ কেন বেছেছ, এক লাইনে।

AI-এর HTML হাতে পেলে — যাচাইয়ের চেকলিস্ট

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

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

প্র ০১<font> আর <center> বাতিল হলো, অথচ <b> আর <i> নতুন অর্থ পেয়ে টিকে গেল — কেন?

HTML 4-এর যুগে b আর i ছিল খাঁটি চেহারার ট্যাগ — “মোটা করো”, “বাঁকা করো”। যুক্তি অনুযায়ী এদেরও font-এর মতো বাতিল হওয়ার কথা। কিন্তু HTML5-এর নকশাকারীরা অন্য পথ নিলেন, আর তার পেছনে ছিল ওয়েবের একটি মৌলিক নীতি: “ওয়েব ভাঙা যাবে না”।

  • কোটি কোটি পুরোনো পেজ: ইন্টারনেটে অগণিত পেজে b আর i আছে। ব্রাউজার এগুলো দেখানো বন্ধ করলে সেই পেজগুলো ভেঙে যেত। তাই ব্রাউজার এদের সমর্থন কখনো বন্ধ করবে না — প্রশ্নটা ছিল শুধু “spec-এ এদের কী বলা হবে”।
  • বাস্তব প্রয়োজন: নকশাকারীরা লক্ষ করলেন, কিছু লেখার প্রচলিত রীতিতে বাঁকা বা মোটা হরফ লাগে, অথচ সেখানে “গুরুত্ব” বা “জোর” নেই — জীববিজ্ঞানের নাম (Tenualosa ilisha), জাহাজের নাম, বিদেশি শব্দ, প্রতিবেদনের প্রথম লাইনের মূল শব্দ। em দিয়ে এগুলো লিখলে ভুল অর্থ হতো।
  • “Paving the cowpaths”: HTML5-এর একটি ঘোষিত নীতি ছিল — মানুষ যে পথে হাঁটে, সেখানেই রাস্তা পাকা করো। অর্থাৎ বাস্তবে যা চলছে, তাকে একটি পরিষ্কার অর্থ দাও।

অন্যদিকে font বা center-এর কোনো যুক্তিসঙ্গত অর্থ খুঁজে পাওয়া যায়নি — এরা ছিল শুধুই চেহারা, যা CSS আরও ভালোভাবে করে। তাই এরা obsolete হলো: ব্রাউজার পুরোনো পেজের জন্য এখনো দেখায়, কিন্তু নতুন কোডে লেখা নিষেধ, validator error দেখায়। একই কারণে small, s, u-ও নতুন অর্থ পেয়েছে।

মূল উপলব্ধি: ওয়েবের মান (standard) শূন্য থেকে নকশা করা হয় না — বাস্তবের লক্ষ কোটি পেজের সাথে আপস করে এগোয়। তাই কোনো ট্যাগের নাম দেখে নয়, আজকের spec-এ তার অর্থ দেখে সিদ্ধান্ত নিন।

প্র ০২HTML spec-এ একসময় “outline algorithm” ছিল, যাতে প্রতিটি section-এ h1 লেখা যেত। সেটি কেন বাদ গেল, আর এ থেকে কী শেখার আছে?

HTML5-এর প্রথম দিকের খসড়ায় একটি সুন্দর ধারণা ছিল: heading-এর লেভেল ঠিক হবে নিজের সংখ্যা দেখে নয়, বরং section, article-এর মতো element কতটা গভীরে আছে তা দেখে। তাহলে প্রতিটি অংশে শুধু h1 লিখলেই চলবে, আর এক পেজের অংশ অন্য পেজে বসালেও লেভেল নিজে থেকে ঠিক হয়ে যাবে — অনেকটা Word-এর স্বয়ংক্রিয় সূচিপত্রের মতো।

সমস্যা হলো, কোনো ব্রাউজার বা screen reader এটি কখনো সত্যিকারভাবে বাস্তবায়ন করেনি। ব্রাউজার শুধু চেহারার জন্য section-এর ভেতরের h1-কে কিছুটা ছোট দেখাত। ফলে যাঁরা spec পড়ে বিশ্বাস করে সব জায়গায় h1 লিখেছিলেন, তাঁদের পেজ screen reader-এ শোনাত “level 1, level 1, level 1…” — রূপরেখা একেবারে সমতল। Accessibility বিশেষজ্ঞরা বছরের পর বছর এ নিয়ে সতর্ক করেছেন। শেষে ২০২২ সালে WHATWG spec থেকে অ্যালগরিদমটি সরিয়ে দেওয়া হয়, আর ব্রাউজারগুলোও section-এর ভেতরের h1-এর সেই বিশেষ ডিফল্ট স্টাইল ধীরে ধীরে তুলে নিচ্ছে।

এখান থেকে তিনটি শিক্ষা:

  • Spec আর বাস্তব এক নয়: কোনো ফিচার কাগজে থাকা মানেই ব্যবহারকারীর কাছে পৌঁছানো নয়। এজন্যই এই কোর্সে বারবার Baseline আর ব্রাউজার সাপোর্টের কথা বলা হবে।
  • আসল টুলে পরীক্ষা করুন: NVDA (Windows-এ ফ্রি), VoiceOver (Mac/iPhone-এ বিল্ট-ইন) বা TalkBack (Android) দিয়ে নিজের পেজ একবার শুনে দেখুন।
  • সহজ নিয়মই নিরাপদ: heading-এর সংখ্যা দিয়েই লেভেল বোঝান — h1, তারপর h2, h3.

মূল উপলব্ধি: ভালো ডেভেলপার spec পড়েন, কিন্তু বিশ্বাস করেন পরীক্ষাকে। “নিয়মে আছে” আর “সবার জন্য কাজ করে” — দুটো আলাদা প্রশ্ন।

প্র ০৩Screen reader যদি ডিফল্টভাবে strong আর em আলাদা করে না পড়ে, তাহলে এগুলো ব্যবহারের আসল লাভটা কী?

প্রশ্নটা খুবই ন্যায্য, আর এর উত্তর semantic HTML সম্পর্কে একটি পরিণত দৃষ্টিভঙ্গি শেখায়। সত্যি কথা হলো, NVDA বা JAWS-এর মতো জনপ্রিয় screen reader ডিফল্ট সেটিংয়ে সাধারণত জোর বা গুরুত্ব আলাদা স্বরে ঘোষণা করে না — কারণ ওয়েবে এগুলোর এত ভুল ব্যবহার, যে প্রতিবার ঘোষণা করলে শোনার অভিজ্ঞতা ক্লান্তিকর হয়ে যেত। তবু লাভ অনেক:

  • অর্থটি সংরক্ষিত থাকে: ব্রাউজার DOM থেকে accessibility tree বানায়, আর সেখানে strong/emphasis তথ্য পৌঁছায়। ব্যবহারকারী চাইলে সেটিং বদলে ঘোষণা চালু করতে পারেন; ব্রেইল ডিসপ্লেও কিছু ক্ষেত্রে চিহ্ন দেখাতে পারে।
  • অন্য পাঠকেরা: reader mode, ইমেইল বা ডকুমেন্টে কপি-পেস্ট, অনুবাদ টুল, সার্চ ইঞ্জিন, AI সারাংশ — সবাই কাঠামো পড়ে। কপি করে Word-এ পেস্ট করলেও জোরটা থেকে যায়।
  • CSS-এর ভরসাযোগ্য হাতল: নকশা বদলালে “সব গুরুত্বপূর্ণ লেখা লাল” — এক লাইনের CSS. b আর strong মিশিয়ে লিখলে কোনটা গুরুত্বপূর্ণ, আলাদা করা যেত না।
  • ভবিষ্যৎ: ARIA-র নতুন সংস্করণে strong ও emphasis-এর জন্য role যোগ হয়েছে — অর্থাৎ সহায়ক প্রযুক্তি এগুলোকে আরও গুরুত্ব দিচ্ছে। আজ সঠিক লিখলে কালকের টুল তা কাজে লাগাবে।

তবে এর একটি দায়িত্বও আছে: যেহেতু জোর সবসময় ঘোষিত হয় না, তাই অত্যাবশ্যক তথ্য শুধু চিহ্নের ওপর ছাড়বেন না। “জরুরি: আজ রাত ১২টার আগে ফি জমা দিন” — এখানে “জরুরি” শব্দটিই কাজ করছে, strong তার সাথে বাড়তি স্তর।

মূল উপলব্ধি: Semantic HTML কোনো একটি টুলের জন্য নয় — এটি তথ্যকে এমনভাবে লেখা, যাতে আজকের ও ভবিষ্যতের যেকোনো পাঠক অর্থ বের করতে পারে। আর অ্যাক্সেসিবিলিটি মানে সতর্ক পরিকল্পনা — একাধিক সংকেত, কোনো একটির ওপর পুরো ভরসা নয়।

প্র ০৪&nbsp;&nbsp;&nbsp; দিয়ে ফাঁক আর <br><br> দিয়ে দূরত্ব — পুরোনো টিউটোরিয়ালে প্রচুর দেখা যায়। আজকের দৃষ্টিতে এর সমস্যা কোথায়, আর &nbsp;-এর সঠিক জায়গা কোথায়?

১৯৯০-এর দশকে CSS ছিল না বা খুব দুর্বল ছিল, তাই ডেভেলপাররা HTML দিয়েই চেহারা বানাতেন: ফাঁকা জায়গার জন্য &nbsp;-এর সারি, নিচে নামাতে কয়েকটা <br>, এমনকি স্বচ্ছ ১×১ পিক্সেলের ছবি (“spacer GIF”). সেই কোড আজও অনেক ব্লগে, পুরোনো বইয়ে, আর তাদের থেকে শেখা AI-এর উত্তরে রয়ে গেছে। আজ এর সমস্যা চারটি:

  • রেসপন্সিভ নকশা ভাঙে: ডেস্কটপে মাপা দশটা nbsp ছোট ফোনে লাইন উপচে দেয় বা অদ্ভুত ফাঁক তৈরি করে। CSS-এর margin, padding, gap পর্দার আকার অনুযায়ী মানিয়ে নিতে পারে (পর্ব ৩০)।
  • অ্যাক্সেসিবিলিটি: খালি লাইন বা অর্থহীন ফাঁক screen reader-এ “blank” হিসেবে শোনা যেতে পারে, বা লেখার প্রবাহ ভেঙে দেয়।
  • রক্ষণাবেক্ষণ: দূরত্ব বদলাতে হলে প্রতিটি পেজের প্রতিটি br খুঁজতে হয়; CSS-এ এক লাইনে হয়।
  • লেখার মান: কপি করা, সার্চ বা অনুবাদের সময় এই বাড়তি অক্ষরগুলো ঝামেলা করে।

তাহলে &nbsp; কি বাদ? না — এর একটি সত্যিকারের কাজ আছে: যে দুটি শব্দ কখনো আলাদা লাইনে যাওয়া উচিত নয়, তাদের জোড়া রাখা। যেমন “১০&nbsp;কেজি”, “৳&nbsp;৫০০”, “পৃষ্ঠা&nbsp;১২”, “Dr.&nbsp;Rahman” — নইলে লাইনের শেষে “১০” আর পরের লাইনের শুরুতে “কেজি” পড়লে পড়তে অস্বস্তি হয়। মুদ্রণশিল্পে এই রীতি বহু পুরোনো। একই কারণে <br>-এরও বৈধ জায়গা আছে — কবিতা, ঠিকানা — যেখানে লাইন ভাঙাটাই বিষয়বস্তু।

মূল উপলব্ধি: প্রশ্ন সবসময় একটাই — “এটি কি বিষয়বস্তুর অংশ, নাকি চেহারার?” বিষয়বস্তু হলে HTML, চেহারা হলে CSS. এই একটি প্রশ্ন দিয়ে HTML-CSS-এর প্রায় সব “কোনটা লিখব” দ্বিধা মেটানো যায়।

প্র ০৫আগে ওয়েবে বাংলা লিখতে অনেকে প্রতিটি অক্ষর numeric reference দিয়ে লিখতেন। আজ কেন সরাসরি UTF-8-এ লেখা উচিত — আর reference কোথায় এখনো অপরিহার্য?

Unicode আসার আগে কম্পিউটারের অক্ষর-তালিকা (encoding) ছিল অঞ্চলভিত্তিক আর ছোট — বেশিরভাগই ইংরেজি অক্ষরের জন্য বানানো। বাংলার জন্য সর্বজনীন কোনো মান ছিল না, তাই একসময় অনেক বাংলা ওয়েবসাইট নিজস্ব ASCII-ভিত্তিক ফন্টের ওপর নির্ভর করত: ফাইলে আসলে থাকত ইংরেজি অক্ষর, বিশেষ ফন্ট সেগুলোকে বাংলার মতো আঁকত। ফন্ট না থাকলে পাঠক দেখতেন হিজিবিজি, আর সার্চ ইঞ্জিন “ঢাকা” খুঁজে পেত না, কারণ ফাইলে “ঢাকা” লেখাই ছিল না।

Unicode সমস্যার মূল সমাধান করে — বাংলার প্রতিটি অক্ষর পায় একটি স্থায়ী নম্বর (যেমন ক = U+0995). এরপর কেউ কেউ ঝুঁকি এড়াতে বাংলা লিখতেন &#2453;-এর মতো numeric reference দিয়ে, যাতে ফাইলের encoding যা-ই হোক, লেখা ঠিক দেখায়। কিন্তু এতে HTML ফাইল কয়েক গুণ বড় হয়, কোড পড়া প্রায় অসম্ভব, আর এক অক্ষর বদলাতেও নম্বর খুঁজতে হয়।

আজ পরিস্থিতি বদলেছে। UTF-8 হলো Unicode লেখার এমন একটি পদ্ধতি, যা ইংরেজির জন্য পুরোনো ASCII-র সাথে হুবহু মেলে, আবার পৃথিবীর সব লিপি ধারণ করে। HTML spec নিজেই নতুন ডকুমেন্টে UTF-8 বাধ্যতামূলক করেছে, আর প্রায় সব ওয়েবসাইট এখন UTF-8-এ। তাই নিয়ম সহজ: <meta charset="utf-8"> রাখুন <head>-এর একেবারে শুরুতে, এডিটরে ফাইল UTF-8-এ সেভ করুন, তারপর বাংলা সরাসরি লিখুন।

Reference এখনো অপরিহার্য যেখানে: (১) < আর &-এর মতো HTML-এর নিজের বিশেষ চিহ্ন; (২) চোখে দেখা যায় না এমন অক্ষর — nbsp, আর বাংলায় গুরুত্বপূর্ণ zero width joiner (&zwj;) ও zero width non-joiner (&zwnj;), যা যুক্তাক্ষর বা ফলার রূপ নিয়ন্ত্রণ করে। কোডে এগুলো সরাসরি থাকলে দেখা যায় না, তাই reference দিয়ে লিখলে পরে বোঝা সহজ।

মূল উপলব্ধি: টেকনোলজির ইতিহাসে বাংলা অনেক দিন “অতিথি” ছিল; Unicode আর UTF-8 তাকে সমান নাগরিক বানিয়েছে। ওয়েবে বাংলার পুরো গল্প — ফন্ট, lang, টাইপোগ্রাফি — আসছে পর্ব ১৪-তে।

অনুশীলন

বেশিরভাগ কাজে ভাবা আর দেখা — একটিতে নিজে কোড লিখবেন।

  1. ঠিক ট্যাগটি বাছুন: নিচের প্রতিটির জন্য কোন element? (ক) অনলাইন দোকানে পুরোনো দাম (খ) “Ctrl + P চাপুন”-এর Ctrl আর P (গ) “পথের পাঁচালী” উপন্যাসের নাম (ঘ) “পাসওয়ার্ড কাউকে দেবেন না” — সতর্কতা (ঙ) “WHO”-এর পূর্ণরূপ (চ) প্রোগ্রামের error মেসেজ

    (ক) <s> — দামটি আর প্রাসঙ্গিক নয়। (খ) <kbd> — ব্যবহারকারী চাপবেন। (গ) <cite> — রচনার নাম। (ঘ) <strong> — গুরুত্বপূর্ণ সতর্কতা। (ঙ) <abbr title="World Health Organization">WHO</abbr>, আর সম্ভব হলে প্রথমবার পূর্ণরূপ লেখাতেই। (চ) <samp> — প্রোগ্রামের আউটপুট। খেয়াল করুন, প্রতিটি উত্তর এসেছে “এটি কী?” প্রশ্ন থেকে, “দেখতে কেমন?” থেকে নয়।

  2. একটি আসল সাইটের রূপরেখা দেখুন: যেকোনো সংবাদ-সাইটের একটি প্রতিবেদন খুলুন, F12 চেপে DevTools-এর Console-এ নিচের লাইনটি লিখে Enter চাপুন। কয়টি h1 পেলেন? লেভেল কোথাও লাফিয়েছে কি?
    $$('h1,h2,h3,h4,h5,h6').map(h => h.tagName + ' ' + h.textContent.trim().slice(0, 40))

    $$ হলো DevTools Console-এর একটি সুবিধা — CSS selector দিয়ে মেলে এমন সব element-এর তালিকা দেয়। ফলাফলে প্রায়ই অবাক হবেন: অনেক বড় সাইটেও h1 নেই বা একাধিক, লোগোকে h1 বানানো, সাইডবারের “জনপ্রিয় খবর” h2 থেকে সরাসরি h4, এমনকি ফাঁকা heading. বড় সাইট মানেই নির্ভুল HTML নয় — নিজের চোখে যাচাই করার অভ্যাসটাই এখানে আসল শিক্ষা। Chrome বা Edge-এর Elements প্যানেলে Accessibility অংশে প্রতিটি heading-এর role ও level-ও দেখা যায়।

  3. div soup সারাই করুন: নিচের কোডটি অর্থবহ HTML-এ নতুন করে লিখুন (শুধু HTML, চেহারার কথা ভুলে যান):
    <div class="title">বইমেলা ২০২৬</div>
    <div>মেলা চলবে <span class="bold">১ থেকে ২৮ ফেব্রুয়ারি</span>.</div>
    <br><br>
    <div><span class="red">বিশেষ সতর্কতা:</span> ব্যাগ সাথে রাখুন।</div>
    <div>HTML-এ অনুচ্ছেদ লিখতে <p> লাগে — এই লেখা নিয়ে আলোচনা হবে।</div>

    একটি সম্ভাব্য উত্তর:

    <h1>বইমেলা ২০২৬</h1>
    <p>মেলা চলবে <time datetime="2026-02-01">১</time> থেকে
       <time datetime="2026-02-28">২৮ ফেব্রুয়ারি</time>.</p>
    <p><strong>বিশেষ সতর্কতা:</strong> ব্যাগ সাথে রাখুন।</p>
    <p>HTML-এ অনুচ্ছেদ লিখতে <code>&lt;p&gt;</code> লাগে — এই লেখা নিয়ে আলোচনা হবে।</p>

    শিরোনাম h1, বাক্যগুলো p, তারিখ time, সতর্কতা strong, আর কোডের নাম code-এর ভেতরে escape করা। <br><br> বাদ — দূরত্ব CSS দেবে। “তারিখ” মোটা করা জরুরি না হলে কোনো ট্যাগই দরকার নেই; একান্ত চাইলে b বা CSS-সহ span.

  4. Validator কী বলে: validator.w3.org/nu-এর “Text input”-এ একটি পূর্ণ HTML ডকুমেন্টের body-তে লিখুন <p>নোটিশ <div>আজ ছুটি</div></p> — তারপর Check চাপুন। কোন error এলো, আর কেন?

    Validator জানাবে No p element in scope but a p end tag seen — অর্থাৎ শেষে এমন একটি </p> পাওয়া গেছে, যার মিলের কোনো খোলা <p> নেই। কারণ <div> phrasing content নয়, তাই parser সেটি দেখামাত্র আগের <p> বন্ধ করে দিয়েছিল। ব্রাউজার পেজ ঠিকই দেখায়, কিন্তু DOM-এ তৈরি হয় তিনটি element: “নোটিশ”-ওয়ালা p, তারপর div, তারপর একটি খালি p. সমাধান: বাইরের মোড়ক div করুন, বা ভেতরের div-কে span/strong করুন।

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

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

ক্রমঅর্থবহ HTML লেখার চিন্তার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. 🤔 লেখার অংশটি আসলে কী — শিরোনাম, অনুচ্ছেদ, সতর্কতা, তারিখ?
  2. 🏷️ সেই অর্থের সাথে মেলে এমন element বেছে নেওয়া (না থাকলে span/div)
  3. 📑 heading-এর লেভেল রূপরেখার ক্রম মিলিয়ে বসানো
  4. 🎨 CSS দিয়ে চেহারা — আকার, রং, দূরত্ব
  5. ✅ validator আর DevTools দিয়ে যাচাই

একটি ব্যাংকিং অ্যাপের পেজে লেখা: “PIN কাউকে জানাবেন না।” এটি গুরুত্বপূর্ণ সতর্কতা হিসেবে চিহ্নিত করতে কোন element সবচেয়ে উপযুক্ত?

  • <b>
  • <strong>
  • <mark>
  • <span class="red">

একটি পেজে <h1>-এর পরে একটি <h2> অংশ আছে। তার ভেতরের একটি উপ-শিরোনাম ছোট দেখাতে হবে। সবচেয়ে সঠিক উপায় কোনটি?

  • <h5> ব্যবহার করা, কারণ সেটি ছোট দেখায়
  • heading বাদ দিয়ে <div>-এ ছোট ফন্ট
  • <h3> ব্যবহার করে CSS দিয়ে font-size কমানো
  • আরেকটি <h1> দিয়ে CSS-এ ছোট করা

HTML পেজের লেখায় হুবহু <p> চিহ্নগুলো দেখাতে (ট্যাগ হিসেবে নয়) কোডে কী লিখতে হবে?

  • &lt;p&gt;
  • "<p>"
  • \<p\>
  • <pre><p></pre>

<time datetime="2026-12-16">১৬ ডিসেম্বর</time>-এ datetime attribute-এর মূল উদ্দেশ্য কী?

  • পর্দায় তারিখটি ইংরেজিতে দেখানো
  • পেজে স্বয়ংক্রিয় কাউন্টডাউন চালু করা
  • ব্রাউজারকে তারিখটি বাংলায় অনুবাদ করতে বলা
  • তারিখটিকে যন্ত্রের পড়ার মতো (machine-readable) মানক রূপে দেওয়া

নিচের কোনটি <p> element-এর ভেতরে বৈধভাবে বসতে পারে (phrasing content)?

  • <div>
  • <em>
  • <h2>
  • <blockquote>

“পথের পাঁচালী” উপন্যাসের নাম চিহ্নিত করার জন্য WHATWG HTML অনুযায়ী সঠিক element কোনটি?

  • <i>
  • <q>
  • <cite>
  • <abbr>

শব্দকোষ

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

মনে রাখুন

  1. HTML = অর্থ, CSS = চেহারা। ট্যাগ বাছুন “এটি কী” দেখে — এতে অ্যাক্সেসিবিলিটি, সার্চ আর রক্ষণাবেক্ষণ তিনটিই ভালো হয়।
  2. সাধারণত একটি h1, তারপর ক্রম মেনে h2, h3 — নিচে নামতে লেভেল লাফাবেন না।
  3. নতুন ভাবনা = নতুন p; br শুধু কবিতা-ঠিকানায়; hr মানে বিষয় বদল; দূরত্ব CSS-এ।
  4. strong গুরুত্ব, em জোর, b/i জোর ছাড়া আলাদা লেখা; অর্থ না থাকলে span. Block/inline আজ CSS-এর display, HTML-এর নিয়ম content category.
  5. লেখায় &lt; আর &amp;; UTF-8 পেজে বাংলা ও ৳ সরাসরি; &nbsp; শুধু জোড়া রাখতে।

পরের পর্বে: লেখা তো সাজালেন — এবার এক পেজ থেকে আরেক পেজে যাওয়ার পথ। <a> লিংক, absolute আর relative path, আর একই পেজের ভেতরে নির্দিষ্ট অংশে লাফ দেওয়ার কৌশল।

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

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