Display & Positioning

ডিসপ্লে ও পজিশনিং

Read: ~24 min Intermediate 5 practice problems Live preview runner

1. Two Different Jobs: display vs position

display decides what kind of box an element generates and how it behaves next to its neighbors. position decides whether an element sits in the normal document flow at all, and if not, exactly where it goes instead. Beginners often confuse the two because both "move things around" — but they solve completely different problems, and this module treats them separately before showing how they interact.

display ঠিক করে একটি এলিমেন্ট কোন ধরনের বক্স তৈরি করে এবং পাশের এলিমেন্টগুলোর সাথে কীভাবে আচরণ করে। position ঠিক করে এলিমেন্টটি সাধারণ document flow-তে থাকবে কিনা, আর না থাকলে ঠিক কোথায় বসবে। দুটোই "জিনিস সরায়" বলে নতুনরা প্রায়ই গুলিয়ে ফেলেন — কিন্তু এরা সম্পূর্ণ ভিন্ন সমস্যার সমাধান করে, তাই এই মডিউলে আগে আলাদা করে বোঝা হবে, তারপর একসাথে কীভাবে কাজ করে তা দেখানো হবে।

2. display: block, inline, inline-block & none

A block element takes the full available width and always starts on a new line (<div>, <p>). An inline element only takes as much width as its content and sits in the middle of a sentence (<span>, <a>) — but it ignores width/height and top/bottom margin. inline-block is the best of both: flows inline but respects width, height, and margin. display: none removes the element entirely — it takes up no space at all, unlike visibility: hidden which hides it but keeps its space.

block এলিমেন্ট পুরো available width নেয় এবং সবসময় নতুন লাইনে শুরু হয় (<div>, <p>)। inline এলিমেন্ট শুধু তার কনটেন্ট যতটুকু জায়গা লাগে ততটুকুই নেয় এবং বাক্যের মাঝে বসে (<span>, <a>) — কিন্তু এটি width/height এবং উপর-নিচের margin উপেক্ষা করে। inline-block দুটোর সেরা দিক নেয়: লাইনের মধ্যে থাকে কিন্তু width, height, margin মেনে চলে। display: none এলিমেন্টটি সম্পূর্ণ সরিয়ে দেয় — কোনো জায়গা নেয় না, যেখানে visibility: hidden এলিমেন্টটি লুকায় কিন্তু তার জায়গা রেখে দেয়।
display-values.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Display values</title>
</head>
<body>
  <div class="block-a">Block A (full width)</div>
  <div class="block-b">Block B (full width)</div>

  <p>
    This sentence has an <span class="inline-tag">inline span</span>
    sitting right in the middle of it, plus two
    <span class="chip">inline-block</span><span class="chip">chips</span>.
  </p>

  <div class="hidden-box">You will never see this (display: none)</div>
</body>
</html>
style.css
.block-a, .block-b {
  background: #e6f4e8;
  padding: 8px;
  margin-bottom: 6px;
}

.inline-tag {
  background: #fff7ed;
  color: #ea580c;
  padding: 2px 4px; /* top/bottom padding does NOT push neighboring lines apart */
}

.chip {
  display: inline-block;
  width: 90px;          /* width works because it's inline-block */
  padding: 6px 10px;
  margin: 0 4px;
  background: #0f172a;
  color: white;
  text-align: center;
  border-radius: 6px;
}

.hidden-box {
  display: none; /* removed entirely — takes up zero space */
}
ValueNew line?Respects width/height?বাংলায়
blockYesYesপুরো width নেয়, নতুন লাইনে শুরু হয়।
inlineNoNoবাক্যের ভেতরে বসে, width/height মানে না।
inline-blockNoYesইনলাইনের মতো বসে কিন্তু সাইজ মানে।
none——সম্পূর্ণভাবে সরিয়ে দেয়, জায়গা রাখে না।

3. position: static & relative

Every element starts with position: static — the default. It sits exactly where the normal document flow places it, and top/left/right/bottom have no effect on it. position: relative keeps the element in the normal flow (its original space is still reserved) but lets you nudge it visually using top/left/etc, offset from where it would otherwise sit.

প্রতিটি এলিমেন্ট ডিফল্টভাবে position: static নিয়ে শুরু হয়। এটি ঠিক সেখানেই বসে যেখানে normal flow তাকে রাখে, এবং top/left/right/bottom এর কোনো প্রভাব নেই এর ওপর। position: relative এলিমেন্টটিকে normal flow-তেই রাখে (তার আসল জায়গা সংরক্ষিত থাকে) কিন্তু top/left ইত্যাদি দিয়ে তাকে সেই আসল জায়গা থেকে সরিয়ে দেখানো যায়।
relative.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>position: relative</title>
</head>
<body>
  <div class="box">1. static (default)</div>
  <div class="box nudged">2. relative, nudged 15px down & right</div>
  <div class="box">3. static — notice box 2's original space is still empty above</div>
</body>
</html>
style.css
.box {
  padding: 12px;
  margin-bottom: 6px;
  background: #eff6ff;
  border: 1px solid #93c5fd;
}

.nudged {
  position: relative;
  top: 15px;
  left: 15px;
  background: #e6f4e8;
  border-color: #39b549;
}

4. position: absolute — Escaping the Flow

position: absolute removes the element from the normal document flow completely — no space is reserved for it — and positions it using top/left/right/bottom relative to its nearest positioned ancestor — the closest parent with a position other than static. If no ancestor is positioned, it falls back to the <html> element itself, which is almost never what you want. This is why you'll see position: relative on a parent purely to "anchor" an absolutely positioned child.

position: absolute এলিমেন্টটিকে normal document flow থেকে সম্পূর্ণ সরিয়ে ফেলে — এর জন্য কোনো জায়গা সংরক্ষিত থাকে না — এবং top/left/right/bottom দিয়ে এটিকে তার নিকটতম positioned ancestor-এর সাপেক্ষে বসায় — অর্থাৎ যে parent-এর position static ছাড়া অন্য কিছু, তার মধ্যে সবচেয়ে কাছেরটি। কোনো ancestor positioned না থাকলে এটি <html> এলিমেন্টের সাপেক্ষে বসে, যা প্রায় কখনোই কাম্য নয়। এই কারণেই প্রায়ই দেখা যায় parent-কে শুধু "অ্যাঙ্কর" করার জন্য position: relative দেওয়া হয়, যাতে child-টি ঠিক জায়গায় বসে।
.card { position: relative; } Product Card Nearest positioned ancestor NEW .badge { position: absolute; top: 15px; right: 15px; } The badge is positioned relative to the card's edges — NOT the page's edges. Figure 15.1 — badge-টি তার নিকটতম position: relative parent (card)-এর সাপেক্ষে বসেছে।
absolute-badge.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Absolute badge</title>
</head>
<body>
  <div class="card">
    <span class="badge">NEW</span>
    <h3>Wireless Headphones</h3>
    <p>৳ 2,499</p>
  </div>
</body>
</html>
style.css
.card {
  position: relative;   /* anchors the badge below */
  width: 260px;
  padding: 20px;
  border-radius: 10px;
  background: #f8f9fa;
  border: 1px solid #e5e7eb;
}

.badge {
  position: absolute;
  top: 12px;
  right: 12px;
  background: #39b549;
  color: white;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
}
Key insight position: absolute always positions itself relative to its nearest positioned ancestor.

position: absolute সবসময় তার নিকটতম position: relative (বা অন্য positioned) বাবা-মা এলিমেন্টের সাপেক্ষে বসে।

5. position: fixed & sticky

position: fixed is like absolute but anchored to the browser viewport instead of an ancestor — it stays in the same screen position even while the page scrolls, which is how "always-visible" chat buttons and cookie banners work. position: sticky behaves like relative until the page scrolls to a chosen threshold (e.g. top: 0), then it "sticks" in place like fixed — commonly used for section headers that stay visible while you scroll through their content.

position: fixed অনেকটা absolute-এর মতোই, কিন্তু কোনো ancestor-এর বদলে ব্রাউজার viewport-এর সাপেক্ষে বসে — পেজ স্ক্রল হলেও এটি স্ক্রিনের একই জায়গায় থেকে যায়, যেভাবে সবসময় দেখা যায় এমন চ্যাট বাটন বা কুকি ব্যানার কাজ করে। position: sticky শুরুতে relative-এর মতো আচরণ করে, তারপর পেজ একটি নির্দিষ্ট সীমায় (যেমন top: 0) পৌঁছালে fixed-এর মতো "আটকে" যায় — কনটেন্টের ভেতর স্ক্রল করার সময় দৃশ্যমান থাকা সেকশন হেডারের জন্য এটি খুব সাধারণ ব্যবহার।
sticky-header.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sticky header</title>
</head>
<body>
  <div class="scroll-area">
    <div class="sticky-title">I stick to the top while you scroll ⬇</div>
    <p>Paragraph one — keep scrolling inside this box.</p>
    <p>Paragraph two.</p>
    <p>Paragraph three.</p>
    <p>Paragraph four.</p>
    <p>Paragraph five.</p>
    <p>Paragraph six.</p>
  </div>
</body>
</html>
style.css
.scroll-area {
  height: 160px;
  overflow-y: scroll;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 0 12px;
}

.sticky-title {
  position: sticky;
  top: 0;
  background: #39b549;
  color: white;
  padding: 8px 4px;
  font-weight: 700;
}

6. z-index & Stacking Context

When positioned elements overlap, z-index (a plain number) decides which one appears on top — higher wins. But z-index only works on elements with a position other than static. Certain CSS properties (like opacity below 1, or transform) create a new stacking context, which traps its children's z-index comparisons inside it — this is the most common reason a "correct" z-index sometimes appears not to work.

যখন positioned এলিমেন্টগুলো একে অপরের ওপর ওভারল্যাপ করে, তখন z-index (একটি সাধারণ সংখ্যা) ঠিক করে কোনটি ওপরে দেখাবে — বড় সংখ্যা জেতে। কিন্তু z-index শুধু তখনই কাজ করে যখন এলিমেন্টের position static ছাড়া অন্য কিছু। কিছু CSS প্রপার্টি (যেমন 1-এর কম opacity, বা transform) একটি নতুন stacking context তৈরি করে, যা তার child-দের z-index তুলনাকে সেই context-এর ভেতরেই আটকে রাখে — এটাই সবচেয়ে সাধারণ কারণ যখন একটি "সঠিক" z-index কাজ করছে না বলে মনে হয়।
z-index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>z-index stacking</title>
</head>
<body>
  <div class="stack">
    <div class="layer back">z-index: 1</div>
    <div class="layer middle">z-index: 2</div>
    <div class="layer front">z-index: 3 (on top)</div>
  </div>
</body>
</html>
style.css
.stack { position: relative; height: 140px; }

.layer {
  position: absolute;
  width: 160px;
  height: 90px;
  color: white;
  font-weight: 700;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.back   { top: 0;  left: 0;  background: #93c5fd; z-index: 1; }
.middle { top: 25px; left: 60px; background: #2563eb; z-index: 2; }
.front  { top: 50px; left: 120px; background: #0f172a; z-index: 3; }

7. Common Positioning Bugs

❌ Common Mistakes (সাধারণ ভুল)

  • Using absolute with no relative parent — element jumps to the page corner
  • Forgetting display: none hides accessibility tools too, not just visuals
  • Expecting z-index to work on a static element
  • A parent with overflow: hidden silently clipping a stuck/absolute child

✅ Safer Habits

  • Always add position: relative to the intended anchor first
  • Use DevTools to confirm which ancestor is actually "positioned"
  • Give positioned elements an explicit z-index, don't rely on source order
  • Prefer sticky over fixed when the element should scroll away eventually
Watch out A parent needs at least one non-static position declared for it to become the reference point for an absolutely positioned child — simply having padding or a border is not enough.

একটি child ঠিকভাবে বসার জন্য parent-এ অন্তত একটি non-static position থাকা লাগবে — শুধু padding বা border থাকলেই যথেষ্ট নয়।

8. Practice Problems

Every problem has a Show Answer button with real, runnable CSS. Try it yourself first.

প্রতিটি প্রশ্নের সাথে Show Answer বাটন আছে, যেখানে চালু-করার-যোগ্য CSS দেওয়া আছে। প্রথমে নিজে চেষ্টা করুন।
  1. Explain in one sentence why an inline <span> ignores a width: 200px rule, and name a fix.
    এক বাক্যে ব্যাখ্যা করুন কেন একটি inline <span> width: 200px উপেক্ষা করে, এবং একটি সমাধান বলুন।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: Inline elements only take up as much horizontal space as their content needs and do not accept an explicit width; changing its display to inline-block (or block) makes the width rule apply.

    Inline এলিমেন্ট শুধু তার কনটেন্ট যতটুকু জায়গা লাগে ততটুকুই নেয় এবং নির্দিষ্ট width গ্রহণ করে না; display-কে inline-block (বা block) করলে width রুল কাজ করবে।

  2. Build a card with position: relative and place a small "SALE" badge in its top-left corner using position: absolute.
    position: relative দিয়ে একটি কার্ড বানান এবং position: absolute দিয়ে এর ওপরের-বাম কোণায় একটি ছোট "SALE" ব্যাজ বসান।
    ✨ Show Answer (উত্তর দেখুন)
    ans2.html
    <div class="card">
      <span class="badge">SALE</span>
      <h3>Running Shoes</h3>
    </div>
    style.css
    .card {
      position: relative;
      width: 220px;
      padding: 20px;
      background: #f8f9fa;
      border-radius: 8px;
    }
    
    .badge {
      position: absolute;
      top: 10px;
      left: 10px;
      background: #dc2626;
      color: white;
      font-size: 12px;
      font-weight: 700;
      padding: 4px 8px;
      border-radius: 4px;
    }
  3. Create a "back to top" button fixed to the bottom-right corner of the viewport.
    viewport-এর নিচের-ডান কোণায় একটি "back to top" বাটন position: fixed দিয়ে বানান।
    ✨ Show Answer (উত্তর দেখুন)
    ans3.html
    <button class="top-btn">↑ Top</button>
    style.css
    .top-btn {
      position: fixed;
      bottom: 20px;
      right: 20px;
      padding: 10px 16px;
      border: none;
      border-radius: 999px;
      background: #39b549;
      color: white;
      font-weight: 700;
      cursor: pointer;
      box-shadow: 0 6px 16px rgba(0,0,0,0.2);
    }
  4. Two absolutely positioned boxes overlap. Make the second one appear above the first without changing the HTML order.
    দুটি absolutely positioned বক্স ওভারল্যাপ করছে। HTML-এর ক্রম না বদলিয়ে দ্বিতীয়টিকে প্রথমটির ওপরে দেখান।
    ✨ Show Answer (উত্তর দেখুন)
    ans4.html
    <div class="wrap">
      <div class="a">A (drawn first)</div>
      <div class="b">B (should be on top)</div>
    </div>
    style.css
    .wrap { position: relative; height: 120px; }
    
    .a, .b {
      position: absolute;
      width: 140px;
      height: 70px;
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .a { top: 0; left: 0; background: #93c5fd; z-index: 1; }
    .b { top: 20px; left: 40px; background: #0f172a; z-index: 2; } /* higher z-index wins */
  5. In two sentences, explain the difference between position: sticky and position: fixed.
    দুই বাক্যে ব্যাখ্যা করুন — position: sticky এবং position: fixed-এর মধ্যে পার্থক্য কী।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: fixed is permanently anchored to the viewport and never scrolls with the page. sticky scrolls normally with its container until it reaches the given threshold (like top: 0), then stays in place only until its container scrolls out of view.

    fixed সবসময় viewport-এর সাপেক্ষে স্থির থাকে, পেজের সাথে স্ক্রল হয় না। sticky প্রথমে তার container-এর সাথে স্বাভাবিকভাবে স্ক্রল হয়, নির্দিষ্ট সীমায় (যেমন top: 0) পৌঁছালে আটকে যায় — এবং container ভিউ থেকে বেরিয়ে গেলে আবার সরে যায়।

Summary — Module 15

display controls what kind of box an element makes (block, inline, inline-block, or none). position controls whether an element stays in normal flow (static, relative) or escapes it (absolute, fixed, sticky). An absolutely positioned element always anchors to its nearest positioned ancestor, and z-index only resolves stacking order between positioned elements.

display নিয়ন্ত্রণ করে একটি এলিমেন্ট কোন ধরনের বক্স তৈরি করে (block, inline, inline-block, বা none)। position নিয়ন্ত্রণ করে এলিমেন্ট normal flow-তে থাকবে কিনা (static, relative) নাকি সেখান থেকে বেরিয়ে যাবে (absolute, fixed, sticky)। একটি absolutely positioned এলিমেন্ট সবসময় তার নিকটতম positioned ancestor-এর সাপেক্ষে বসে, আর z-index শুধু positioned এলিমেন্টগুলোর মধ্যে স্ট্যাকিং অর্ডার ঠিক করে।

Next Module → Flexbox: One-Dimensional Layout — একটি অক্ষ বরাবর এলিমেন্ট align ও distribute করা।