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

লিংক আর path — absolute, relative আর পেজের ভেতরে লাফ

Links & Paths — Anchors, URLs, Relative Paths, Fragments and Safe, Accessible Links

Taught in Bangla, this lesson covers HTML links and paths: the anatomy of a URL, writing absolute, relative and root-relative paths from a folder tree, and jumping within a page using fragments, id and :target. It explains email, phone, WhatsApp and download links, opening new tabs safely with rel values such as noopener and sponsored, accessible link text, links versus buttons, the base element trap and finding broken links.

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

  • একটি URL-এর প্রতিটি অংশ চেনা — কোনটি সার্ভারে যায়, কোনটি যায় না
  • ফোল্ডার-গাছ দেখে যেকোনো relative path নির্ভুলভাবে লেখা, আর ভাঙা path-এর কারণ ধরা
  • পাতার ভেতরে লাফের লিংক, ইমেইল-ফোন-ডাউনলোডের লিংক আর নতুন ট্যাবের নিরাপদ নিয়ম
  • SEO-র জন্য rel-এর মান, আর screen reader ব্যবহারকারীর জন্য ভালো লিংক টেক্সট
  • লিংক আর বাটনের পার্থক্য, <base>-এর ফাঁদ আর ভাঙা লিংক খোঁজার পেশাদার উপায়

১ · লিংক — যে জিনিসটি ওয়েবকে “ওয়েব” বানায়

পর্ব ০১-এ দেখেছেন, ব্রাউজার একটি ঠিকানা থেকে HTML ফাইল এনে পাতা আঁকে। কিন্তু একটি পাতা থেকে আরেকটিতে যাওয়ার পথ কে দেখায়? সেই কাজ hyperlink-এর, সংক্ষেপে লিংক। “World Wide Web” নামের “Web” মানে মাকড়সার জাল — কোটি কোটি পাতা, একে অপরের সাথে লিংকের সুতায় বাঁধা। লিংক না থাকলে প্রতিটি পাতা হতো একটি বিচ্ছিন্ন দ্বীপ।

ঢাকার একটি বড় শপিং মলের কথা ভাবুন। প্রতিটি দোকানের একটি নম্বর আছে — “লেভেল ৪, ব্লক বি, দোকান ১২”। মলের গাইড-ম্যাপে কোনো দোকানের নামে আঙুল রাখলেই আপনি জানেন কোথায় যেতে হবে। লিংক ঠিক এই গাইড-ম্যাপের লেখা: ওপরে দোকানের নাম (যা মানুষ পড়ে), ভেতরে দোকানের ঠিকানা (যা ব্রাউজার পড়ে)। ঠিকানা ভুল লিখলে মানুষটি ভুল দোকানে বা বন্ধ শাটারের সামনে গিয়ে দাঁড়াবে — ওয়েবে যার নাম “404 Not Found”.

HTML-এ লিংক বানায় anchor element — <a>. আর ঠিকানাটি থাকে href attribute-এ (পর্ব ০৩-এ attribute চিনেছেন)। href এসেছে “hypertext reference” থেকে।

<a href="https://www.bangladesh.gov.bd/">বাংলাদেশ জাতীয় তথ্য বাতায়ন</a>
  • <a> — একটি inline element (পর্ব ০৪), তাই বাক্যের ভেতরেই বসে। আধুনিক HTML-এ এর ভেতরে পুরো একটি কার্ড, ছবি বা heading-ও রাখা যায় — শর্ত একটাই, ভেতরে আরেকটি লিংক বা বাটন থাকবে না।
  • href — কোথায় যাবে। এটি না থাকলে <a> আর লিংক থাকে না: ক্লিক হয় না, কিবোর্ডের Tab দিয়ে সেখানে পৌঁছানোও যায় না।
  • ভেতরের লেখা — যা দেখা যায়, যাতে ক্লিক করা হয়, আর screen reader যা পড়ে শোনায়। এটি সাজসজ্জা নয়, লিংকের নাম। অংশ ৭-এ এর গুরুত্ব দেখবেন।

ব্রাউজার নিজে থেকে লিংককে নীল রঙে আর নিচে দাগ দিয়ে দেখায়; ঘুরে আসা লিংক হয় বেগুনি। এই চেহারা CSS দিয়ে বদলানো যায় (:hover, :focus-visible আসছে পর্ব ৩৪-এ), কিন্তু একটি নিয়ম মনে রাখুন: লিংক যেন আশপাশের লেখা থেকে শুধু রঙে নয়, দাগ বা অন্য কোনো চিহ্নেও আলাদা বোঝা যায় — যাঁরা রং ভালো দেখেন না, তাঁদের জন্য।

“Hypertext” শব্দটি ১৯৬০-এর দশকে চালু করেন Ted Nelson — এমন লেখা, যার ভেতর থেকে অন্য লেখায় লাফ দেওয়া যায়। ১৯৮৯ সালে CERN-এ Tim Berners-Lee প্রস্তাব দেন hypertext আর ইন্টারনেট জুড়ে দেওয়ার, আর ১৯৯০-৯১ সালে তৈরি হয় প্রথম ওয়েবসাইট। একেবারে প্রথম HTML-এও <a> ছিল। নামটা “anchor” (নোঙর) কেন? তখন একই ট্যাগ দুই কাজ করত — href দিলে লিংকের শুরু, আর name দিলে পাতার ভেতরের একটি নোঙর, যেখানে অন্য লিংক এসে থামবে। আজ দ্বিতীয় কাজটি করে id, কিন্তু নামটি রয়ে গেছে।

২ · URL-এর শরীর — scheme, host, path, query, fragment

href-এ যা লেখেন, তা একটি URL (Uniform Resource Locator) — ওয়েবে যেকোনো জিনিসের ঠিকানা। চিঠির খামের ঠিকানার মতোই এর কয়েকটি অংশ আছে: দেশ, জেলা, থানা, বাড়ি নম্বর, প্রাপকের নাম। নিচের ডায়াগ্রামে একটি অনলাইন দোকানের ঠিকানা ভেঙে দেখুন (amardokan.example একটি কাল্পনিক ঠিকানা)।

https:// shop.amardokan.example :443 /products/rice.html ?size=5kg&brand=chinigura #reviews
  1. Scheme — কোন নিয়মে কথা হবে। https মানে HTTP-র নিরাপদ (এনক্রিপ্ট করা) সংস্করণ। আরও আছে http (পুরোনো, অনিরাপদ), mailto, tel, file. এরপরের // বলে, “এবার একটি সার্ভারের নাম আসছে।”
  2. Host — কোন সার্ভার। এটি domain নাম। ব্রাউজার DNS-কে জিজ্ঞেস করে এর IP ঠিকানা বের করে, তারপর সেই কম্পিউটারের সাথে যোগাযোগ করে। shop. অংশটি একটি subdomain — একই মালিকের আলাদা একটি সাইট।
  3. Port — সার্ভারের কোন দরজা। একটি সার্ভারে অনেক সেবা চলে, প্রতিটির আলাদা দরজা-নম্বর। https-এর ডিফল্ট 443, http-এর 80 — ডিফল্ট হলে ব্রাউজার এটি লুকিয়েই রাখে, তাই সাধারণত চোখে পড়ে না।
  4. Path — সার্ভারের ভেতরে কোন ফাইল বা পাতা। ফোল্ডারের মতো / দিয়ে ভাগ করা। সাধারণ static সাইটে (যেমন cPanel-এ রাখা HTML ফাইল) এটি সত্যিই সার্ভারের ফোল্ডার আর ফাইলের নাম; বড় সাইটে প্রোগ্রাম এটিকে পড়ে ঠিক করে কী দেখাবে।
  5. Query — বাড়তি প্রশ্ন। ? দিয়ে শুরু, নাম=মান জোড়া, মাঝে &. এখানে বলা হচ্ছে “৫ কেজির চিনিগুঁড়া চাল দেখাও।” সার্চের ফল, ফিল্টার, পাতার নম্বর — সব এখানে আসে। পর্ব ০৮-এ দেখবেন, ফর্ম জমা দিলেও এমন query তৈরি হয়।
  6. Fragment — পাতার ভেতরের কোন জায়গা। #-এর পরের অংশ। এটি কখনো সার্ভারে পাঠানো হয় না — ব্রাউজার পুরো পাতা এনে নিজেই id="reviews" অংশে স্ক্রল করে। অংশ ৪ পুরোটাই এ নিয়ে।

ব্রাউজার URL-কে ঠিক এভাবেই টুকরো করে পড়ে। JavaScript-এর URL নামের একটি built-in টুল দিয়ে সেটি নিজের চোখে দেখা যায় — JavaScript না জানলেও চলবে, শুধু “চালিয়ে দেখুন” চাপুন আর ফলটি পড়ুন:

// ব্রাউজার একটি URL-কে যেভাবে ভাগ করে পড়ে
const u = new URL('https://shop.amardokan.example:443/products/rice.html?size=5kg&brand=chinigura#reviews');
console.log('protocol :', u.protocol);
console.log('hostname :', u.hostname);
console.log('port     :', JSON.stringify(u.port));
console.log('pathname :', u.pathname);
console.log('search   :', u.search);
console.log('hash     :', u.hash);
console.log('size =', u.searchParams.get('size'));
console.log('href     :', u.href);
// বাংলা বা ফাঁকা জায়গা থাকা ফাইলের নাম ঠিকানায় কেমন হয়?
console.log(new URL('ঈদ অফার.html', u).pathname);

প্রথম ছয় লাইনে URL-এর ছয়টি অংশ আলাদা হয়ে আসে। খেয়াল করুন port : "" — 443 যেহেতু https-এর ডিফল্ট, ব্রাউজার সেটি বাদ দিয়ে দিয়েছে; শেষের href-এও :443 নেই। size = 5kg দেখায়, query থেকে একটি মান আলাদা করে পড়া যায়। শেষ লাইনে /products/%E0%A6%88…%20… — বাংলা অক্ষর আর ফাঁকা জায়গা percent-encoding হয়ে লম্বা কোডে বদলে গেছে, আর ফাইলটি খোঁজা হচ্ছে /products/ ফোল্ডারে, কারণ u-কে ভিত্তি ধরা হয়েছে। 443-এর জায়গায় 8080 লিখে আবার চালান — এবার port লুকাবে না।

ফাইলের নামে ফাঁকা জায়গা, বাংলা অক্ষর বা বড় হাতের অক্ষর ব্রাউজার সামলাতে পারে, কিন্তু ঝামেলা বাড়ায় — লিংক কপি করলে %20-ভরা লম্বা ঠিকানা আসে, আর বানানে ছোট ভুল হলেই লিংক ভাঙে। পেশাদার নিয়ম: ফাইল ও ফোল্ডারের নাম ছোট হাতের ইংরেজি অক্ষরে, শব্দের মাঝে হাইফেন — eid-offer.html, price-list.pdf. এই সাইটের প্রতিটি পর্বের নামও এই নিয়মে।

৩ · Absolute, relative আর root-relative path

নিজের সাইটের এক পাতা থেকে আরেক পাতায় লিংক দিতে প্রতিবার পুরো ঠিকানা লেখার দরকার নেই। ঠিকানা লেখার তিনটি উপায় আছে, আর পার্থক্যটা হলো “কোথা থেকে হিসাব শুরু”।

🌐 Absolute URL

পুরো ঠিকানা — scheme আর host-সহ। যেকোনো জায়গা থেকে একই জায়গায় নিয়ে যায়। অন্য সাইটে লিংক দিতে এটিই লাগে।

https://amardokan.example/about.html

📂 Relative path

এই পাতাটি যে ফোল্ডারে আছে, সেখান থেকে হিসাব। ../ মানে এক ফোল্ডার উপরে, ./ মানে এই ফোল্ডারেই।

../about.html

🏠 Root-relative path

শুরুতে / — এই সাইটের গোড়া (root) থেকে হিসাব। পাতা যে ফোল্ডারেই থাকুক, ফল একই।

/images/logo.png

সবচেয়ে বেশি ভুল হয় relative path-এ, তাই একটি ফোল্ডার-গাছ ধরে ধাপে ধাপে দেখি। ধরুন আপনি আছেন blog/posts/eid-recipe.html পাতায়, আর সেখান থেকে নানা ফাইলে লিংক দিচ্ছেন। প্রতি ধাপে বাঁ দিকে উজ্জ্বল লাইনটি হলো যে ফাইলে গিয়ে পৌঁছাল:

1amardokan/          ← সাইটের root ( / )2├── index.html3├── about.html4├── css/5│   └── style.css6├── images/7│   └── logo.png8└── blog/9    ├── index.html10    └── posts/11        ├── eid-recipe.html  ← আপনি12        └── photo.jpg
ব্রাউজারের হিসাব
href
শুরু
ফল
  1. আপনি কোথায় আছেন? সব relative হিসাবের শুরু এই প্রশ্ন দিয়ে। পাতাটি /blog/posts/ ফোল্ডারে, তাই এই ফোল্ডারটিই “এখানে”। ঠিক যেন মলের ম্যাপে লাল বিন্দু — “আপনি এখানে আছেন”।
  2. photo.jpg — একই ফোল্ডারে। কোনো / বা ../ নেই মানে “এই ফোল্ডারেই খোঁজো”। ./photo.jpg লিখলেও একই ফল — ./ মানে “এই ফোল্ডার”, শুধু স্পষ্ট করে বলা।
  3. ../index.html — এক ধাপ উপরে। .. মানে মা-ফোল্ডার। posts/ থেকে উঠে এলাম blog/-এ, সেখানকার index.html. খেয়াল করুন, এটি সাইটের মূল index.html নয়!
  4. ../../about.html — দুই ধাপ উপরে। প্রতিটি ../ একটি করে সিঁড়ি। posts/ → blog/ → root. সেখানে about.html.
  5. ../../css/style.css — উঠে, তারপর নামা। দুই ধাপ উঠে root-এ, তারপর css/ ফোল্ডারে ঢুকে style.css. উপরে ওঠা আর নিচে নামা একসাথে — বেশিরভাগ path এমনই।
  6. /images/logo.png — root থেকে। শুরুতে / থাকলে বর্তমান ফোল্ডার ভুলে যান; সোজা সাইটের গোড়া থেকে হিসাব। এই লিংক সাইটের যেকোনো পাতায় বসালেও একই লোগোতে যাবে — তাই menu, লোগো, CSS-এর জন্য এটি জনপ্রিয়।
  7. ../../../index.html — বেশি উঠলে কী হয়? তিন ধাপ উঠতে চাইলেন, কিন্তু দুই ধাপেই root-এ পৌঁছে গেছেন। Root-এর ওপরে আর কিছু নেই, তাই ব্রাউজার root-এই থেমে যায় — ফল /index.html. এজন্য বাড়তি ../ ভুলটা সাথে সাথে চোখে পড়ে না।
  8. Absolute — কোনো হিসাবই লাগে না। পুরো ঠিকানা দিলে আপনি কোথায় আছেন তাতে কিছু যায় আসে না। একই লোগোতে যাওয়ার এটি তৃতীয় উপায়। তবে নিজের সাইটের ভেতরে এভাবে লিখলে ডোমেইন বদলালে সব লিংক বদলাতে হবে।

এবার একই হিসাব ব্রাউজারকে দিয়ে করিয়ে নিই। নিচের কোড প্রতিটি href-কে eid-recipe.html পাতার সাপেক্ষে পুরো ঠিকানায় বদলে দেখায় — শেষ দুটি লাইনে দুটি চমক আছে:

// আপনি আছেন এই পাতায় — প্রতিটি href এর সাপেক্ষে মেলানো হবে
const page = 'https://amardokan.example/blog/posts/eid-recipe.html';
const hrefs = ['photo.jpg', './photo.jpg', '../index.html', '../../about.html',
  '/images/logo.png', '../../../../index.html', '#ingredients', '?lang=en',
  '//cdn.example/app.js', 'blog/posts/photo.jpg', 'C:\\site\\logo.png'];
for (const h of hrefs) {
  console.log(h.padEnd(22), '→', new URL(h, page).href);
}

প্রথম ছয়টি লাইন স্টেপারের সাথে মিলিয়ে নিন। #ingredients আর ?lang=en শুধু পাতার শেষ অংশ বদলায় — একই পাতা, অন্য জায়গা বা অন্য প্রশ্ন। //cdn.example/app.js হলো “protocol-relative” — scheme এই পাতা থেকে ধার করে। এবার চমক: blog/posts/photo.jpg গিয়ে দাঁড়াল /blog/posts/blog/posts/photo.jpg-এ! শুরুতে / না দিলে ব্রাউজার এটিকে “এই ফোল্ডারের ভেতরের blog ফোল্ডার” ধরে — নতুনদের সবচেয়ে প্রচলিত ভুল। আর Windows-এর C:\site\logo.png ঠিকানাটি Chrome বা Edge-এ হয়ে যায় file:///C:/site/logo.png — অর্থাৎ আপনার নিজের কম্পিউটারের একটি ফাইল, যা দর্শকের কম্পিউটারে নেই (অন্য ব্রাউজারে ফল আরও অদ্ভুত হতে পারে)। ওয়েবে এটি কোনো কাজের নয়। তালিকায় '/blog/posts/photo.jpg' যোগ করে আবার চালিয়ে দেখুন।

যে তিনটি ফাঁদে সবাই একবার পড়ে

ফাঁদকী ঘটেসমাধান
বড়-ছোট হাতের অক্ষর: Logo.PNG বনাম logo.pngনিজের Windows কম্পিউটারে সব ঠিক চলে, কিন্তু cPanel-এর Linux সার্ভারে আপলোড করতেই ছবি ভাঙে — Linux অক্ষরের বড়-ছোট আলাদা ধরেসব নাম ছোট হাতের অক্ষরে; লিংকে হুবহু একই বানান
উল্টো স্ল্যাশ \ বা C:\… ঠিকানাশুধু আপনার কম্পিউটারে, তাও কখনো কখনো, কাজ করেURL-এ সবসময় সামনের স্ল্যাশ /
ফাইল ডাবল-ক্লিক করে খোলা পাতায় /css/style.cssfile:// দিয়ে খোলা পাতায় “root” মানে পুরো ড্রাইভের গোড়া (C:/), তাই CSS পাওয়া যায় নাVS Code-এর Live Server-এর মতো ছোট সার্ভার দিয়ে খুলুন (পর্ব ০২), অথবা relative path ব্যবহার করুন
কোনটি কখন

অন্য সাইটে: সবসময় absolute URL. নিজের সাইটের ভেতরে: relative বা root-relative — তাহলে ডোমেইন বদলালেও বা অন্য সার্ভারে সরালেও লিংক ভাঙে না। ছোট সাইট, যেটি কখনো ডাবল-ক্লিক করেও খোলা হতে পারে, সেখানে relative নিরাপদ। যে ঠিকানা পাতার বাইরে যায় — canonical লিংক, সোশ্যাল শেয়ারের ছবি (পর্ব ১৩), ইমেইলের ভেতরের লিংক — সেখানে অবশ্যই absolute.

৪ · পাতার ভেতরে লাফ — fragment, id আর :target

লম্বা একটি পাতা — রেসিপি, নিয়মকানুন, প্রশ্নোত্তর। ওপরে একটি সূচিপত্র থাকলে পাঠক এক ক্লিকে নিজের দরকারি অংশে চলে যেতে পারেন। এর জন্য দুটি জিনিস লাগে: যেখানে পৌঁছাতে চান সেই element-এ একটি id, আর লিংকের href-এ # আর সেই id.

<a href="#steps">রান্নার ধাপে যান</a>
…
<section id="steps"> … </section>

ক্লিক করলে ভেতরে ঠিক কী ঘটে, ধাপে ধাপে দেখুন:

  1. ক্লিকhref="#steps"পূর্ণ ঠিকানা বানানো
  2. মেলানোএকই পাতা?সার্ভারে যাবে না
  3. খোঁজাid="steps"লক্ষ্য element
  4. স্ক্রল…/recipe.html#stepsঠিকানা ও history
  5. :target:target { … }CSS জেগে ওঠে
  1. ক্লিক — আগে পূর্ণ ঠিকানা। #steps একটি relative URL. ব্রাউজার এটিকে বর্তমান পাতার ঠিকানার সাথে জুড়ে পূর্ণ URL বানায় — …/recipe.html#steps.
  2. একই পাতা কি না মেলানো। নতুন ঠিকানা আর এখনকার ঠিকানা যদি শুধু #-এর পরের অংশে আলাদা হয়, ব্রাউজার বোঝে: এটি একই পাতা। তাই সার্ভারে কোনো অনুরোধ যায় না, পাতা নতুন করে লোডও হয় না — চোখের পলকে কাজ শেষ।
  3. লক্ষ্য খোঁজা। পাতায় id="steps" আছে এমন element খোঁজে (না পেলে পুরোনো নিয়মে <a name="steps">). id-র বানান হুবহু মিলতে হবে — #Steps আর steps আলাদা। কিছুই না পেলে নীরবে কিছুই হয় না। ব্যতিক্রম: #top বা শুধু # পাতার একদম ওপরে নিয়ে যায়।
  4. স্ক্রল, ঠিকানা বদল আর history. লক্ষ্য element স্ক্রল হয়ে ওপরে আসে, ঠিকানার ঘরে #steps যোগ হয়, আর history-তে একটি নতুন ধাপ জমা হয় — তাই ব্রাউজারের Back বাটন চাপলে আগের জায়গায় ফিরে যান। ঠিকানাটি কপি করে কাউকে পাঠালে তিনিও সোজা ওই অংশে পৌঁছাবেন।
  5. :target জেগে ওঠে। যে element-এর id এখন ঠিকানার fragment-এর সাথে মেলে, CSS-এর :target নিয়ম তার ওপর খাটে। এভাবে লাফ দেওয়া অংশটিকে হালকা রঙে উজ্জ্বল করা যায়, যাতে পাঠক বোঝেন কোথায় এসে পড়লেন। কিবোর্ডে পরের Tab-ও এখান থেকেই শুরু হয়।

এবার নিজে চালিয়ে দেখুন। নিচের প্রিভিউতে সূচিপত্রের লিংকগুলোতে ক্লিক করুন — প্রিভিউর ভেতরে পাতাটি স্ক্রল হবে, আর পৌঁছানো অংশটি হলুদ হবে:

<!doctype html>
<html lang="bn">
<head>
  <meta charset="utf-8">
  <title>ঈদের সেমাই</title>
  <style>
    section { min-height: 240px; border-top: 1px solid #ccc; }
    :target { background: #fff3b0; }
  </style>
</head>
<body>
  <h1 id="top">ঈদের সেমাই রেসিপি</h1>
  <nav>
    <a href="#ingredients">উপকরণ</a> |
    <a href="#steps">রান্নার ধাপ</a> |
    <a href="#tips">টিপস</a>
  </nav>
  <section id="ingredients"><h2>উপকরণ</h2>
    <p>সেমাই ২০০ গ্রাম, দুধ ১ লিটার, চিনি আর এলাচ</p></section>
  <section id="steps"><h2>রান্নার ধাপ</h2>
    <p>ঘিয়ে সেমাই হালকা ভেজে ফুটন্ত দুধে দিন</p>
    <a href="#top">↑ উপরে ফিরুন</a></section>
  <section id="tips"><h2>টিপস</h2>
    <p>দুধ ঘন হলে নামিয়ে বাদাম ছড়িয়ে দিন</p>
    <a href="#">↑ একদম শুরুতে</a></section>
</body>
</html>

প্রিভিউতে ওপরে শিরোনাম আর তিনটি লিংক, নিচে দাগ দিয়ে ভাগ করা তিনটি অংশ। “টিপস”-এ ক্লিক করলে প্রিভিউর ভেতরে পাতা নেমে যায় আর টিপস অংশ হলুদ হয় — এটাই :target. “উপরে ফিরুন” আছে #top-এ, যা এখানে h1-এর id; “একদম শুরুতে” শুধু #, তবু ওপরে নিয়ে যায়। এবার চেষ্টা করুন: (১) id="tips"-কে id="Tips" করুন, তারপর “টিপস”-এ ক্লিক করুন — কিছুই হবে না, কারণ id-র বড়-ছোট অক্ষর মেলেনি। (২) #fff3b0-এর জায়গায় lightgreen লিখুন।

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

অন্য পাতার নির্দিষ্ট জায়গায়, আর আরও কিছু কৌশল

  • অন্য পাতার ভেতরের অংশ: href="faq.html#delivery" — আগে faq.html লোড হবে, তারপর id="delivery"-তে স্ক্রল। এই সাইটের প্রতিটি পর্বের অংশেও এমন লিংক দেওয়া যায় — যেমন links-paths.html#s4.
  • ওপরে sticky header থাকলে লাফ দেওয়া heading-টি header-এর নিচে ঢাকা পড়ে। সমাধান CSS-এ: scroll-margin-top: 4rem; — Baseline Widely available, অর্থাৎ সব আধুনিক ব্রাউজারে বহুদিন ধরে চলে। আর মসৃণ স্ক্রলের scroll-behavior: smooth আসবে পর্ব ৪২-এ।
  • id-র নিয়ম: পুরো পাতায় একটি id একবারই থাকবে; ভেতরে ফাঁকা জায়গা চলবে না; অর্থবহ, ছোট নাম দিন — delivery-charge, s4.
  • লেখার টুকরোয় লাফ (text fragment): #:~:text=ডেলিভারি দিলে ব্রাউজার পাতার ওই শব্দটি খুঁজে হাইলাইট করে, id ছাড়াই। Chrome-এ কোনো লেখা সিলেক্ট করে “Copy link to highlight” চাপলে এমন লিংক তৈরি হয়। এটি তুলনামূলক নতুন ফিচার, প্রধান ব্রাউজারগুলোতে ধাপে ধাপে এসেছে — না চললে সাধারণ লিংকের মতো শুধু পাতাটি খোলে, তাই ক্ষতি নেই।

৫ · বিশেষ লিংক — ইমেইল, ফোন, WhatsApp আর ডাউনলোড

লিংক শুধু পাতায় যায় না। scheme বদলালে লিংক অন্য অ্যাপকেও ডাকতে পারে — ছোট ব্যবসার সাইটে এগুলোই সবচেয়ে বেশি কাজে লাগে।

লিংকযা ঘটেখেয়াল রাখুন
mailto:ইমেইল অ্যাপ খুলে প্রাপকের ঠিকানা বসিয়ে দেয়?subject=…&body=… দিয়ে বিষয় আর লেখাও আগে থেকে বসানো যায়; ফাঁকা জায়গা %20. ঠিকানাটি লেখাতেও দেখান — অনেকের কম্পিউটারে ইমেইল অ্যাপ সেট করা থাকে না।
tel:মোবাইলে ডায়াল-প্যাডে নম্বর বসায়আন্তর্জাতিক রূপে লিখুন: বাংলাদেশের কোড +880, তারপর শুরুর ০ বাদ — 01712345678 হয় +8801712345678. তাহলে বিদেশ থেকেও কাজ করে।
https://wa.me/…WhatsApp-এ সেই নম্বরের চ্যাট খোলেএটি আসলে সাধারণ https লিংক; নম্বর লিখতে হয় +, ফাঁকা আর হাইফেন ছাড়া — wa.me/8801712345678.
download attributeফাইলটি খোলার বদলে ডাউনলোড করতে বলেdownload="নতুন-নাম.pdf" দিলে সেই নামে সেভ হয়। শুধু নিজের সাইটের ফাইলে কাজ করে — অন্য সাইটের ফাইলে ব্রাউজার এটি উপেক্ষা করে।

নিচের প্রিভিউতে একটি দোকানের যোগাযোগ-অংশ। ছোট একটি CSS কৌশল (attr(href)) প্রতিটি লিংকের পাশে তার আসল href-টি ধূসর রঙে দেখিয়ে দিচ্ছে — যাতে লেখা আর ঠিকানা পাশাপাশি দেখা যায়। এখানে ক্লিক নয়, গঠন দেখাই উদ্দেশ্য:

<style>
  a::after { content: "  ⟶ " attr(href); color: #666; font-size: .8em; }
  a[target="_blank"]::after { content: "  ⟶ " attr(href) " (নতুন ট্যাবে)"; }
  a[href^="tel:"]::before { content: "📞 "; }
  li { margin: 6px 0; }
</style>
<h3>রহিম স্টোর — যোগাযোগ</h3>
<ul>
  <li><a href="mailto:info@rahimstore.example?subject=Order%20query">info@rahimstore.example-এ ইমেইল করুন</a></li>
  <li><a href="tel:+8801712345678">ফোন: ০১৭১২-৩৪৫৬৭৮</a></li>
  <li><a href="https://wa.me/8801712345678">WhatsApp-এ মেসেজ দিন</a></li>
  <li><a href="price-list.pdf" download="rahim-store-prices.pdf">দামের তালিকা (PDF, ১২০ KB)</a></li>
  <li><a href="https://www.openstreetmap.org/" target="_blank" rel="noopener noreferrer">ম্যাপে দোকান খুঁজুন</a></li>
</ul>

প্রিভিউতে পাঁচটি নীল লিংক, প্রতিটির পাশে ধূসর লেখায় তার href; ফোনের লিংকের আগে 📞 এসেছে a[href^="tel:"] নিয়ম থেকে — “যে লিংকের href tel: দিয়ে শুরু” (attribute selector, পর্ব ১৭)। শেষ লিংকের পাশে “(নতুন ট্যাবে)” এসেছে target="_blank" দেখে। খেয়াল করুন, ডাউনলোডের লিংকে ফাইলের ধরন আর আকার লেখাতেই বলে দেওয়া হয়েছে — মোবাইল ডেটায় থাকা পাঠকের জন্য এটি জরুরি তথ্য। প্রিভিউতে কোনো লিংকে ক্লিক করলে ইমেইল অ্যাপ, ডায়াল-প্যাড বা ডাউনলোড খুলবে না — নিচে শুধু লেখা আসবে, যেমন লিংকে ক্লিক → tel:+8801712345678, আর ম্যাপের লিংকে বাড়তি “(নতুন ট্যাবে)”; আসল পাতায় এগুলো ঠিকই কাজ করবে। চেষ্টা করুন: ফোন নম্বরটি নিজের দোকানের ধরে বদলান, আর ?subject=-এর পরে &body=Assalamu%20alaikum যোগ করুন — পাশের ধূসর লেখায় তা দেখা যাবে।

৬ · নতুন ট্যাবে খোলা আর rel — নিরাপত্তা আর SEO

target="_blank" দিলে লিংক নতুন ট্যাবে খোলে। শুনতে নিরীহ, কিন্তু অনেক বছর ধরে এর ভেতরে একটি নিরাপত্তা-ফাঁক লুকিয়ে ছিল, যার নাম tabnabbing. ধাপে ধাপে দেখুন:

  1. ট্যাব ১: আপনার সাইটtarget="_blank"rel নেই
  2. ট্যাব ২: অন্য সাইটwindow.openerট্যাব ১-এর হাতল
  3. ট্যাব ১ বদলে গেলনকল লগইন পাতাপাঠক টেরই পান না
  4. rel="noopener"opener = nullহাতল কাটা
  1. একটি সাধারণ লিংক। আপনার সাইটের একটি পাতায় অন্য কারও সাইটের লিংক, target="_blank" দেওয়া, কিন্তু কোনো rel নেই। পাঠক ক্লিক করলেন।
  2. নতুন ট্যাবের হাতে একটি হাতল। পুরোনো নিয়মে নতুন ট্যাবের পাতা JavaScript-এ window.opener পেত — যে ট্যাব তাকে খুলেছে, তার দিকে একটি হাতল। এই হাতল দিয়ে সে পুরোনো ট্যাবের ঠিকানা বদলে দিতে পারত।
  3. চুপিচুপি বদল। অসৎ সাইটটি পেছনের ট্যাব ১-কে একটি নকল লগইন পাতায় পাঠিয়ে দিল — দেখতে হুবহু আপনার সাইট, বা কোনো ব্যাংক বা মোবাইল-ওয়ালেটের মতো। পাঠক পুরোনো ট্যাবে ফিরে ভাবলেন “লগআউট হয়ে গেছি”, আর পাসওয়ার্ড দিয়ে বসলেন। এটি phishing-এর একটি ধূর্ত রূপ।
  4. হাতল কেটে দেওয়া। rel="noopener" দিলে নতুন ট্যাব window.opener পায় না (null). এখন HTML-এর নিয়মই বদলে গেছে: আধুনিক সব প্রধান ব্রাউজারে target="_blank" নিজে থেকেই noopener-এর মতো আচরণ করে। তবু পুরোনো ব্রাউজারের জন্য আর স্পষ্টতার জন্য অনেকে এখনো লিখে দেন — ক্ষতি নেই।

তাহলে noreferrer কেন? ব্রাউজার সাধারণত নতুন সাইটকে জানায় পাঠক কোন পাতা থেকে এসেছেন — একটি Referer header-এ। noreferrer এই তথ্যটি পাঠাতে দেয় না (আর সাথে noopener-এর কাজও করে)। আধুনিক ব্রাউজারের ডিফল্ট নীতিতে অন্য সাইটে এমনিতেই শুধু ডোমেইনটুকু যায়, পুরো ঠিকানা নয়। তাই noreferrer তখনই দিন, যখন সত্যিই চান না অন্য সাইট জানুক আপনি পাঠিয়েছেন — মনে রাখবেন, এতে তাদের পরিসংখ্যানে আপনার সাইট আর দেখা যাবে না।

নতুন ট্যাবে খোলা কি আদৌ উচিত? বেশিরভাগ ক্ষেত্রে না। পাঠক চাইলে নিজেই Ctrl+ক্লিক বা লম্বা-চাপে নতুন ট্যাবে খুলতে পারেন; জোর করে খোলালে Back বাটন কাজ করে না, আর screen reader ব্যবহারকারী বুঝতেই পারেন না কেন “পেছনে যাওয়া” যাচ্ছে না। ব্যতিক্রম: ফর্ম পূরণের মাঝখানে সাহায্যের লিংক, যাতে লেখা হারিয়ে না যায়। তখন লেখাতেই জানিয়ে দিন — “(নতুন ট্যাবে খুলবে)”।

rel দিয়ে সার্চ ইঞ্জিনকে লিংকের পরিচয় জানানো

Google-এর মতো সার্চ ইঞ্জিন লিংককে একরকম “ভোট” হিসেবে দেখে — অনেক ভালো সাইট যে পাতায় লিংক দেয়, সেটিকে গুরুত্বপূর্ণ ধরে। SEO-র এই জগতে সৎ থাকতে rel attribute দিয়ে লিংকের ধরন জানানো হয়:

মানঅর্থউদাহরণ
rel="sponsored"টাকা, পণ্য বা কোনো সুবিধার বিনিময়ে দেওয়া লিংকস্পনসর করা রিভিউ, affiliate লিংক
rel="ugc"ব্যবহারকারীর লেখা (user-generated content)মন্তব্য, ফোরামের পোস্ট
rel="nofollow"“এই লিংকের পক্ষে আমি সুপারিশ করছি না”যাচাই করতে পারেননি এমন সাইট; উপরের দুটি না খাটলে

একাধিক মান ফাঁকা দিয়ে একসাথে দেওয়া যায়: rel="ugc nofollow". এগুলো ব্রাউজারের আচরণ বদলায় না — ক্লিক করলে লিংক আগের মতোই খোলে; শুধু সার্চ ইঞ্জিনের কাছে একটি ইঙ্গিত। টাকা নিয়ে দেওয়া লিংক না জানালে Google-এর নিয়ম ভাঙে, আর সাইটের র‍্যাংকিং ক্ষতিগ্রস্ত হতে পারে — freelancing-এ “guest post বিক্রি”-র কাজ নেওয়ার আগে এটি জেনে রাখুন। head-এর SEO বিষয়গুলো বিস্তারিত আসছে পর্ব ১৩-এ।

৭ · সবার জন্য লিংক — ভালো লিংক টেক্সট, আর লিংক বনাম বাটন

যাঁরা চোখে দেখেন না, তাঁরা screen reader দিয়ে ওয়েব ব্যবহার করেন — একটি সফটওয়্যার, যা পাতার লেখা জোরে পড়ে শোনায় (Windows-এ ফ্রি NVDA, ফোনে TalkBack বা VoiceOver). পাতা দ্রুত বুঝতে তাঁরা প্রায়ই শুধু লিংকগুলোর একটি তালিকা খোলেন (NVDA-তে Insert+F7). তখন আশপাশের বাক্য থাকে না — থাকে শুধু লিংকের লেখা, অর্থাৎ লিংকের accessible name.

নিচের প্রিভিউতে একই চারটি লিংক দুইভাবে লেখা। ছোট একটি স্ক্রিপ্ট screen reader-এর মতো করে সব লিংকের নাম একটি তালিকায় দেখাবে (প্রিভিউর নিচে):

<p>ঈদ অফার চলছে! <a href="offer.html">এখানে ক্লিক করুন</a></p>
<p>ডেলিভারির নিয়ম জানতে <a href="delivery.html">এখানে ক্লিক করুন</a></p>
<p>ফেরত দেওয়ার নিয়ম — <a href="return.html">আরও পড়ুন</a></p>
<p><a href="cart.html"><svg width="22" height="22"><circle cx="11" cy="11" r="9" fill="teal"/></svg></a></p>
<hr>
<p><a href="offer.html">ঈদ অফারের সব পণ্য দেখুন</a></p>
<p><a href="delivery.html">ঢাকার বাইরে ডেলিভারির খরচ ও সময়</a></p>
<p><a href="return.html">পণ্য ফেরত দেওয়ার নিয়ম</a></p>
<p><a href="cart.html" aria-label="কার্ট দেখুন"><svg width="22" height="22" aria-hidden="true"><circle cx="11" cy="11" r="9" fill="teal"/></svg></a></p>
<script>
  // screen reader-এর "লিংকের তালিকা" যেমন শোনায়
  let k = 1;
  for (const a of document.querySelectorAll('a')) {
    const label = a.getAttribute('aria-label') || a.textContent.trim() || '(নাম নেই!)';
    console.log(k++ + '. ' + label);
  }
</script>

প্রিভিউর নিচে আটটি লাইন আসে। প্রথম চারটি: 1. এখানে ক্লিক করুন, 2. এখানে ক্লিক করুন, 3. আরও পড়ুন, 4. (নাম নেই!) — তালিকায় দুটি হুবহু একই নাম, একটির কোনো মানে নেই, আর ছবির লিংকটির নামই নেই; screen reader সেখানে হয়তো শুধু “link” বা ফাইলের নাম পড়বে। পরের চারটি (5. ঈদ অফারের সব পণ্য দেখুন … 8. কার্ট দেখুন) প্রসঙ্গ ছাড়াও পরিষ্কার। চেষ্টা করুন: ৪ নম্বর লিংকের ভেতরে <svg>-এর পরে কার্ট শব্দটি লিখুন — তালিকায় নামটি চলে আসবে।

ভালো লিংক টেক্সটের নিয়ম

লেখাটি একাই বলবে লিংক কোথায় নেবে। WCAG 2.2-এর ন্যূনতম শর্ত 2.4.4 (Link Purpose — In Context, Level A) অন্তত আশপাশের বাক্যসহ উদ্দেশ্য বোঝা যেতে বলে; আর 2.4.9 (Link Only, Level AAA) চায় শুধু লিংকের লেখা থেকেই বোঝা যাক — লক্ষ্য রাখুন এটিই। “এখানে ক্লিক করুন”, “আরও পড়ুন”, “লিংক” — এগুলো এড়ান; মোবাইলে তো কেউ “ক্লিক”-ও করেন না! একই লেখার দুটি লিংক যেন একই জায়গায় যায়। শুধু আইকনের লিংকে aria-label বা চোখে-না-দেখা লেখা দিন। আর ছবি দিয়ে লিংক বানালে ছবির alt-ই হয় লিংকের নাম (পর্ব ০৬)। লম্বা ঠিকানা (https://…) লিংকের লেখা হিসেবে দেবেন না — screen reader অক্ষর ধরে পড়বে।

লিংক নাকি বাটন — কাজ দেখে ঠিক করুন

দেখতে একটি নীল লেখা আর একটি ধূসর বাক্স — কিন্তু আসল পার্থক্য চেহারায় নয়, কাজে। লিংক (<a href>) মানে কোথাও যাওয়া — অন্য পাতা, অন্য অংশ, একটি ফাইল। বাটন (<button>) মানে এখানেই কিছু করা — কার্টে যোগ, মেনু খোলা, ফর্ম জমা। ব্রাউজার দুটিকে আলাদা সুবিধা দেয়:

বৈশিষ্ট্য<a href><button>
কিবোর্ডে চালু করাEnterEnter আর Space
নতুন ট্যাবে খোলা, লিংক কপি, বুকমার্কহ্যাঁনা
screen reader যা বলে“link”“button”
Back বাটনে ফেরাহ্যাঁ, আগের পাতায়প্রযোজ্য নয়
<style>
  .fake { display: inline-block; padding: 2px 8px; background: #ddd; cursor: pointer; }
</style>
<h3>চিনিগুঁড়া চাল — ৫ কেজি, ৳৭৫০</h3>
<p><button type="button" id="add">কার্টে যোগ করুন</button> ← এখানেই একটি কাজ</p>
<p><span class="fake" id="fake">কার্টে যোগ করুন</span> ← নকল বাটন (span)</p>
<p><a href="cart.html">কার্ট পাতায় যান</a> ← অন্য পাতায় যাওয়া</p>
<script>
  let count = 0;
  document.getElementById('add').addEventListener('click', () => {
    count++;
    console.log('আসল বাটন: কার্টে এখন ' + count + 'টি');
  });
  document.getElementById('fake').addEventListener('click', () => {
    console.log('নকল বাটন: মাউসে চলে, কিন্তু কিবোর্ডে পৌঁছানো যায় না');
  });
</script>

প্রিভিউতে একটি আসল বাটন, তার নিচে দেখতে প্রায় একই রকম একটি ধূসর বাক্স, আর একটি লিংক। শুরুতে নিচে কিছুই আসে না — আসবে ক্লিক করলে। দুটি “কার্টে যোগ করুন”-এই মাউসে ক্লিক করুন: দুটিই কাজ করে। এবার প্রিভিউর ভেতরে একবার ক্লিক করে কিবোর্ডের Tab চাপতে থাকুন — ফোকাস আসল বাটন থেকে সোজা লিংকে লাফ দেয়, নকল বাটনকে এড়িয়ে যায়; আর আসল বাটনে ফোকাস রেখে Space চাপলেও গণনা বাড়ে। কিবোর্ড বা screen reader ব্যবহারকারীর কাছে নকল বাটনটির অস্তিত্বই নেই। শেষে “কার্ট পাতায় যান”-এ ক্লিক করুন — নিচে আসবে লিংকে ক্লিক → cart.html: আসল সাইটে এখানে পুরো পাতাটাই বদলে যেত, কার্টের গণনা নয়। এটাই navigation আর action-এর পার্থক্য।

দুটি পুরোনো অভ্যাস ছাড়ুন: (১) <a href="#" onclick="…"> বা href="javascript:void(0)" দিয়ে “বাটন” বানানো — কাজ না হলে পাতা ওপরে লাফ দেয়, নতুন ট্যাবে খুললে ফাঁকা পাতা আসে, screen reader ভুল করে “link” বলে। কাজ হলে <button type="button"> দিন। (২) <div> বা <span>-এ ক্লিক বসিয়ে বাটন বানানো। “ARIA-র প্রথম নিয়ম” বলে: যে কাজের জন্য HTML-এ নিজস্ব element আছে, সেটিই ব্যবহার করুন — role="button" জুড়ে নকল জিনিস বানাবেন না। বিস্তারিত পর্ব ১২-এ।

৮ · <base>-এর ফাঁদ, ভাঙা লিংক আর লিংক যাচাই

<base> — সাবধানে ধরতে হয় এমন একটি ট্যাগ

<base> ট্যাগটি <head>-এ বসে আর পুরো পাতার জন্য বলে দেয়: “সব relative ঠিকানা এই ঠিকানার সাপেক্ষে হিসাব করো।” শুনতে সুবিধাজনক, কিন্তু এর প্রভাব ঠিক “সব”-এর ওপর:

<head>
  <base href="https://amardokan.example/shop/">
</head>
<body>
  <a href="rice.html">চাল</a>      <!-- → /shop/rice.html (ঠিক যেমন চেয়েছিলেন) -->
  <img src="logo.png" alt="লোগো">  <!-- → /shop/logo.png (হয়তো চাননি!) -->
  <a href="#reviews">রিভিউ</a>   <!-- → /shop/#reviews — অন্য পাতা! -->
</body>

শেষ লাইনটিই সবচেয়ে বড় ফাঁদ: <base> থাকলে পাতার ভেতরের # লিংকও base-এর সাপেক্ষে হিসাব হয়। এই পাতার ঠিকানা যদি /shop/rice.html হয়, #reviews আর একই পাতায় লাফ দেবে না, বরং /shop/ পাতাটি লোড করবে। অংশ ৩-এর JavaScript কোডে দেখেছেন, #ingredients আসলে “ভিত্তি-ঠিকানা + #ingredients”; <base> সেই ভিত্তিটাই বদলে দেয়। আরও তিনটি নিয়ম: পাতায় একটিই <base> থাকবে; সেটি থাকবে URL ব্যবহার করা অন্য সব ট্যাগের আগে; আর <base target="_blank"> দিলে পাতার সব লিংক নতুন ট্যাবে খুলবে। তাই সাধারণ পরামর্শ: খুব নির্দিষ্ট কারণ ছাড়া <base> ব্যবহার করবেন না।

ভাঙা লিংক — কেন হয়, কীভাবে খুঁজবেন

ভাঙা লিংক মানে এমন লিংক, যার ঠিকানায় আর কিছু নেই — সার্ভার উত্তর দেয় 404 Not Found. কারণ প্রায় সবসময় এগুলোর একটি: ফাইলের নাম বা ফোল্ডার বদলানো, বানান বা বড়-ছোট অক্ষরের ভুল, ভুল ../, আর অন্য সাইট তাদের পাতা সরিয়ে বা মুছে ফেলেছে। ভাঙা লিংক পাঠককে বিরক্ত করে, আর সার্চ ইঞ্জিনের চোখে সাইটকে অযত্নের দেখায়।

DevTools (পর্ব ০২, ৪৭)

F12 চেপে Network ট্যাব খুলে পাতা আবার লোড করুন; লাল রঙে 404 স্ট্যাটাসের ফাইলগুলোই ভাঙা CSS, ছবি বা স্ক্রিপ্ট। Console-ও এগুলোর কথা জানায়।

নিজের পাতার ফাইলের জন্য

Link checker

W3C-র ফ্রি Link Checker (validator.w3.org/checklink) পাতার প্রতিটি লিংক একে একে খুলে দেখে কোনটি ভাঙা বা অন্যত্র সরানো। পুরো সাইটের জন্য crawler ধরনের টুল আছে।

পুরো পাতা বা সাইটের জন্য

Google Search Console

সাইট প্রকাশের পর Google নিজেই জানায় কোন পাতা “Not found (404)” পেয়েছে — অন্য সাইট থেকে আসা ভাঙা লিংকসহ।

প্রকাশিত সাইটের জন্য

সবচেয়ে ভালো সমাধান হলো লিংক ভাঙতেই না দেওয়া। কোনো পাতার নাম বদলাতে হলে পুরোনো ঠিকানা থেকে নতুন ঠিকানায় একটি স্থায়ী 301 redirect বসান — cPanel-এর সাইটে .htaccess ফাইলে এক লাইনেই হয় (পর্ব ৫৩)। এই কোর্সের পুরোনো পর্বগুলোর ঠিকানাও এভাবেই নতুন পর্বে পাঠানো হয়।

আরও গভীরে: ব্রাউজার URL পড়ে WHATWG-এর “URL Standard” নামের একটি বিস্তারিত নিয়ম মেনে — আগের RFC 3986-এর সাথে কিছু জায়গায় এর অমিল আছে, কারণ এটি লেখা হয়েছে ব্রাউজারগুলো বাস্তবে যা করে তা মিলিয়ে (যেমন \-কে / ধরে নেওয়া)। প্রতিটি পাতার একটি “document base URL” থাকে — সাধারণত পাতার নিজের ঠিকানা, <base> থাকলে সেটি, আর srcdoc দিয়ে বানানো iframe-এ বাইরের পাতার ঠিকানা; সব relative URL এর সাপেক্ষেই মেলে। Fragment-এ লাফ দিলে নতুন কোনো Document তৈরি হয় না, শুধু history-তে একটি entry যোগ হয় আর hashchange event ঘটে — একসময় single-page app-গুলো এই কৌশলেই পাতা না বদলে “পাতা বদলের” অনুভূতি দিত (#!/products).

পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে —
লিংক তৈরির ট্যাগ ও attribute? <a> (anchor) আর href (hypertext reference).
Absolute আর relative URL-এর পার্থক্য? Absolute-এ scheme ও host-সহ পুরো ঠিকানা; relative হিসাব হয় বর্তমান পাতার ঠিকানা থেকে।
পাতার ভেতরের একটি অংশে লিংক কীভাবে? লক্ষ্যে id="x", লিংকে href="#x".
target="_blank"-এর সাথে rel="noopener" কেন? নতুন পাতা যেন window.opener দিয়ে পুরোনো পাতা বদলাতে না পারে (tabnabbing); আধুনিক ব্রাউজারে এটি ডিফল্ট।
কখন লিংক, কখন বাটন? অন্য ঠিকানায় যাওয়া হলে <a href>; এই পাতায় কোনো কাজ হলে <button>.

৯ · AI-এর যুগে — লিংক লিখে দেয় AI, যাচাই করেন আপনি

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

AI-এর ভুলফলকীভাবে ধরবেন
নিজের ধরে নেওয়া ফোল্ডার-গঠনে path (assets/img/…)ছবি আর CSS ভাঙাDevTools-এর Network-এ 404
বানানো (hallucinated) ঠিকানা — “এই ডকুমেন্টেশন দেখুন” বলে না-থাকা লিংকপাঠক 404 পাতায়প্রতিটি বাইরের লিংক নিজে খুলে দেখুন
সব জায়গায় target="_blank", অথবা “Click here”খারাপ UX ও accessibilityলিংকের তালিকা পড়ে দেখুন (অংশ ৭)
<a href="#" onclick> বা <div onclick> দিয়ে বাটনকিবোর্ডে কাজ করে নাশুধু Tab আর Enter দিয়ে পাতা চালিয়ে দেখুন
অন্য সাইটের লিংকে http:// বা পুরোনো ঠিকানানিরাপত্তা-সতর্কতা বা ভাঙা লিংকW3C Link Checker

AI-কে আপনার আসল ফোল্ডার-গঠন জানিয়ে দিলে বেশিরভাগ ভুল শুরুতেই এড়ানো যায়। আর তাকে দিয়ে নিজের কাজ “অডিট” করানোর সময় নির্দিষ্ট মাপকাঠি দিন:

আমার সাইটের ফোল্ডার-গঠন এমন: mysite/index.html, mysite/about.html, mysite/css/style.css, mysite/images/logo.png, mysite/blog/eid-recipe.html blog/eid-recipe.html পাতার জন্য একটি navigation বানিয়ে দাও (Home, About, লোগো আর CSS-সহ)। ১. প্রতিটি path relative রাখো, আর পাশে মন্তব্যে লেখো কেন ../ লাগল বা লাগল না। ২. লিংকের লেখা যেন প্রসঙ্গ ছাড়াও বোঝা যায় — "এখানে ক্লিক করুন" দিও না। ৩. target="_blank" দিও না, আর কোনো কাজের জন্য a ট্যাগ না দিয়ে button দাও। ৪. কোনো বাইরের লিংক দিলে বলো সেটি তুমি নিশ্চিতভাবে জানো, নাকি অনুমান করছ।

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

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

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলো লিংককে শুধু একটি ট্যাগ নয়, একটি ব্যবস্থা হিসেবে দেখতে শেখাবে।

প্র ০১লিংক ভাঙে কেন, আর “Cool URIs don't change” কথাটির মানে কী?

লিংক আসলে একটি প্রতিশ্রুতি: “এই ঠিকানায় গেলে এই জিনিসটি পাবেন।” কিন্তু ঠিকানার মালিক আর লিংক-দাতা প্রায়ই আলাদা মানুষ। আপনি আজ কোনো সরকারি নোটিশ বা পত্রিকার খবরে লিংক দিলেন; কয়েক বছর পর সেই সাইট নতুন করে বানানো হলো, ফোল্ডারের নাম বদলাল, পুরোনো পাতা মুছে গেল — আপনার লিংক কিছু না জেনেই ভেঙে গেল। এই ধীরে ধীরে ভেঙে যাওয়াকে বলে link rot. গবেষণায় বারবার দেখা গেছে, এক দশক আগের ওয়েব-পাতার বড় একটা অংশ আর পাওয়া যায় না; আদালতের রায় আর গবেষণাপত্রের উদ্ধৃতিতেও এমন ভাঙা লিংক পাওয়া গেছে।

১৯৯৮ সালে Tim Berners-Lee একটি ছোট লেখা প্রকাশ করেন, যার শিরোনাম “Cool URIs don't change”. তাঁর যুক্তি: ঠিকানা বদলানোর প্রায় সব কারণই আসলে অজুহাত। ঠিকানায় যদি এমন জিনিস রাখেন যা বদলায় — প্রযুক্তির নাম (.php, .asp), বিভাগের নাম, কর্মীর নাম — তাহলে একদিন তা বদলাবেই। ঠিকানা হওয়া উচিত বিষয়ভিত্তিক আর স্থায়ী। এই সাইটের পর্বগুলোর নামও এজন্য বিষয় দিয়ে রাখা (links-paths.html), ক্রমিক নম্বর দিয়ে নয় — নতুন পর্ব মাঝখানে ঢুকলে নম্বর বদলায়, বিষয় বদলায় না।

বাস্তবে যা করা হয়: (১) নাম বদলাতেই হলে পুরোনো ঠিকানায় 301 redirect রাখা, যাতে পুরোনো লিংক নতুন জায়গায় পৌঁছায় আর সার্চ ইঞ্জিনও নতুন ঠিকানা শিখে নেয়; (২) মুছে ফেলা পাতার জন্য 410 Gone বা একটি কাজের 404 পাতা, যেখানে সার্চ বা মূল মেনু আছে; (৩) গুরুত্বপূর্ণ বাইরের উৎস Internet Archive-এর Wayback Machine-এ সংরক্ষিত কপির সাথে মিলিয়ে রাখা — Wikipedia নিজের ভাঙা উৎস-লিংক অনেক ক্ষেত্রে এভাবে আর্কাইভ কপিতে বদলে দেয়।

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

প্র ০২URL-এ // কেন, আর ঠিকানার নকশায় ছোট সিদ্ধান্ত কেন দশকের পর দশক টিকে থাকে?

https://-এর দুটি স্ল্যাশের আলাদা কোনো কাজ নেই — কোলনের পরেই host লিখলেও যন্ত্রের বোঝার অসুবিধা হতো না। ওয়েবের শুরুর দিনে Berners-Lee ঠিকানার এই রূপ বেছে নিয়েছিলেন তখনকার কিছু নেটওয়ার্ক-ফাইল-ব্যবস্থার রীতি মেনে, যেখানে // মানে “এবার একটি কম্পিউটারের নাম আসছে”। পরে তিনি নিজেই একাধিক সাক্ষাৎকারে বলেছেন, ফিরে তাকালে স্ল্যাশ দুটি অপ্রয়োজনীয় মনে হয় — কোটি কোটি মানুষ বছরের পর বছর বাড়তি দুটি অক্ষর টাইপ করেছেন, বিজ্ঞাপনে ছাপা হয়েছে, মুখে উচ্চারণ করা হয়েছে।

তবু কেউ এটি বদলায় না। কারণ ওয়েবের সবচেয়ে বড় মূল্যবোধ পেছনের দিকে সামঞ্জস্য (backward compatibility): ১৯৯০-এর দশকের একটি HTML পাতা আজকের ব্রাউজারেও খোলে, আর সেই পাতার লিংকও কাজ করে। একটি ঠিকানার নিয়ম বদলালে পৃথিবীর অগণিত পাতা, ইমেইল, ছাপা কার্ড, QR কোড ভেঙে যেত। এজন্যই ব্রাউজাররা আজ URL পড়ে WHATWG-এর URL Standard মেনে, যা অনেকটা “বাস্তবে যা চলছে তার দলিল” — যেমন কেউ ভুল করে \ লিখলে ব্রাউজার সেটিকে / ধরে নেয়, বা ঠিকানার ঘরে শুধু abcltech.com লিখলে নিজেই scheme বসিয়ে নেয়। নিয়ম কঠোর করার চেয়ে ভাঙা জিনিস চালিয়ে নেওয়াকে ওয়েব বেশি গুরুত্ব দেয়।

একই কারণে ফাইলের নাম বা ঠিকানার ছোট সিদ্ধান্তও আপনার সাইটে বছরের পর বছর টিকে থাকে। আজ Product Page FINAL(2).html নামে একটি পাতা প্রকাশ করলে, আর কেউ সেটি শেয়ার করলে, আপনাকে চিরকাল সেই নাম বা একটি redirect বয়ে বেড়াতে হবে। তাই শুরু থেকেই ছোট হাতের অক্ষর, হাইফেন আর অর্থবহ, স্থায়ী নাম — products/rice.html.

মূল উপলব্ধি: যে জিনিস অনেকে ব্যবহার করে, তার নকশার ভুলও স্থায়ী হয়ে যায়। ইন্টারফেস — হোক সেটা একটি URL, একটি ফাংশনের নাম বা একটি API — প্রকাশের আগে ভাবুন; পরে বদলানোর দাম শোধ করে সবাই।

প্র ০৩নিজের সাইটের ভেতরে relative, root-relative নাকি absolute — একটি পেশাদার দল কোনটি বেছে নেবে?

এটি একটি সত্যিকারের trade-off, আর উত্তর নির্ভর করে সাইটটি কোথায় কোথায় চলবে তার ওপর।

  • Absolute (https://amardokan.example/about.html): সবচেয়ে স্পষ্ট, কিন্তু সবচেয়ে অনমনীয়। ডেভেলপারের নিজের কম্পিউটারে, পরীক্ষার (staging) সার্ভারে আর আসল সাইটে — তিন জায়গায় তিন রকম ডোমেইন। Absolute লিংক থাকলে পরীক্ষার সাইটে ক্লিক করলেই আসল সাইটে চলে যাবেন, ভুলটা টেরও পাবেন না। ডোমেইন বদলালে (যেমন .com থেকে .com.bd) প্রতিটি পাতা খুঁজে বদলাতে হবে।
  • Root-relative (/about.html): ডোমেইন বদলালেও চলে, পাতা যে ফোল্ডারেই থাকুক একই লেখা কাজ করে — তাই বড় সাইটের menu, CSS, লোগোতে জনপ্রিয়। দুর্বলতা: সাইটটি যদি ডোমেইনের গোড়ায় না থেকে একটি সাব-ফোল্ডারে থাকে — যেমন GitHub Pages-এর project সাইট username.github.io/myshop/ — তাহলে /about.html খুঁজবে ভুল জায়গায়। আর ডাবল-ক্লিক করে (file://) খুললে তো কাজই করে না।
  • Relative (../about.html): সবচেয়ে বহনযোগ্য — পুরো ফোল্ডারটি যেখানেই কপি করুন, ডাবল-ক্লিক করেও খুলুন, সব চলে। দুর্বলতা: পাতাকে অন্য ফোল্ডারে সরালে তার ভেতরের সব ../ নতুন করে হিসাব করতে হয়, আর গভীর ফোল্ডারে ../../../ পড়তে কষ্ট হয়।

বাস্তবে বড় দলগুলো প্রায়ই হাতে path লেখেই না — static site generator বা framework একটি “base path” সেটিং থেকে সব ঠিকানা নিজেই তৈরি করে, ফলে সাব-ফোল্ডারে বা অন্য ডোমেইনে সরানো এক লাইনের কাজ। আর যেখানে ঠিকানা পাতার বাইরে যায় — rel="canonical", Open Graph ছবি, sitemap, ইমেইল নিউজলেটার — সেখানে নিয়ম অনুযায়ী বা ব্যবহারিক কারণে absolute লাগবেই, কারণ সেগুলো যে পড়বে তার কাছে “বর্তমান পাতা” বলে কিছু নেই। পুরোনো দিনের //cdn… (protocol-relative) কৌশল এখন আর দরকার নেই — সব জায়গায় সরাসরি https:// লিখুন।

মূল উপলব্ধি: “সেরা path” বলে কিছু নেই; আছে “এই সাইট কোথায় কোথায় চলবে” প্রশ্নের উত্তর। সিদ্ধান্তটি একবার নিয়ে পুরো সাইটে একই নিয়ম মেনে চলাই আসল পেশাদারিত্ব।

প্র ০৪সার্চ ইঞ্জিন লিংককে “ভোট” ধরে কেন, আর nofollow, ugc, sponsored কেন এল?

১৯৯০-এর দশকের শেষে সার্চ ইঞ্জিনগুলো পাতার ভেতরের শব্দ গুনে ফল সাজাত — ফলে যে পাতায় একটি শব্দ সবচেয়ে বেশিবার লেখা, সেটিই ওপরে। ঠকানো ছিল খুব সহজ। স্ট্যানফোর্ডের দুই ছাত্র Larry Page আর Sergey Brin অন্যভাবে ভাবলেন: একাডেমিক জগতে যে গবেষণাপত্র বেশি উদ্ধৃত হয়, সেটি গুরুত্বপূর্ণ — ওয়েবেও কি তাই নয়? তাঁদের PageRank অ্যালগরিদম প্রতিটি লিংককে একটি ভোট ধরে, আর গুরুত্বপূর্ণ পাতার ভোটের ওজন বেশি। এই ধারণার ওপর দাঁড়িয়েই Google-এর যাত্রা শুরু।

কিন্তু ভোট থাকলে ভোট-কেনাও আসে। ব্লগের মন্তব্যের ঘরে, ফোরামে, উইকিতে স্বয়ংক্রিয় প্রোগ্রাম দিয়ে লাখ লাখ লিংক বসানো শুরু হলো — comment spam. ২০০৫ সালে Google আর অন্য বড় সার্চ ইঞ্জিনগুলো মিলে চালু করে rel="nofollow": “এই লিংকটি আমার সুপারিশ নয়, এর জন্য ভোট গুনো না।” ব্লগ সফটওয়্যারগুলো মন্তব্যের সব লিংকে এটি নিজে থেকেই বসাতে শুরু করে, ফলে স্প্যাম করার লাভ কমে যায়।

সময়ের সাথে প্রশ্ন উঠল — “সুপারিশ নয়” কি একরকম? টাকা নিয়ে দেওয়া বিজ্ঞাপনী লিংক আর পাঠকের মন্তব্যের লিংক তো আলাদা জিনিস। ২০১৯ সালে Google যোগ করে আরও দুটি মান: sponsored (বিজ্ঞাপন, affiliate, টাকার বিনিময়ে লিংক) আর ugc (ব্যবহারকারীর লেখা)। একই সাথে জানায়, এগুলোকে কঠোর আদেশ নয়, “ইঙ্গিত” হিসেবে দেখা হবে। আজও টাকা নিয়ে লিংক দিয়ে তা না জানানো Google-এর স্প্যাম-নীতির লঙ্ঘন; অনলাইন মার্কেটপ্লেসে “high DA backlink” বা “guest post” বিক্রির অনেক কাজ ঠিক এই ঝুঁকিতে পড়ে।

মূল উপলব্ধি: যে মাপকাঠি গুরুত্বপূর্ণ হয়ে ওঠে, মানুষ তা নিয়ে কারসাজি শুরু করে — আর তখন নিয়ম বানাতে হয়। একজন সৎ ওয়েব-নির্মাতা হিসেবে আপনার কাজ সহজ: লিংক যেমন, তেমন করেই জানিয়ে দিন।

প্র ০৫এত মানুষ <div onclick> বা <a href="#"> দিয়ে বাটন বানায় কেন, আর এর আসল ক্ষতিটা কোথায়?

কারণটা প্রায়ই ইতিহাস আর অভ্যাস। একসময় <button>-কে CSS দিয়ে সাজানো ছিল ঝামেলার — প্রতিটি ব্রাউজারে আলাদা চেহারা, বাড়তি border আর padding. অনেকে তাই <a href="#"> নিয়ে নিজের মতো সাজাতেন, আর JavaScript দিয়ে কাজ বসাতেন। পরে JavaScript framework-এর যুগে “সবকিছুই একটা <div>, ক্লিক বসিয়ে দাও” হয়ে উঠল সহজ পথ। আর এখন AI এই লক্ষ লক্ষ পুরোনো কোড থেকে শিখেছে বলে প্রায়ই সেই একই ধাঁচ ফিরিয়ে দেয়। অথচ আজ <button>-এর চেহারা CSS দিয়ে পুরোপুরি বদলানো যায় (পর্ব ৪৩)।

ক্ষতিটা চোখে দেখা যায় না বলেই বিপজ্জনক। মাউস ব্যবহারকারীর কাছে সব ঠিক; কিন্তু নকল বাটনে Tab দিয়ে পৌঁছানো যায় না, Enter বা Space কাজ করে না, screen reader একে বাটন বলে চেনে না। <a href="#">-এর সমস্যা আরও সূক্ষ্ম: screen reader বলে “link”, তাই ব্যবহারকারী আশা করেন অন্য কোথাও যাবেন; JavaScript ব্যর্থ হলে পাতা ওপরে লাফ দেয় আর ঠিকানায় # যোগ হয়; কেউ নতুন ট্যাবে খুললে একই পাতা আবার খোলে। উল্টো ভুলও আছে — অন্য পাতায় যাওয়ার জন্য <button onclick="location.href=…">: তখন নতুন ট্যাবে খোলা, লিংক কপি বা বুকমার্ক করা যায় না, আর সার্চ ইঞ্জিন সেই পাতা খুঁজেই পায় না, কারণ crawler লিংক অনুসরণ করে, বাটন চাপে না।

WAI-ARIA-র লেখকরা এজন্য একটি “প্রথম নিয়ম” লিখে দিয়েছেন: নিজস্ব অর্থ আর আচরণসহ কোনো HTML element থাকলে সেটিই ব্যবহার করুন, role দিয়ে নকল বানাবেন না। <div role="button" tabindex="0"> করেও আপনাকে নিজের হাতে Enter আর Space-এর কোড লিখতে হবে, focus-এর চেহারা দিতে হবে — যা <button> বিনা পয়সায় দেয়। আধুনিক router-গুলোও তাই আসল <a href> রাখে, শুধু ক্লিক ধরে পাতা না বদলে ভেতরের অংশ বদলায় — JavaScript না চললেও লিংক কাজ করে।

মূল উপলব্ধি: HTML element শুধু চেহারা নয়, একটি চুক্তি — ব্রাউজার, কিবোর্ড, screen reader আর সার্চ ইঞ্জিন সবাই সেই চুক্তি মেনে আচরণ করে। ঠিক element বেছে নিলে এই সব সুবিধা আপনি বিনা খরচে পান।

অনুশীলন

খাতা-কলম নিয়ে বসুন — বেশিরভাগ কাজে কোড লিখতে হবে না, ভাবতে হবে।

  1. Path ধাঁধা: অংশ ৩-এর ফোল্ডার-গাছটি দেখুন। এবার আপনি আছেন blog/index.html পাতায়। সেখান থেকে (ক) css/style.css, (খ) blog/posts/photo.jpg, (গ) সাইটের মূল index.html — এই তিনটির relative path লিখুন। তারপর তিনটিরই root-relative রূপ লিখুন।

    blog/index.html আছে /blog/ ফোল্ডারে, তাই root-এ যেতে একটি ../ লাগে।

    (ক) ../css/style.css — এক ধাপ উঠে root, তারপর css/. Root-relative: /css/style.css.

    (খ) posts/photo.jpg (বা ./posts/photo.jpg) — নিচে নামা, উপরে ওঠা নয়। Root-relative: /blog/posts/photo.jpg.

    (গ) ../index.html. Root-relative: /index.html, অথবা শুধু / — সার্ভার ফোল্ডারের ঠিকানায় সাধারণত index.html-ই দেখায়। যাচাই করতে অংশ ৩-এর JavaScript কোডে page-কে https://amardokan.example/blog/index.html করে নিজের উত্তরগুলো তালিকায় দিয়ে চালান।

  2. ভাঙা সূচিপত্র মেরামত: একজন বন্ধুর পাতায় সূচিপত্রের তিনটি লিংকেই ভুল আছে — দুটি একেবারেই কাজ করে না, আর একটি হয়তো চলে, কিন্তু নিয়মবিরুদ্ধ। কোডটি এমন: <a href="#Price"> → <section id="price">; <a href="#delivery area"> → <section id="delivery area">; আর <a href="contact"> → <section id="contact">. তিনটি ভুল খুঁজে ঠিক করুন।

    (১) #Price আর price — id-তে বড়-ছোট অক্ষর আলাদা। (২) id-র ভেতরে ফাঁকা জায়গা নিয়মে চলে না — ঠিকানায় এটি %20 হয়ে যায়; আধুনিক ব্রাউজার মিলিয়ে নিলেও validator error দেখায়, আর CSS-এর # selector দিয়ে একে ধরাই যায় না। delivery-area লিখুন। (৩) href="contact"-এ # নেই, তাই ব্রাউজার “contact” নামের একটি ফাইল খুঁজবে। ঠিক করা রূপটি নিচে চালিয়ে দেখুন — তিনটি লিংকই কাজ করবে:

    <!doctype html>
    <html lang="bn">
    <head>
      <meta charset="utf-8">
      <title>মেরামত করা সূচিপত্র</title>
      <style>section { min-height: 200px; } :target { background: #e0f2fe; }</style>
    </head>
    <body>
      <nav>
        <a href="#price">দাম</a> |
        <a href="#delivery-area">ডেলিভারি এলাকা</a> |
        <a href="#contact">যোগাযোগ</a>
      </nav>
      <section id="price"><h2>দাম</h2></section>
      <section id="delivery-area"><h2>ডেলিভারি এলাকা</h2></section>
      <section id="contact"><h2>যোগাযোগ</h2></section>
    </body>
    </html>

    প্রিভিউতে তিনটি লিংক আর তিনটি অংশ; যেকোনো লিংকে ক্লিক করলে সেই অংশে পৌঁছে হালকা নীল হয়। এবার ইচ্ছা করে #contact-এর # মুছে ক্লিক করুন — লাফ হবে না, নিচে আসবে লিংকে ক্লিক → contact: ব্রাউজার এখন এটিকে “contact” নামের একটি ফাইল ভাবছে।

  3. লিংক অডিট: আপনার পছন্দের যেকোনো একটি সংবাদ বা অনলাইন দোকানের সাইট খুলুন। (ক) কতগুলো লিংকের লেখা “এখানে ক্লিক করুন”, “আরও পড়ুন” বা শুধু আইকন? (খ) কোনো বাইরের লিংকে ডান-ক্লিক করে “Inspect” চাপুন — target আর rel কী লেখা আছে? (গ) পাতায় কোনো “বাটন” কি আসলে <div> বা <a href="#">?

    সাধারণত যা পাবেন: খবরের সাইটে “আরও পড়ুন” ধরনের লিংক অনেক — screen reader-এর লিংক-তালিকায় সেগুলো একের পর এক একই নাম। বাইরের লিংকে প্রায়ই target="_blank" rel="noopener" বা rel="nofollow"; বিজ্ঞাপন বা affiliate লিংকে rel="sponsored" থাকার কথা। Elements প্যানেলে মেনু খোলার “হ্যামবার্গার” আইকন বা “কার্টে যোগ” প্রায়ই <div>. একটি সহজ পরীক্ষা: মাউস সরিয়ে রেখে শুধু Tab চাপুন — যেখানে ফোকাস যায় না বা ফোকাস দেখা যায় না, সেখানেই সমস্যা।

  4. ভাঙা লিংকের খোঁজ: নিজের বানানো যেকোনো HTML পাতা (বা পর্ব ০৩-এর পাতাটি) খুলে DevTools-এর Network ট্যাবে দেখুন কোনো 404 আছে কি না। তারপর ইচ্ছা করে CSS ফাইলের নামে একটি অক্ষর বড় হাতের করে দিন (Style.css). Windows-এ কী হলো? এই পাতা Linux সার্ভারে আপলোড হলে কী হতো?

    Network ট্যাবে প্রতিটি অনুরোধের পাশে স্ট্যাটাস থাকে — 200 মানে পাওয়া গেছে, লাল রঙের 404 মানে ভাঙা। Windows-এর ফাইল-ব্যবস্থা নামের বড়-ছোট অক্ষর আলাদা ধরে না, তাই নিজের কম্পিউটারে Style.css লিখলেও CSS ঠিকই লোড হয় — ভুলটা লুকিয়ে থাকে। cPanel-এর মতো Linux সার্ভারে Style.css আর style.css দুটি আলাদা নাম, তাই সেখানে CSS-এর অনুরোধ 404 পাবে আর পাতা সাদামাটা দেখাবে। এজন্যই নিয়ম: সব ফাইলের নাম ছোট হাতের অক্ষরে, আর আপলোডের পর আসল সাইটে আরেকবার Network ট্যাব দেখা।

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

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

ক্রমএকটি URL-এর অংশগুলো বাঁ থেকে ডানে সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Scheme — https://
  2. Host — shop.amardokan.example
  3. Port — :443
  4. Path — /products/rice.html
  5. Query — ?size=5kg
  6. Fragment — #reviews

একটি পাতার ঠিকানা https://site.example/blog/posts/a.html. সেই পাতায় <a href="../index.html"> লিংকটি কোথায় নেবে?

  • https://site.example/blog/index.html
  • https://site.example/index.html
  • https://site.example/blog/posts/index.html
  • https://site.example/posts/index.html

URL-এর কোন অংশটি ব্রাউজার কখনো সার্ভারে পাঠায় না?

  • Path
  • Query
  • Host
  • Fragment (#-এর পরের অংশ)

আধুনিক ব্রাউজারে rel ছাড়া একটি target="_blank" লিংক খুললে নতুন ট্যাবের পাতা window.opener-এ কী পায়?

  • আগের ট্যাবের পূর্ণ নিয়ন্ত্রণ
  • কিছুই না — null, কারণ এটি নিজে থেকেই noopener
  • শুধু আগের পাতার ঠিকানা
  • লিংকটি খোলেই না, error দেখায়

একটি রিভিউ ব্লগে কোম্পানির কাছ থেকে টাকা নিয়ে তাদের পণ্যের পাতায় লিংক দেওয়া হলো। লিংকে কোন rel মান দেওয়া উচিত?

  • noopener
  • ugc
  • sponsored
  • noreferrer

Screen reader ব্যবহারকারীর জন্য কোন লিংক টেক্সটটি সবচেয়ে ভালো?

  • এখানে ক্লিক করুন
  • আরও পড়ুন
  • https://amardokan.example/policy/return.html
  • পণ্য ফেরত দেওয়ার নিয়ম

একটি অনলাইন দোকানে “কার্টে যোগ করুন” চাপলে পাতা না বদলে শুধু কার্টের সংখ্যা বাড়ে। এর জন্য কোন element সবচেয়ে উপযুক্ত?

  • <a href="#"> আর তাতে ক্লিকের কোড
  • <button type="button">
  • <div> আর তাতে ক্লিকের কোড
  • <a href="javascript:void(0)">

শব্দকোষ

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

মনে রাখুন

  1. লিংক = <a href="ঠিকানা">অর্থবহ লেখা</a>; href না থাকলে লিংকই নয়।
  2. URL-এর অংশ: scheme, host, port, path, query, fragment — fragment কখনো সার্ভারে যায় না।
  3. Relative হিসাব হয় বর্তমান ফোল্ডার থেকে (../ = এক ধাপ উপরে), root-relative সাইটের গোড়া থেকে (/), absolute-এ পুরো ঠিকানা।
  4. পাতার ভেতরে লাফ: href="#x" ↔ id="x", বানান হুবহু; :target দিয়ে রাঙানো; <base> থাকলে এই হিসাবও বদলায়।
  5. নতুন ট্যাব খুব কম, rel সৎভাবে (sponsored, ugc, nofollow), লেখায় গন্তব্য স্পষ্ট; যাওয়া = লিংক, কাজ = বাটন।

পরের পর্বে: আজ যে path-এর হিসাব শিখলেন, তার সবচেয়ে বড় পরীক্ষা ছবি — <img src>-এর একটি ভুল ../ মানেই ভাঙা ছবি। সাথে অডিও, ভিডিও আর অন্য সাইটের জিনিস পাতায় বসানোর <iframe>.

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

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