এই পর্বে যা শিখবেন
- Flexbox কোন সমস্যার সমাধান করল — float, table, inline-block আর উল্লম্বভাবে মাঝখানে বসানোর পুরোনো যন্ত্রণা, আর spec-এর ২০০৯ থেকে ২০১২-র বিবর্তন
- flex container আর flex item, main axis আর cross axis —
flex-directionবদলালে কী ঘোরে justify-content,align-items,align-self,flex-wrap,align-contentআরgapদিয়ে সাজানো- item-এর মাপের অ্যালগরিদম —
flex-grow,flex-shrink,flex-basisআরflexshorthand, সংখ্যা ধরে হিসাব min-width: auto-এর ফাঁদ,margin: auto-এর কৌশল,order-এর অ্যাক্সেসিবিলিটি সমস্যা আর DevTools-এর flex overlay
১ · Flexbox কেন এলো — লেআউটের পুরোনো যন্ত্রণা
ধরুন একটি মোবাইল ব্যাংকিং অ্যাপের ওপরের অংশ বানাচ্ছেন। বাঁয়ে লোগো, ডানে দুটি বোতাম, আর তিনটিই উচ্চতায় ঠিক মাঝখানে। আজ এটি তিন লাইনের CSS. কিন্তু ২০১০-এর দশকের শুরুতেও এই সাধারণ কাজটি ছিল ওয়েব ডেভেলপারদের নিত্যদিনের মাথাব্যথা। “একটি div মাঝখানে বসাবো কীভাবে?” — এই প্রশ্ন নিয়ে তখন এত রসিকতা হতো যে সেটি প্রায় প্রবাদ হয়ে গিয়েছিল।
কারণটা বোঝা দরকার। CSS-এর প্রথম লক্ষ্য ছিল দলিল সাজানো — শিরোনাম, প্যারাগ্রাফ, ছবি, ওপর থেকে নিচে, যেমন পত্রিকার পাতা (পর্ব ২৩-এর normal flow). অ্যাপের মতো ইন্টারফেস বানানোর জন্য কোনো লেআউট-যন্ত্র CSS-এ ছিলই না। তাই ডেভেলপাররা অন্য কাজের জন্য তৈরি জিনিস দিয়ে লেআউট বানাতেন:
| যা চাইতেন | পুরোনো কৌশল | সমস্যা | Flexbox-এ |
|---|---|---|---|
| পাতা বা কলাম সাজানো | <table> দিয়ে পুরো পাতা (layout table) | অর্থহীন markup, screen reader বিভ্রান্ত, ফোনে ভাঙে | display: flex |
| পাশাপাশি কলাম | float: left + clearfix | parent নিজের উচ্চতা হারায়, ক্রম আর ফাঁক সামলানো কঠিন | display: flex + gap |
| সারিতে বোতাম বা মেনু | display: inline-block | HTML-এর ফাঁকা জায়গা থেকে অদ্ভুত ছোট ফাঁক, লেখার baseline-এ ঝুলে থাকা | item-দের মাঝে শুধু gap |
| সব কলাম সমান উঁচু | ব্যাকগ্রাউন্ড ছবি দিয়ে “নকল কলাম”, বা display: table-cell | লেখা বাড়লে মেলে না, ছবি বদলাতে হয় | ডিফল্টেই সমান (stretch) |
| উল্লম্বভাবে মাঝখানে | table-cell + vertical-align, বা position: absolute + transform, বা line-height | প্রতিটির আলাদা শর্ত; লেখা দুই লাইন হলেই ভাঙে | align-items: center |
float আসলে তৈরি হয়েছিল পত্রিকার মতো ছবির পাশ দিয়ে লেখা গড়িয়ে নিতে — পুরো পাতার কাঠামো বানাতে নয়। একটি কাজের যন্ত্র দিয়ে অন্য কাজ করানোয় প্রতিটি লেআউট ভঙ্গুর হতো: একটি লম্বা শিরোনাম বা একটি বাড়তি বোতামেই সব ভেঙে পড়ত। দরকার ছিল এমন একটি যন্ত্র, যাকে বলা যায় “এই জিনিসগুলো এক সারিতে রাখো, ফাঁকা জায়গা এভাবে ভাগ করো, আর সবাইকে মাঝখানে বসাও” — হিসাব ব্রাউজার করবে। সেই যন্ত্রই Flexbox, পুরো নাম CSS Flexible Box Layout.
Flexbox-এর spec একবারে তৈরি হয়নি — তিনবার প্রায় নতুন করে লেখা হয়েছে। ২০০৯ সালের প্রথম খসড়া এসেছিল Mozilla-র নিজস্ব ইন্টারফেস-ভাষা XUL-এর box লেআউট থেকে অনুপ্রাণিত হয়ে; তার লেখার ধরন ছিল display: box আর box-orient, ব্রাউজারে চলত -webkit-box বা -moz-box নামে। ২০১১ সালে একটি মাঝামাঝি রূপ আসে — display: flexbox; Internet Explorer 10 এটিকেই -ms-flexbox নামে চালু করেছিল। শেষে ২০১২ সালে spec Candidate Recommendation পর্যায়ে পৌঁছায় আজকের display: flex আর flex-grow, justify-content-এর মতো নাম নিয়ে। ২০১০-এর দশকের মাঝামাঝির মধ্যে প্রধান ব্রাউজারগুলো prefix ছাড়াই এই চূড়ান্ত রূপটি চালায়। তাই পুরোনো কোডে বা AI-এর উত্তরে display: -webkit-box বা -ms-flexbox দেখলে বুঝবেন সেগুলো পুরোনো খসড়ার অবশেষ — আজ শুধু display: flex লিখলেই চলে (একটি ব্যতিক্রম: লেখা কয়েক লাইনে কেটে দেওয়ার -webkit-line-clamp এখনো পুরোনো display: -webkit-box চায়, যার সাথে লেআউটের কোনো সম্পর্ক নেই)।
Flexbox এখন Baseline Widely available — বহু বছর ধরে সব আধুনিক ব্রাউজারে কোনো vendor prefix ছাড়াই চলে। flex container-এ gap দেওয়াটা সবার শেষে এসেছে (২০২১ সালে Safari যোগ করার পর সব প্রধান ব্রাউজারে), সেটিও এখন Baseline Widely available. তাই এই পর্বের কোনো কিছুর জন্য fallback লাগবে না।
২ · Container আর item — কে কাকে সাজায়
Flexbox-এ সবসময় দুটি পক্ষ। যে element-এ আপনি display: flex লেখেন, সে হয় flex container. আর তার সরাসরি child-রা হয় flex item. container ঠিক করে item-রা কোন দিকে, কতটা ফাঁকে, কোথায় বসবে; প্রতিটি item বলতে পারে সে নিজে কতটা জায়গা নেবে, বা নিজে আলাদা কোথায় বসবে।
মুদি দোকানের একটি তাকের কথা ভাবুন। দোকানদার (container) ঠিক করেন তাকে মালগুলো বাঁ থেকে ডানে সাজবে, মাঝে কতটা ফাঁক থাকবে, সব মাল তাকের মাঝখানে না এক কিনারায়। প্রতিটি মাল (item) — চালের বস্তা, তেলের বোতল, বিস্কুটের কার্টন — নিজের আকার নিয়ে আসে, আর কেউ কেউ বাড়তি জায়গা পেলে ছড়িয়ে বসে। কিন্তু খেয়াল করুন: তাকে বসানো হয়েছে বিস্কুটের কার্টন, কার্টনের ভেতরের বিস্কুটের প্যাকেট নয়। দোকানদারের নিয়ম শুধু কার্টনের ওপর খাটে; ভেতরের প্যাকেট কার্টনের নিজের ব্যাপার। Flexbox-ও শুধু সরাসরি child-দের সাজায় — নাতি-পুতিদের নয়।
নিচের এডিটরে একটি তাক আছে। ভেতরে তিনটি div, একটি p, আর শেষে কোনো ট্যাগ ছাড়া একটি শব্দ। তৃতীয় বাক্সের ভেতরে একটি span-ও আছে।
.shelf {
display: flex;
border: 2px dashed #64748b;
padding: 8px;
}
.box {
background: #fde68a;
border: 1px solid #b45309;
padding: 8px 12px;
margin: 4px;
}
span { background: #bfdbfe; }পাঁচটি জিনিস এক সারিতে বাঁ থেকে ডানে বসেছে — এমনকি block element p-ও আর নতুন লাইনে যায়নি। ট্যাগ ছাড়া “লবণ” শব্দটিও একটি item হয়েছে; ব্রাউজার তাকে একটি অদৃশ্য বাক্সে মুড়ে নেয়, একে বলে anonymous flex item. কিন্তু নীল span আলাদা item হয়নি — সে “তেল” বাক্সের ভেতরে, অর্থাৎ নাতি। সব বাক্স সমান উঁচুও হয়েছে, যদিও কেউ উচ্চতা বলে দেয়নি — এর কারণ অংশ ৫-এ। চেষ্টা করুন: display: flex লাইনটি মুছে দিন — সব আবার পুরোনো নিয়মে ওপর-নিচে চলে গেল। তারপর flex-এর জায়গায় inline-flex লিখুন — তাকটি এবার পুরো লাইন না নিয়ে শুধু নিজের জিনিসগুলোর সমান চওড়া হলো।
এই ছোট পরীক্ষা থেকে Flexbox-এর কয়েকটি মৌলিক নিয়ম বেরিয়ে আসে:
flexবনামinline-flex: দুটিই ভেতরে একই Flexbox চালায়। পার্থক্য শুধু বাইরের আচরণে —flexcontainer নিজে block-এর মতো পুরো লাইন নেয়,inline-flexলেখার লাইনের ভেতরে একটি শব্দের মতো বসে।- item মানেই block-এর মতো বাক্স: সরাসরি child যদি
spanবাa-এর মতো inline element-ও হয়, item হওয়ার পর সে width, height, ওপর-নিচের margin — সব মানে। - কিছু পুরোনো property item-এ কাজ করে না: item-এর ওপর
floatআরvertical-alignউপেক্ষা হয়। - margin মেশে না: পর্ব ১৯-এর margin collapsing flex item-দের মধ্যে হয় না — দুই item-এর 4px + 4px margin মিলে ফাঁক ঠিক 8px.
| container-এ লেখা হয় | item-এ লেখা হয় |
|---|---|
display: flex / inline-flex | flex-grow, flex-shrink, flex-basis |
flex-direction, flex-wrap (একসাথে flex-flow) | flex (তিনটির shorthand) |
justify-content, align-items, align-content | align-self |
gap (row-gap, column-gap) | order, আর margin: auto-এর কৌশল |
৩ · Main axis আর cross axis — Flexbox-এর দুই দিক
Flexbox বোঝার আসল চাবি একটিই: দুটি অক্ষ। item-রা যে দিকে একের পর এক বসে, সেটি main axis (মূল অক্ষ)। তার সাথে সমকোণে আড়াআড়ি দিকটি cross axis. কোনটি main হবে, তা ঠিক করে container-এর flex-direction. Flexbox-এর প্রায় প্রতিটি property “বাঁ-ডান” বা “ওপর-নিচ” নয়, এই দুই অক্ষের ভাষায় কথা বলে। নিচের ডায়াগ্রামে অক্ষ দুটিকে ঘুরতে দেখুন:
- row — ডিফল্ট। কিছু না লিখলে
flex-direction: row. main axis চলে লেখার দিকে — বাংলায় বাঁ থেকে ডানে; item ১, ২, ৩ পরপর বসে। cross axis ওপর থেকে নিচে। খেয়াল করুন, container 110px উঁচু আর item-রা cross axis বরাবর পুরো উচ্চতা জুড়ে টানটান হয়েছে — এটাই ডিফল্টstretch. - row-reverse — উল্টো সারি। main axis-এর শুরু এখন ডানে, তাই ১ সবার ডানে, ৩ সবার বাঁয়ে। HTML-এ ক্রম কিন্তু একই আছে — শুধু চোখে দেখার ক্রম উল্টেছে। এর একটি অ্যাক্সেসিবিলিটি দাম আছে, অংশ ৯-এ দেখব।
- column — অক্ষ ৯০° ঘুরল। main axis এখন ওপর থেকে নিচে, item-রা নিচে নিচে বসে। cross axis হয়ে গেল বাঁ থেকে ডানে, তাই
stretchএখন item-দের চওড়ায় টানছে — সবাই পুরো চওড়া। দেখতে normal flow-এর মতো, কিন্তু ভেতরে Flexbox-এর সব ক্ষমতা আছে। - column-reverse — নিচ থেকে ওপরে। main axis-এর শুরু এখন নিচে: ১ সবার নিচে। চ্যাট অ্যাপের মতো “নতুন বার্তা নিচে” লেআউটে কেউ কেউ এটি ব্যবহার করেন, তবে row-reverse-এর মতো এখানেও HTML-এর ক্রম আর চোখের ক্রম আলাদা হয়ে যায়।
- একই property, ভিন্ন দিক।
justify-content: centerসবসময় main axis বরাবর মাঝখানে আনে — row-তে আনুভূমিকভাবে, column-এ উল্লম্বভাবে। তাই “justify মানে বাঁ-ডান” মুখস্থ করলে column-এ গিয়ে বিভ্রান্ত হবেন। মনে রাখুন অক্ষ দিয়ে: justify = main, align = cross. আরও একটি সূক্ষ্ম কথা: row-এর দিক আসলে লেখার দিক মেনে চলে — আরবি বা উর্দুর মতো ডান থেকে বাঁয়ে লেখা পাতায় (dir="rtl") একইrowডান থেকে শুরু হয়, CSS না বদলেই।
flex-direction বদলালে অক্ষ ঘোরে, নিয়ম নয়Flexbox “left/right/top/bottom” দিয়ে ভাবে না, ভাবে start আর end দিয়ে — main axis-এর শুরু আর শেষ, cross axis-এর শুরু আর শেষ। এজন্যই flex-start, flex-end নামগুলো। এই চিন্তাই পর্ব ৩৫-এর logical property-এর ভিত্তি, আর এর ফলেই একই CSS বাংলা আর আরবি দুই পাতাতেই ঠিকঠাক চলে।
৪ · Main axis-এ সাজানো — justify-content আর gap
item-রা নিজেদের মাপমতো জায়গা নেওয়ার পর container-এ যে জায়গা বাকি থাকে, তার নাম free space (ফাঁকা জায়গা)। justify-content ঠিক করে এই ফাঁকা জায়গা main axis বরাবর কোথায় যাবে — সব এক পাশে, দুই পাশে সমান, না item-দের মাঝে ভাগ করে।
| মান | ছবিতে (· = ফাঁকা) | কোথায় কাজে লাগে |
|---|---|---|
flex-start (ডিফল্টের মতো) | [১][২][৩]······ | সাধারণ সারি |
flex-end | ······[১][২][৩] | ডানে জড়ো করা বোতাম |
center | ···[১][২][৩]··· | মাঝখানে বসানো |
space-between | [১]···[২]···[৩] | দুই কিনারায় দুই প্রান্ত |
space-around | ·[১]··[২]··[৩]· | প্রতিটির দুই পাশে সমান — কিনারায় অর্ধেক |
space-evenly | ··[১]··[২]··[৩]·· | কিনারা সহ সব ফাঁক সমান |
এবার এই পর্বের খেলার মাঠ। নিচে পাঁচটি রঙিন বাক্সের একটি তাক — বাক্সের রং আর মাপ আলাদা রাখা আছে, এডিটরে শুধু তাকের Flexbox-এর property. মন্তব্যে (/* */) প্রতিটি property-র অন্য মানগুলো লেখা আছে — একটি একটি করে বদলে দেখুন।
/* খেলার মাঠ: মান বদলান, প্রিভিউ নিজে বদলাবে */
.shelf {
display: flex;
flex-direction: row;
/* row-reverse | column | column-reverse */
justify-content: flex-start;
/* flex-end | center | space-between |
space-around | space-evenly */
align-items: stretch;
/* flex-start | center | flex-end | baseline */
gap: 8px;
/* 0 | 24px | 1rem */
}শুরুতে পাঁচটি বাক্স বাঁয়ে জড়ো, মাঝে 8px ফাঁক, ডানে বাকি সব ফাঁকা জায়গা। ২ নম্বর বাক্সের লেখা বড়, তবু সব বাক্স সমান উঁচু — সবাই তাকের পুরো উচ্চতা (min-height: 90px) জুড়ে টানটান, কারণ align-items: stretch. চেষ্টা করুন: justify-content-কে space-between করুন — ১ বাঁ কিনারায়, ৫ ডান কিনারায়, বাকিরা মাঝে সমান দূরে। তারপর align-items: center দিন — বাক্সগুলো আর টানটান নয়, উচ্চতার মাঝখানে বসেছে, আর এবার বড় লেখার ২ নম্বরটি বাকিদের চেয়ে উঁচু। সবশেষে flex-direction: column আর তাকে height: 360px; যোগ করে আবার justify-content বদলে দেখুন — এবার ফাঁকা জায়গা ওপর-নিচে ভাগ হচ্ছে।
gap — ফাঁকের সঠিক যন্ত্র
gap শুধু item-দের মাঝে ফাঁক দেয়, প্রথমটির আগে বা শেষটির পরে নয়। Flexbox-এ gap আসার আগে সবাই প্রতিটি item-এ margin-right দিত, তারপর শেষটির জন্য :last-child { margin-right: 0 } লিখে বাড়তি ফাঁক মুছত; সারি ভেঙে নতুন লাইনে গেলে সেই হিসাবও গোলমেলে হতো। এখন এক লাইনেই কাজ: gap: 16px দুই দিকেই, বা gap: 12px 24px দিলে প্রথমটি সারির মাঝে (row-gap), দ্বিতীয়টি কলামের মাঝে (column-gap). একটি জিনিস মনে রাখুন: gap হলো সর্বনিম্ন ফাঁক; space-between বাড়তি জায়গা থাকলে তার ওপর আরও ফাঁক যোগ করে।
৫ · Cross axis-এ সাজানো — align-items, align-self আর মাঝখানে বসানো
align-items ঠিক করে প্রতিটি item তার লাইনের ভেতরে cross axis বরাবর কোথায় বসবে। ডিফল্ট আচরণ stretch — item-এর cross দিকের মাপ (row-এ উচ্চতা) ঠিক করে দেওয়া না থাকলে সে লাইনের পুরো উচ্চতা জুড়ে টানটান হয়। পুরোনো দিনের “সব কলাম সমান উঁচু” সমস্যার সমাধান তাই একেবারে বিনা খরচে। আর কোনো একটি item দলছুট হতে চাইলে নিজের ওপর align-self লেখে — সেটি শুধু তার জন্য align-items-কে বাতিল করে।
.row {
display: flex;
gap: 8px;
height: 170px;
border: 2px dashed #64748b;
align-items: stretch;
/* flex-start | center | flex-end | baseline */
}
.row > div {
background: #bae6fd;
border: 1px solid #0369a1;
padding: 8px;
}
.d { font-size: 30px; }
.c { align-self: flex-end; } /* শুধু ডালপুরি দলছুট */চা, সিঙ্গারার তালিকা আর জিলাপি — তিনটিই 170px-এর পুরো উচ্চতা জুড়ে টানটান; শুধু ডালপুরি নিজের align-self: flex-end মেনে নিচে নেমে বসেছে, আর তার উচ্চতা শুধু লেখার সমান। চেষ্টা করুন: align-items-কে center করুন — সব বাক্স নিজের লেখার সমান উঁচু হয়ে মাঝখানে বসল। তারপর baseline দিন — এবার বাক্সগুলো এমনভাবে বসল যে প্রথম লাইনের লেখাগুলো একই সরলরেখায়, বড় অক্ষরের “জিলাপি” সহ (ডালপুরি বাদে — সে এখনো নিজের align-self মানছে); দামের ট্যাগ আর লেবেল পাশাপাশি রাখলে এটি খুব কাজের। শেষে .c-এর লাইনটি মুছে দিন — ডালপুরি আবার দলে ফিরল।
সেই বিখ্যাত প্রশ্নের উত্তর — “মাঝখানে বসাবো কীভাবে?”
এখন দুই অক্ষ জানেন, তাই উত্তর দুই লাইনে: main axis-এ justify-content: center, cross axis-এ align-items: center. লেখা এক লাইন হোক বা দশ লাইন, বাক্স ছোট হোক বা বড় — কোনো সংখ্যা হিসাব করতে হয় না।
.parent {
display: flex;
justify-content: center; /* main axis: আনুভূমিক মাঝখান */
align-items: center; /* cross axis: উল্লম্ব মাঝখান */
min-height: 300px; /* উচ্চতা না থাকলে উল্লম্ব মাঝখানের অর্থ নেই */
}শেষ লাইনটি খেয়াল করুন। নতুনরা প্রায়ই অভিযোগ করেন “align-items: center কাজ করছে না!” — কারণ container-এর উচ্চতা তার লেখার সমান, তাই উল্লম্ব দিকে কোনো ফাঁকা জায়গাই নেই, মাঝখানে আনার প্রশ্নই ওঠে না। DevTools-এ container-এর মাপ দেখলেই ধরা পড়ে। একই কাজ margin: auto দিয়েও হয় (অংশ ৮), আর Grid-এ এক লাইনের place-items: center দিয়ে (পর্ব ২৭)। বাস্তব পাতায় লগইন বক্স, “লোড হচ্ছে” চিহ্ন বা খালি তালিকার বার্তায় এগুলো কীভাবে লাগে, সেটি পর্ব ২৬-এর বিষয়।
৬ · flex-wrap আর align-content — এক লাইনে না ধরলে
ডিফল্টে Flexbox সব item-কে এক লাইনেই রাখার চেষ্টা করে (flex-wrap: nowrap) — দরকার হলে item-দের চেপে ছোট করে, তাতেও না ধরলে container ছাপিয়ে বাইরে বের করে দেয়। flex-wrap: wrap দিলে জায়গা না ধরলে item-রা নতুন লাইনে চলে যায়, ঠিক যেমন লেখার শব্দ লাইনের শেষে পৌঁছে পরের লাইনে যায়। প্রতিটি লাইনকে বলে flex line, আর প্রতিটি লাইন নিজে একটি ছোট্ট আলাদা Flexbox — justify-content প্রতিটি লাইনের ভেতরে আলাদাভাবে কাজ করে।
লাইন একাধিক হলে নতুন একটি প্রশ্ন আসে: লাইনগুলো নিজেরা container-এর cross axis বরাবর কীভাবে সাজবে? এর উত্তর align-content. পার্থক্যটা মনে রাখুন — align-items সাজায় লাইনের ভেতরে item, align-content সাজায় container-এর ভেতরে লাইন।
.shelf {
display: flex;
flex-wrap: nowrap; /* wrap | wrap-reverse */
align-content: normal;
/* flex-start | center | space-between | flex-end */
gap: 8px;
width: 280px;
height: 220px;
border: 2px dashed #64748b;
}
.box { width: 70px; }সাতটি বাক্সের প্রতিটির width 70px (সাথে দুই পাশে 8px padding), আর মাঝে ফাঁক — মোট লাগে 600px-এর বেশি, অথচ তাক মাত্র 280px. nowrap-এ Flexbox তাদের চেপে এক লাইনে ধরিয়েছে (প্রতিটি প্রায় 33px), আর সবাই 220px-এর পুরো উচ্চতা জুড়ে লম্বা। চেষ্টা করুন: flex-wrap: wrap দিন — এক লাইনে তিনটি করে ধরল, তিনটি লাইন হলো, আর লাইনগুলো ফাঁকা উচ্চতা ভাগ করে নিয়ে টানটান হয়েছে (normal এখানে stretch-এর মতো আচরণ করে)। এবার align-content: flex-start দিন — লাইনগুলো ওপরে জড়ো হলো, নিচে ফাঁকা। space-between দিলে প্রথম লাইন ওপরে, শেষটি নিচে। আর flex-wrap আবার nowrap করে align-content বদলে দেখুন — কিছুই বদলাবে না, কারণ লাইন একটিই।
align-content কখন কাজ করে না: container nowrap হলে (single-line), অথবা cross axis-এ কোনো বাড়তি জায়গা না থাকলে (যেমন container-এর উচ্চতা লেখার সমান)। তবে flex-wrap: wrap দেওয়া থাকলে লাইন বাস্তবে একটি হলেও container-কে multi-line ধরা হয়, তখন align-content সেই একটি লাইনকেও সরাতে পারে। আর flex-direction আর flex-wrap একসাথে লেখার shorthand flex-flow: row wrap.
৭ · item-এর মাপ — flex-grow, flex-shrink আর flex-basis
এতক্ষণ item-রা নিজের মাপেই ছিল, আমরা শুধু ফাঁকা জায়গা সরিয়েছি। Flexbox-এর আসল শক্তি হলো item-দের নমনীয় মাপ — বাড়তি জায়গা থাকলে item বড় হতে পারে, কম পড়লে ছোট হতে পারে। প্রতিটি item-এর জন্য ব্রাউজার তিনটি প্রশ্ন করে:
- শুরুর মাপ কত? —
flex-basis. ডিফল্টauto: item-এ main দিকেরwidth(column-এheight) দেওয়া থাকলে সেটি, না থাকলে ভেতরের লেখার মাপ।flex-basis-এ নির্দিষ্ট মান দিলে main axis-এ সেটিwidth-কে হারিয়ে দেয়। - জায়গা বাড়তি থাকলে কতটা নেবে? —
flex-grow, একটি অনুপাত। ডিফল্ট 0, অর্থাৎ বাড়বে না। - জায়গা কম পড়লে কতটা ছাড়বে? —
flex-shrink, এটিও অনুপাত। ডিফল্ট 1, অর্থাৎ দরকারে ছোট হবে।
ধরুন একটি বিয়ের দাওয়াতে এক টেবিলে তিন পরিবার বসবে। প্রত্যেক পরিবার আগে নিজের ন্যূনতম চেয়ার নিল (basis). টেবিলে বাড়তি জায়গা থাকলে সেটা ভাগ হবে পরিবারের “ভাগের অংশ” অনুযায়ী — যার ২ ভাগ, সে পাবে যার ১ ভাগ তার দ্বিগুণ (grow). আর জায়গা কম পড়লে সবাইকে চেপে বসতে হবে, তবে বড় পরিবার একটু বেশি চাপবে, কারণ তার কাছে ছাড়ার মতো জায়গাও বেশি (shrink × basis).
এবার সংখ্যা ধরে পুরো হিসাবটি দেখুন। প্রথম চার ধাপে বাড়তি জায়গা ভাগ, পরের তিন ধাপে জায়গা কম পড়ার হিসাব:
| a | |
| b | |
| c | |
| free space |
- শুরুর মাপ — basis. 600px চওড়া তাকে তিনটি item: a, b, c — basis যথাক্রমে 100, 150 আর 50px. সবার grow এখনো 0, তাই কেউ বাড়বে না। তিনজনে মিলে নিয়েছে 300px.
- free space বের করা। container 600 − basis-এর যোগফল 300 = +300px বাড়তি। ধনাত্মক মানে জায়গা বেশি, তাই প্রশ্ন এখন flex-grow-এর। grow 0 থাকায় এই 300px ডানে ফাঁকা পড়ে আছে —
justify-contentএটাই সরায়। - grow-এর অনুপাতে ভাগ। এবার a-কে grow 1, b-কে grow 2 দেওয়া হলো, c 0-ই থাকল। মোট ভাগ 1 + 2 + 0 = 3, তাই এক ভাগ = 300 ÷ 3 = 100px. a পাবে ১ ভাগ (100), b পাবে ২ ভাগ (200), c কিছুই না। খেয়াল করুন: grow 2 মানে “দ্বিগুণ চওড়া” নয় — “বাড়তি জায়গার দ্বিগুণ অংশ”।
- চূড়ান্ত মাপ। a = 100 + 100 = 200, b = 150 + 200 = 350, c = 50. যোগফল ঠিক 600 — তাক ভরে গেছে, free space শূন্য। b-এর চওড়া a-এর দ্বিগুণের চেয়ে কম, কারণ basis আলাদা ছিল।
- এবার ঘাটতি। নতুন অবস্থা: তাক মাত্র 300px (ধরুন ফোনের পর্দা), basis 200, 200 আর 100 — যোগফল 500. free space = 300 − 500 = −200px. ঋণাত্মক মানে জায়গা কম; এখন কাজ flex-shrink-এর। সবার shrink ডিফল্ট 1.
- shrink-এর ভাগ basis-এর ওজনে। shrink সমান হলেও কাটা সমান নয়: প্রতিটির ওজন = shrink × basis = 200, 200, 100 (মোট 500). a থেকে কাটা যাবে 200 × 200/500 = 80, b থেকে 80, c থেকে 40. ফল 120, 120, 60 — যোগফল 300 ✓. বড় item বেশি ছাড়ে, যাতে ছোট item একেবারে চ্যাপ্টা না হয়ে যায়।
- flex-shrink: 0 — “আমাকে ছোঁবেন না”। c-কে shrink 0 দিলে সে 100px-এ অনড়। পুরো 200px ঘাটতি এবার a আর b-এর মধ্যে (ওজন 200 : 200) — প্রত্যেকে 100 করে ছাড়ল, তিনজনই 100px. লোগো, আইকন বা ছবির মতো যেসব জিনিস চেপে যাওয়া চলবে না, তাদের জন্য
flex-shrink: 0খুব পরিচিত লাইন।
+ হলে grow-এর অনুপাতে যোগ · − হলে (shrink × basis)-এর অনুপাতে বিয়োগ
flex shorthand — তিনটি এক লাইনে
বাস্তবে তিনটি property আলাদা করে প্রায় কেউ লেখেন না; লেখেন flex — ক্রম grow, shrink, basis. কিন্তু এর কয়েকটি এক-শব্দের রূপের অর্থ আলাদা করে মুখস্থ রাখার মতো, কারণ সেগুলোতে basis-এর মান লুকিয়ে বদলে যায়:
| লিখলেন | আসলে (grow shrink basis) | আচরণ |
|---|---|---|
flex: initial (কিছু না লিখলে) | 0 1 auto | নিজের মাপে থাকে, বাড়ে না; জায়গা কম পড়লে ছোট হয় |
flex: auto | 1 1 auto | লেখার মাপ থেকে শুরু, তারপর বাড়তি জায়গা সমান ভাগে — বড় লেখার item বড়ই থাকে |
flex: none | 0 0 auto | একদম অনড় — বাড়েও না, কমেও না |
flex: 1 | 1 1 0% | basis শূন্য, তাই পুরো জায়গা সমান ভাগ — লেখা যা-ই হোক, সবাই সমান চওড়া |
flex: 2 | 2 1 0% | flex: 1-এর পাশে থাকলে দ্বিগুণ চওড়া (padding-border না থাকলে হুবহু) |
flex: 200px | 1 1 200px | 200px থেকে শুরু, দুই দিকেই নমনীয় |
সবচেয়ে বেশি গোলমাল হয় flex: 1 আর flex: auto-তে। নাম কাছাকাছি, কিন্তু basis ভিন্ন। flex: auto-তে বাড়তি জায়গা ভাগ হয় লেখার মাপের পরে যা বাঁচে তা থেকে, তাই লম্বা লেখার item চওড়াই থাকে। flex: 1-এ basis 0, অর্থাৎ পুরো container-টাই “বাড়তি জায়গা” — সমান grow পেলে সবাই হুবহু সমান। নিজের চোখে দেখুন — দুই সারিতে একই তিনটি লেখা, শুধু flex-এর মান আলাদা:
.row {
display: flex;
gap: 6px;
width: 420px;
margin-bottom: 12px;
}
.row > div {
background: #fde68a;
border: 1px solid #b45309;
padding: 8px;
}
.one > div { flex: 1; } /* = 1 1 0% */
.auto > div { flex: auto; } /* = 1 1 auto */ওপরের সারিতে তিনটি বাক্স হুবহু সমান চওড়া — “চা”-এর মতো ছোট লেখাও বাকিদের সমান জায়গা পেয়েছে। নিচের সারিতে “সিঙ্গারা আর সমুচা” স্পষ্টতই সবচেয়ে চওড়া, কারণ লেখার মাপ নিয়ে শুরু করে তারপর সবাই সমান বাড়তি পেয়েছে। চেষ্টা করুন: .one-এর দ্বিতীয় বাক্সকে আলাদা করে flex: 2 দিতে লিখুন .one > div:nth-child(2) { flex: 2; } — সে বাকিদের প্রায় দ্বিগুণ (padding আর border বাদে ভেতরের অংশ হুবহু দ্বিগুণ, কারণ basis 0 থেকে শুধু content-এর মাপ ভাগ হয়)। তারপর .auto-কে flex: none করুন — বাক্সগুলো আর বাড়ছে না, ডানে ফাঁকা পড়ে থাকল।
চোখের আন্দাজ নয়, সংখ্যা চাইলে ব্রাউজারকেই জিজ্ঞেস করুন। নিচের ছোট JavaScript একই দুই সারির প্রতিটি বাক্সের আসল চওড়া মেপে লিখে দেয়:
// প্রতিটি সারির বাক্সগুলোর চওড়া মেপে দেখাই
function measureRows() {
document.querySelectorAll('.row').forEach(function (row) {
const widths = Array.from(row.children).map(function (box) {
return Math.round(box.getBoundingClientRect().width);
});
console.log(getComputedStyle(row.children[0]).flex, '→', widths.join(' + '), 'px');
});
}
// ফ্রেমের layout শেষ হওয়া পর্যন্ত অপেক্ষা, তারপর মাপা
(function wait() {
document.body.offsetWidth ? measureRows() : setTimeout(wait, 50);
})();প্রথম লাইনে আসবে 1 1 0% আর তিনটি সমান সংখ্যা (420 থেকে দুটি 6px ফাঁক বাদ দিয়ে তিন ভাগ, প্রতিটি প্রায় 136px). দ্বিতীয় লাইনে 1 1 auto আর তিনটি আলাদা সংখ্যা — মাঝেরটি সবচেয়ে বড়। খেয়াল করুন, ব্রাউজার নিজেই বলছে flex: 1-এর basis হলো 0%. চেষ্টা করুন: CSS অংশে .row-এর width 420px থেকে 300px করে আবার চালান — সংখ্যাগুলো কীভাবে বদলায়, হাতে হিসাব করে মিলিয়ে দেখুন। (এখানে মাপা হচ্ছে border box — padding সহ — তাই সংখ্যার যোগফল 420 − 12 = 408.)
আরও গভীরে: spec-এর আসল অ্যালগরিদমের নাম “Resolving Flexible Lengths”, আর এটি এক ধাপে শেষ হয় না — একটি লুপ। ব্রাউজার প্রথমে উপরের মতো অনুপাতে ভাগ করে; তারপর দেখে কোনো item তার min-width বা max-width-এর সীমা ভেঙেছে কি না। ভাঙলে তাকে সীমায় আটকে “জমিয়ে” (freeze) দেয়, আর বাকি item-দের মধ্যে ঘাটতি বা বাড়তি নতুন করে ভাগ করে — যতক্ষণ না সবাই স্থির হয়। আরেকটি কম জানা নিয়ম: সব item-এর grow-এর যোগফল 1-এর কম হলে পুরো free space ভাগ হয় না — একটিমাত্র item-এ flex-grow: 0.5 দিলে সে বাড়তি জায়গার ঠিক অর্ধেক নেয়, বাকি অর্ধেক ফাঁকা থাকে। আর flex-basis-এ শতাংশ দিলে তা হিসাব হয় container-এর main দিকের মাপ থেকে; সেই মাপ জানা না থাকলে (যেমন উচ্চতা ঠিক না করা column-এ) ব্রাউজার শতাংশটিকে content ধরে নেয়।
৮ · একটি ফাঁদ আর একটি কৌশল — min-width: auto আর margin: auto
ফাঁদ: লম্বা লেখা item ছাপিয়ে বেরিয়ে যায়
অংশ ৭-এ দেখলেন জায়গা কম পড়লে item ছোট হয়। কিন্তু কতটা ছোট? Flexbox-এর একটি সুরক্ষা-নিয়ম আছে: item-এর min-width-এর ডিফল্ট মান auto, আর flex item-এর ক্ষেত্রে এর অর্থ “ভেতরের লেখার সবচেয়ে ছোট সম্ভাব্য মাপের নিচে নামবে না”। এই মাপকে বলে min-content — সাধারণত সবচেয়ে লম্বা শব্দের চওড়া। নিয়মটির নাম automatic minimum size. উদ্দেশ্য ভালো: লেখা যাতে চেপে একে অপরের ওপর না পড়ে। কিন্তু একটি লম্বা URL, ফাইলের নাম, বা এক লাইনে আটকানো (white-space: nowrap) লেখা থাকলে min-content বিশাল হয়ে যায় — item আর ছোট হয় না, container ছাপিয়ে বেরিয়ে যায়, আর ফোনে পুরো পাতা পাশে স্ক্রল করে।
.card {
display: flex;
gap: 10px;
width: 260px;
padding: 10px;
border: 2px solid #0369a1;
}
.icon { flex: none; font-size: 28px; }
.text {
/* min-width: 0; */
}
.text p { margin: 0; }
.name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /* লম্বা হলে … দেখাও */
}নীল কার্ডটি 260px, কিন্তু ফাইলের নাম কার্ডের ডান দাগ পেরিয়ে বাইরে চলে গেছে, আর “…” (text-overflow) দেখাই যাচ্ছে না। কারণ .text item-টি তার min-content — পুরো এক লাইনের নাম — এর নিচে ছোট হতে রাজি নয়, তাই .name-এর overflow: hidden কাটার মতো কিছুই পাচ্ছে না। চেষ্টা করুন: .text-এর ভেতরের min-width: 0; লাইনের মন্তব্য চিহ্ন (/* */) মুছে দিন — item এবার কার্ডের মাপে ছোট হলো, আর নামের শেষে “…” এলো। তারপর min-width: 0-এর বদলে overflow: hidden; লিখে দেখুন — এটিও কাজ করে, কারণ যে item নিজে overflow কাটে, তার automatic minimum শূন্য ধরা হয়।
মনে রাখার নিয়ম: flex item-এর ভেতরের লেখা বা ছবি অকারণে বাইরে বেরোলে আগে item-এ min-width: 0 দিয়ে দেখুন (column-এ min-height: 0). flex-এর ভেতরে flex থাকলে প্রতিটি স্তরের item-এ লাগতে পারে। আর শুধু ছোট করাই যথেষ্ট না হলে লেখা ভাঙতে overflow-wrap: anywhere (পর্ব ২১) যোগ করুন — বাংলা লেখায় লম্বা ইংরেজি URL বা ইমেইল প্রায়ই এই সমস্যা তৈরি করে।
কৌশল: margin: auto সব বাড়তি জায়গা খেয়ে ফেলে
পর্ব ১৯-এ দেখেছেন block-এ বাঁ-ডানের auto margin বাক্সকে আনুভূমিকভাবে মাঝখানে আনে। Flexbox-এ auto margin আরও শক্তিশালী: ব্রাউজার item-দের মাপ ঠিক করার পর যে free space বাঁচে, সেটি justify-content-এর আগেই auto margin-গুলোকে দিয়ে দেয়। ফলে কোনো item-এ margin-left: auto দিলে তার বাঁ পাশের সব বাড়তি জায়গা সে নিজে নেয় — সে আর তার পরের সবাই ডানে ঠেলে যায়। আর চার দিকেই auto দিলে, দুই অক্ষেই মাঝখানে।
.bar {
display: flex;
gap: 8px;
padding: 8px;
background: #e2e8f0;
}
.push { margin-left: auto; }
.stage {
display: flex;
height: 140px;
margin-top: 12px;
border: 2px dashed #64748b;
}
.dot { margin: auto; }ওপরের ধূসর সারিতে লোগো, হোম, দোকান বাঁয়ে, আর “লগইন” একা ডান কিনারায় — তার বাঁ পাশের auto margin মাঝের সব ফাঁকা জায়গা নিয়ে নিয়েছে। নিচের ড্যাশ দাগের বাক্সে বেগুনি “মাঝখানে” দুই অক্ষেই ঠিক মাঝে, কোনো justify-content বা align-items ছাড়াই। চেষ্টা করুন: CSS-এ .push-এর জায়গায় .b2 লিখুন — এবার দুটি সবুজ বাক্স (হোম আর দোকান) দুজনেই বাঁ পাশে auto margin পেল, তাই বাড়তি জায়গা দুই ভাগ হয়ে দুটি ফাঁকে বসল। তারপর margin-left-এর বদলে margin-inline-start লিখুন — ফল একই, কিন্তু ডান থেকে বাঁয়ে লেখা পাতাতেও এবার ঠিক কাজ করবে। পুরো navbar বানানো পর্ব ২৬-এ।
৯ · order আর অ্যাক্সেসিবিলিটি — চোখের ক্রম বনাম HTML-এর ক্রম
order property দিয়ে HTML না বদলেই item-দের চোখে দেখার ক্রম বদলানো যায়। সবার ডিফল্ট order: 0; ছোট সংখ্যা আগে বসে, সমান হলে HTML-এর ক্রম। ঋণাত্মক সংখ্যাও চলে — order: -1 দিলে item সবার আগে। শুনতে সুবিধাজনক, কিন্তু এখানে একটি বড় ফাঁদ আছে, যা ধাপে ধাপে দেখা দরকার:
- HTML-এর ক্রম। একটি পেমেন্ট ফর্মের চারটি অংশ: নাম, মোবাইল, পিন, আর “জমা দিন” বোতাম। HTML-এ যে ক্রমে লেখা, চোখেও সেই ক্রম। এই ক্রমকে বলে DOM order — ব্রাউজারের ভেতরের গাছে element-রা যে ক্রমে আছে।
- order: -1 দিয়ে বোতাম আগে আনা হলো। কেউ নকশার খাতিরে বোতামটি বাঁয়ে আনতে চাইলেন। চোখে এখন “জমা দিন” প্রথমে। কিন্তু HTML-এ একটি অক্ষরও বদলায়নি — বোতাম এখনো DOM-এর শেষে।
- Tab চাপলে কী হয়। কীবোর্ড ব্যবহারকারী Tab চাপলেন। focus যায় tab order মেনে, আর tab order আসে DOM থেকে: নাম → মোবাইল → পিন → তারপর হঠাৎ লাফ দিয়ে বাঁ কোণের বোতামে। চোখ যা বলছে, focus তার উল্টো পথে ঘুরছে — দৃষ্টিশক্তি থাকা কীবোর্ড ব্যবহারকারীর জন্য এটা খুবই বিভ্রান্তিকর।
- screen reader কী শোনায়। দৃষ্টিপ্রতিবন্ধী ব্যবহারকারীর screen reader পড়ে DOM-এর ক্রমে — তিনি শুনবেন বোতাম সবার শেষে, যা আসলে ঠিকই আছে। কিন্তু পাশে বসা কেউ যদি বলেন “বাঁয়ের প্রথম বোতাম চাপুন”, দুজনের পাতা দুই রকম। লেখা মাউস দিয়ে বাছাই করে কপি করলেও DOM-এর ক্রমেই কপি হয়।
- সমাধান: ক্রম বদলাতে হলে HTML বদলান। যে ক্রমে মানুষ পড়বে ও ব্যবহার করবে, HTML-এ সেই ক্রমেই লিখুন।
order,row-reverseআরcolumn-reverseশুধু তখন ব্যবহার করুন, যখন চোখের ক্রম বদলালেও অর্থ বা ব্যবহারের ক্রম বদলায় না — যেমন একটি সাজসজ্জার ছবিকে লেখার আগে বা পরে দেখানো। WCAG 2.2-এর 1.3.2 (Meaningful Sequence) আর 2.4.3 (Focus Order) ঠিক এই সমস্যার কথাই বলে।
শুধু পড়ে নয়, নিজে অনুভব করুন। নিচের প্রিভিউর ভেতরে একবার ক্লিক করে বারবার Tab চাপুন, আর হলুদ দাগটি কোন পথে ঘোরে দেখুন:
<style>
.menu { display: flex; gap: 8px; }
.menu button { padding: 8px 12px; font-size: 15px; }
.menu button:focus-visible { outline: 3px solid #f59e0b; }
.last { order: -1; }
</style>
<p>এখানে ক্লিক করে Tab চাপুন:</p>
<div class="menu">
<button>১ · হোম</button>
<button>২ · পণ্য</button>
<button>৩ · অফার</button>
<button class="last">৪ · যোগাযোগ</button>
</div>চোখে প্রথম বোতাম “৪ · যোগাযোগ”, কিন্তু প্রথম Tab-এ হলুদ দাগ যায় “১ · হোম”-এ, তারপর ২, ৩ — আর শেষে লাফ দিয়ে বাঁ কোণের “৪”-এ। চেষ্টা করুন: .last { order: -1; } লাইনটি মুছে .menu-তে flex-direction: row-reverse; যোগ করুন — চোখে ক্রম পুরো উল্টো, কিন্তু Tab এখনো ১ → ২ → ৩ → ৪, অর্থাৎ এবার ডান থেকে বাঁয়ে। দুটি অভিজ্ঞতাই কীবোর্ড ব্যবহারকারীর কাছে বিভ্রান্তিকর।
চোখের ক্রম মেনে focus ঘোরানোর জন্য CSS-এ reading-flow নামে একটি নতুন property প্রস্তাব করা হয়েছে, আর সম্প্রতি Chrome-এ এসেছে। কিন্তু এটি এখনো Baseline নয় — অন্য ব্রাউজারে কাজ করে না। তাই আজকের নিরাপদ নিয়ম একটিই: অর্থবহ ক্রম HTML-এই ঠিক রাখুন।
DevTools-এর flex overlay — Flexbox চোখে দেখুন
Flexbox-এ কিছু অদ্ভুত লাগলে অনুমান না করে DevTools খুলুন। Chrome বা Edge-এ Elements প্যানেলে flex container-এর পাশে ছোট একটি “flex” ব্যাজ দেখা যায়। সেটিতে ক্লিক করলে পাতার ওপর একটি রঙিন flex overlay আঁকা হয় — প্রতিটি item-এর সীমানা, gap-এর ডোরাকাটা জায়গা আর বাকি free space আলাদা করে দেখা যায়। Styles অংশে display: flex-এর পাশের ছোট আইকনে ক্লিক করলে একটি flexbox editor খোলে, যেখানে justify-content বা align-items-এর মান বোতাম চেপে বদলে তখনই ফল দেখা যায়। Firefox-এর Layout প্যানেলের Flexbox অংশ আরও এক ধাপ এগিয়ে — কোনো item বেছে নিলে দেখায় তার basis কত ছিল, সে কতটা বেড়েছে বা কমেছে, আর কোনো min/max সীমায় আটকেছে কি না; অংশ ৭-এর পুরো অঙ্কটাই সেখানে লেখা থাকে।
পরীক্ষা ও ইন্টারভিউতে — বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে:
- main axis আর cross axis কী? — item যে দিকে পরপর বসে সেটি main axis (
flex-directionঠিক করে), তার সমকোণে cross axis;justify-contentmain-এ,align-itemscross-এ কাজ করে। - একটি div দুই দিকেই মাঝখানে আনবেন কীভাবে? — parent-এ
display: flex; justify-content: center; align-items: center;(আর parent-এর উচ্চতা), অথবা child-এmargin: auto. flex: 1আরflex: auto-এর পার্থক্য? —flex: 1=1 1 0%, পুরো জায়গা সমান ভাগ;flex: auto=1 1 auto, লেখার মাপের পরে বাঁচা জায়গা ভাগ।- align-items আর align-content-এর পার্থক্য? — align-items লাইনের ভেতরে item সাজায়; align-content multi-line (wrap) container-এ লাইনগুলোকে সাজায়।
- Flexbox না Grid? — এক দিকে (সারি বা কলাম) জিনিস সাজাতে, বিশেষত item-এর মাপ যখন লেখা ঠিক করে — Flexbox; সারি আর কলাম একসাথে মেলাতে — Grid (পর্ব ২৭)।
১০ · AI-এর যুগে — Flexbox-এর কাজ AI-কে দিলে কী দেখবেন
“একটা ঝকঝকে হেডার বানিয়ে দাও” বললে AI প্রায় সবসময় Flexbox-ই দেয়, আর বড় পর্দায় তা ঠিকঠাক দেখায়ও। সমস্যা লুকিয়ে থাকে কিনারায় — লম্বা লেখায়, ছোট পর্দায়, কীবোর্ডে। আর পুরোনো টিউটোরিয়াল থেকে শেখা বলে AI মাঝে মাঝে পুরোনো খসড়ার কোডও নিয়ে আসে।
AI সাধারণত যেসব ভুল করে
| AI-এর ভুল | আপনি যা দেখবেন | ঠিক উপায় |
|---|---|---|
display: -webkit-box, -ms-flexbox, -webkit-flex | অপ্রয়োজনীয় বাড়তি লাইন, পুরোনো খসড়ার আচরণ | শুধু display: flex |
মাঝখানে আনতে position: absolute + transform, বা float + clearfix | লেখা বাড়লে ওপরে-নিচে কেটে যায় | justify-content + align-items, বা margin: auto |
প্রতিটি item-এ margin, তারপর :last-child { margin: 0 } | wrap হলে অসমান ফাঁক | container-এ gap |
লম্বা লেখা আছে এমন item-এ min-width: 0 নেই | ফোনে পাতা পাশে স্ক্রল, “…” কাজ করে না | item-এ min-width: 0 |
নকশা মেলাতে order বা row-reverse | Tab আর screen reader-এর ক্রম চোখের সাথে মেলে না | HTML-এর ক্রমই বদলান |
সব item-এ flex: 1, অথবা width: 33.33% + flex | ছোট লেখার বোতামও অকারণে চওড়া, বা wrap-এ ভাঙা | দরকার বুঝে flex: auto / none / basis |
| কার্ডের গ্যালারির মতো সারি-কলাম দুটোই মেলানো লেআউটে Flexbox | শেষ সারির কার্ড বেমানান চওড়া | Grid (পর্ব ২৭) |
AI-কে কাজ দেওয়ার সময় Flexbox-এর শর্তগুলো আগেই লিখে দিন। শেষের অনুরোধটি খেয়াল করুন — প্রতিটি property কোন অক্ষে কাজ করছে বলতে বললে AI-এর বিভ্রান্তি (justify আর align গুলিয়ে ফেলা) নিজেই বেরিয়ে আসে।
AI-এর দেওয়া Flexbox কোড হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলোই আপনাকে CSS লেখক থেকে লেআউট-চিন্তক বানাবে।
প্র ০১Flexbox-এর spec ২০০৯ থেকে ২০১২-র মধ্যে তিনবার বদলাল কেন? এর ফলে ডেভেলপারদের কী ভুগতে হয়েছিল, আর ব্রাউজার-নির্মাতারা কী শিখলেন?
প্রথম খসড়াটি তৈরি হয়েছিল একটি বিদ্যমান ব্যবস্থাকে প্রায় হুবহু মান হিসেবে লিখে ফেলে — Mozilla তাদের Firefox-এর নিজস্ব ইন্টারফেস বানাত XUL নামের একটি ভাষায়, যার box লেআউট বহু বছর ধরে চলছিল। দ্রুত শুরু করার জন্য এটি সুবিধাজনক ছিল, কিন্তু ব্যবহার করতে গিয়ে দুর্বলতা বেরোল: একাধিক লাইনে মোড়ানো (wrap) ঠিকমতো ছিল না, মাপের হিসাব অস্পষ্ট ছিল, আর নামগুলো (box-pack, box-align) কী করে তা বোঝা কঠিন ছিল। তাই CSS Working Group ২০১১ সালে প্রায় নতুন একটি নকশা দিল, আর আরও আলোচনার পর ২০১২ সালে আবার নাম ও আচরণ বদলে আজকের চূড়ান্ত রূপে পৌঁছাল।
সমস্যা হলো, ব্রাউজাররা তখন নতুন ফিচার পরীক্ষামূলকভাবে চালু করত vendor prefix দিয়ে — -webkit-, -moz-, -ms-. ডেভেলপাররা সেগুলো আসল সাইটে ব্যবহার করে ফেলতেন। ফলে একসময় একটি সাধারণ সারি বানাতেও লিখতে হতো display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; — তিনটি আলাদা খসড়ার তিন রকম ভাষা, আর প্রতিটির আচরণেও সূক্ষ্ম পার্থক্য। Autoprefixer-এর মতো টুল (পর্ব ৫০-এর PostCSS) এই বোঝা কমাতে জনপ্রিয় হয়। আরও খারাপ, কোটি কোটি পাতা পুরোনো prefix-এর ওপর দাঁড়িয়ে যাওয়ায় ব্রাউজাররা সেগুলো সহজে বাদও দিতে পারেনি — আজও অনেক ব্রাউজার -webkit-box বোঝে।
এই অভিজ্ঞতা (আর একই সময়ের অন্য ফিচারের অনুরূপ ঝামেলা) থেকে ব্রাউজার-নির্মাতারা নীতি বদলান। এখন নতুন ফিচার সাধারণত prefix ছাড়াই, কিন্তু একটি “flag”-এর পেছনে বা সীমিত পরীক্ষায় চালু হয় — ডেভেলপাররা পরীক্ষা করতে পারেন, কিন্তু সাধারণ ব্যবহারকারীর পাতায় ভুল করে চালু হয়ে যায় না। spec স্থির হলে তবেই সবার জন্য খোলা হয়। Baseline লেবেলও এই শিক্ষারই ফল — কোন ফিচার কখন নিরাপদ, এক নজরে বোঝানো।
মূল উপলব্ধি: মানদণ্ড তৈরি একটি পুনরাবৃত্তিমূলক প্রক্রিয়া — প্রথম চেষ্টা প্রায়ই ভুল হয়। কিন্তু ওয়েবে একবার কিছু ছড়িয়ে পড়লে তা ফেরানো প্রায় অসম্ভব। তাই পরীক্ষামূলক জিনিস আলাদা রাখা, আর স্থির হওয়ার পর ব্যবহার করা — ডেভেলপার আর ব্রাউজার দুই পক্ষের জন্যই সবচেয়ে নিরাপদ পথ।
প্র ০২“Flexbox এক দিকের, Grid দুই দিকের” — এ কথার আসল মানে কী? Flexbox-এ তো flex-wrap দিয়ে কয়েক সারিও বানানো যায়!
ঠিকই, flex-wrap: wrap দিলে Flexbox-এও কয়েকটি সারি দেখা যায়। কিন্তু “এক দিক” কথাটা সারির সংখ্যা নিয়ে নয় — হিসাব কোন দিকে হয় তা নিয়ে। wrap করা Flexbox-এ প্রতিটি লাইন একটি স্বাধীন সারি। প্রথম লাইনের item-রা নিজেদের মধ্যে free space ভাগ করে; দ্বিতীয় লাইন জানেই না প্রথম লাইনে কী হয়েছে। তাই ওপরের সারির দ্বিতীয় কার্ড আর নিচের সারির দ্বিতীয় কার্ড একই খাড়া রেখায় পড়বে, তার কোনো নিশ্চয়তা নেই। শেষ লাইনে যদি একটি কার্ড থাকে আর তার flex-grow: 1 থাকে, সে একাই পুরো লাইন জুড়ে বিশাল হয়ে যায় — অনলাইন দোকানের পণ্যের গ্যালারিতে এই দৃশ্য খুব পরিচিত।
Grid উল্টো দিক থেকে ভাবে। আগে সারি আর কলামের একটি জাল (track) তৈরি হয়, তারপর item-রা সেই জালের ঘরে বসে। একটি কলামের চওড়া ঠিক হলে সেটি সব সারির জন্য একই — তাই খাড়া আর আড়াআড়ি দুই দিকেই সারিবদ্ধতা নিশ্চিত। এজন্য অনেকে পার্থক্যটা এভাবে বলেন: Flexbox “content-out” — ভেতরের জিনিস নিজের মাপ নিয়ে আসে, লেআউট সেটা মেনে নেয়; Grid “layout-in” — আগে কাঠামো, তারপর জিনিস তাতে বসে।
বাস্তবে তাই প্রশ্নটা “কোনটা ভালো” নয়, “কোন অংশের জন্য কোনটা”। বোতামের সারি, navbar, ট্যাগের তালিকা, আইকন আর লেখা পাশাপাশি, কার্ডের ভেতরের অংশগুলো ওপর-নিচে — যেখানে প্রতিটি item-এর মাপ তার লেখা ঠিক করে, সেখানে Flexbox স্বাভাবিক। পুরো পাতার কাঠামো, ড্যাশবোর্ড, সমান কলামের কার্ড গ্যালারি — যেখানে কাঠামো আগে, সেখানে Grid. একটি পাতায় দুটো একসাথে থাকাই স্বাভাবিক: Grid দিয়ে কার্ডের জাল, প্রতিটি কার্ডের ভেতরে Flexbox. Grid আসছে পর্ব ২৭-এ, আর কোন লেআউটে কোনটি — তার তুলনা পর্ব ২৯-এ।
মূল উপলব্ধি: Flexbox আর Grid প্রতিদ্বন্দ্বী নয়, সহকর্মী। প্রশ্ন করুন: “এই লেআউটে কি আমার দুই দিকেই সারিবদ্ধতা লাগবে, নাকি শুধু এক সারিতে ফাঁকা জায়গা ভাগ?” উত্তরই বলে দেবে কোন যন্ত্র।
প্র ০৩flex item-এর min-width: auto এত সমস্যা তৈরি করে — তাহলে ডিফল্ট হিসেবে 0 রাখা হলো না কেন? এই সিদ্ধান্তের পেছনের যুক্তি কী?
ভাবুন ডিফল্ট যদি min-width: 0 হতো। একটি সারিতে তিনটি item, আর জায়গা কম। flex-shrink: 1 সবাইকে চাপতে থাকবে — দরকার হলে শূন্য চওড়া পর্যন্ত। তখন লেখাগুলো item-এর বাইরে উপচে একে অপরের ওপর চড়ে বসবে: পণ্যের নামের ওপর দাম, দামের ওপর বোতামের লেখা। কিছু item একেবারে অদৃশ্যও হয়ে যেতে পারে। পাঠক বুঝতেই পারবেন না কিছু হারিয়েছে। CSS-এর নকশায় একটি পুরোনো নীতি আছে — তথ্য হারানো (data loss) এড়াও। এজন্যই overflow-এর ডিফল্ট visible, hidden নয়: লেখা বাক্স ছাপিয়ে গেলে কুৎসিত দেখাক, কিন্তু অন্তত পড়া যাক।
min-width: auto একই নীতি মানে। item-কে তার min-content-এর নিচে নামতে না দিয়ে Flexbox নিশ্চিত করে লেখা কখনো অন্য item-এর ওপর চড়বে না; খারাপ হলে পুরো সারিটি container ছাপিয়ে যাবে — যা চোখে পড়ে, DevTools-এ ধরা যায়, আর এক লাইনে সারানো যায়। অর্থাৎ ডিফল্ট আচরণ “নিরাপদ কিন্তু কখনো কখনো বিরক্তিকর”, আর ডেভেলপার জেনে-বুঝে min-width: 0 দিয়ে বলেন “আমি দায়িত্ব নিচ্ছি — এখানে ellipsis বা লাইন ভাঙা দিয়ে লেখা সামলাব”।
তবু এই নিয়ম Flexbox-এর সবচেয়ে বেশি প্রশ্ন-ওঠা আচরণগুলোর একটি। ব্রাউজারগুলো শুরুতে এটি একইভাবে প্রয়োগও করত না, তাই ডেভেলপার Philip Walton-এর শুরু করা জনপ্রিয় “Flexbugs” তালিকায় ব্রাউজারের ভিন্নতা আর তার সমাধান সংগ্রহ করা হয়েছিল — নিয়মটি না জানায় অগণিত ঘণ্টা নষ্ট হয়েছে। একটি সূক্ষ্ম অংশও আছে: যে item নিজে scroll container (overflow visible নয়), তার automatic minimum শূন্য — কারণ সে নিজেই উপচে পড়া লেখা স্ক্রল বা কেটে সামলাতে পারে, data loss-এর ভয় নেই। Grid-এর 1fr ট্র্যাকেও একই ধরনের নিয়ম আছে, যার সমাধান minmax(0, 1fr) — পর্ব ২৮-এ দেখবেন।
মূল উপলব্ধি: CSS-এর অনেক “বিরক্তিকর” ডিফল্ট আসলে সুরক্ষা — বিষয়বস্তু লুকানোর চেয়ে ভাঙা দেখানো ভালো। ডিফল্টের পেছনের নীতি জানলে বুঝবেন কখন সেটি বদলানো নিরাপদ, আর বদলালে বিকল্প সুরক্ষা (ellipsis, wrap, scroll) কী দিতে হবে।
প্র ০৪CSS যদি চোখের ক্রম বদলাতে দেয় (order, row-reverse), তাহলে Tab-এর ক্রমও সাথে সাথে বদলে দেয় না কেন? এটা কি নকশার ভুল?
এর পেছনে ওয়েবের একটি মৌলিক নীতি: HTML হলো অর্থ, CSS হলো চেহারা। HTML-এর ক্রমই দলিলের যৌক্তিক ক্রম — screen reader সেই ক্রমে পড়ে, সার্চ ইঞ্জিন সেই ক্রমে বোঝে, CSS বন্ধ থাকলে বা Reader mode-এ সেই ক্রমে দেখায়, আর কপি-পেস্টও সেই ক্রমে হয়। Tab order এই যৌক্তিক ক্রমেরই অংশ। CSS যদি চুপচাপ Tab-এর ক্রম বদলাতে পারত, তাহলে চেহারার নিয়ম দিয়ে অর্থ বদলে যেত, আর একই পাতা বিভিন্ন পর্দায় (যেখানে media query-তে ভিন্ন order) ভিন্ন যৌক্তিক ক্রম পেত — screen reader ব্যবহারকারী আর দৃষ্টিশক্তি থাকা কীবোর্ড ব্যবহারকারী তখন একে অপরের সাথে কথা বলতেই পারতেন না।
আবার উল্টো দিকটাও সত্য: চোখের ক্রম আর focus-এর ক্রম আলাদা হলে দৃষ্টিশক্তি থাকা কীবোর্ড ব্যবহারকারী বিপদে পড়েন। ভাবুন একটি মোবাইল রিচার্জের ফর্মে focus নম্বরের ঘর থেকে লাফ দিয়ে পাতার ওপরের বোতামে চলে গেল — কোথায় আছেন খুঁজে পেতে সময় লাগে, ভুল বোতামে Enter পড়ার ঝুঁকিও বাড়ে। এজন্যই WCAG-এর 1.3.2 (Meaningful Sequence) চায় অর্থ বদলায় এমন ক্রম প্রোগ্রাম-পঠনযোগ্যভাবে ঠিক থাকুক, আর 2.4.3 (Focus Order) চায় focus-এর ক্রম অর্থ ও ব্যবহার রক্ষা করুক। Flexbox spec নিজেও স্পষ্ট লিখে রেখেছে — order শুধু চেহারার জন্য, অর্থবহ ক্রমের জন্য HTML বদলাতে হবে।
তাহলে সমস্যার সমাধান কী? বহু বছর এর একমাত্র উত্তর ছিল: যে ক্রম অর্থবহ, সেটি HTML-এ লিখুন, আর রেসপন্সিভ নকশায় বড় ক্রম-বদল এড়ান। Grid আর Flexbox-এর শক্তি বাড়ার সাথে সমস্যাটা এত বড় হলো যে CSS Working Group এখন reading-flow নামে নতুন property নিয়ে কাজ করছে, যেটি ডেভেলপার জেনে-বুঝে বলতে পারবেন “এই container-এ focus আর পড়ার ক্রম চোখের ক্রম মেনে চলুক”। এটি সম্প্রতি Chrome-এ এসেছে, কিন্তু এখনো Baseline নয়। লক্ষ করুন, এখানেও সিদ্ধান্তটা ডিফল্ট নয় — ডেভেলপারকে স্পষ্ট করে চাইতে হয়।
মূল উপলব্ধি: এটি ভুল নয়, স্তর আলাদা রাখার সচেতন সিদ্ধান্ত। চেহারার নিয়ম যেন চুপচাপ অর্থ বদলে না দেয় — আর অর্থ ঠিক রাখার দায়িত্ব HTML লেখকের।
প্র ০৫Flexbox ২০১২-তে স্থির হলো, অথচ flex container-এ gap সব ব্রাউজারে এলো প্রায় এক দশক পরে। এত দেরি কেন, আর এই সময়টায় কী কী ঝামেলা হয়েছিল?
gap-এর জন্ম আসলে Flexbox-এ নয়, Grid-এ। CSS Grid যখন ২০১৭ সালে সব প্রধান ব্রাউজারে আসে, তখন তার ফাঁকের property-র নাম ছিল grid-gap, grid-row-gap, grid-column-gap. পরে CSS Working Group বুঝল ফাঁকের ধারণাটা শুধু Grid-এর নয় — Flexbox, এমনকি বহু-কলামের লেখাতেও (column-gap আগে থেকেই ছিল) একই জিনিস দরকার। তাই নাম সাধারণ করে gap রাখা হলো, আর Flexbox-এও এটি যোগ হলো। Firefox আগে চালু করে, Chrome ২০২০ সালে, আর Safari ২০২১ সালে — তখনই এটি সব প্রধান ব্রাউজারে পৌঁছায়।
এই মাঝের বছরগুলোতে একটি অদ্ভুত সমস্যা হয়েছিল। ব্রাউজার কোনো ফিচার বোঝে কি না জানার স্বাভাবিক উপায় হলো @supports (পর্ব ৪৮)। কিন্তু @supports (gap: 1rem) লিখলে Grid-এর gap বোঝে এমন সব ব্রাউজারই “হ্যাঁ” বলত — property-টা তো তারা চেনে! সে flex container-এ কাজ করে কি না, তা জানার কোনো CSS উপায় ছিল না। ফলে ডেভেলপাররা JavaScript দিয়ে একটি অদৃশ্য flex বাক্স বানিয়ে তার উচ্চতা মেপে দেখতেন gap কাজ করছে কি না, অথবা নিরাপদ থাকতে পুরোনো negative margin-এর কৌশলই রেখে দিতেন: container-এ margin: -8px, প্রতিটি item-এ margin: 8px — যা পড়তে দুর্বোধ্য আর পাশের element-এর সাথে প্রায়ই সংঘাত করত। এটি feature detection-এর একটি বিখ্যাত শিক্ষা: property-র নাম চেনা আর প্রতিটি প্রসঙ্গে তার আচরণ সমর্থন করা এক কথা নয়।
ঠিক এই সময়েই CSS framework-গুলোও Flexbox-এ সরে আসে। Bootstrap-এর তৃতীয় সংস্করণ কলাম বানাত float দিয়ে; ২০১৮ সালে প্রকাশিত Bootstrap 4 তার পুরো গ্রিড Flexbox-এ নতুন করে লেখে, তবে gap-এর অভাবে কলামের ফাঁক রাখত padding আর negative margin দিয়ে। আজ gap Baseline Widely available, তাই নতুন কোডে এসব কৌশলের আর দরকার নেই — কিন্তু পুরোনো প্রজেক্টে দেখলে চিনে নিন।
মূল উপলব্ধি: একটি ফিচার “স্থির” হওয়া আর তার প্রতিটি অংশ সবার কাছে পৌঁছানো আলাদা ঘটনা। Baseline, Can I use আর নিজের হাতে পরীক্ষা — তিনটিই দেখে সিদ্ধান্ত নিন, শুধু property-র নাম চেনা দেখে নয়।
অনুশীলন
হাতে হিসাব, DevTools-এ দেখা আর এডিটরে পরীক্ষা — তিনটিই কাজে লাগান।
-
হাতে হিসাব: একটি 500px চওড়া flex container-এ তিনটি item:
.a { flex: 1 1 100px; },.b { flex: 2 1 100px; },.c { flex: 0 0 100px; }— gap নেই, padding-border নেই। প্রতিটির চূড়ান্ত চওড়া কত? container 200px হলে কত?500px: basis-এর যোগফল 300, free space +200. grow মোট 1 + 2 + 0 = 3, এক ভাগ ≈ 66.67. a = 100 + 66.67 ≈ 166.67px, b = 100 + 133.33 ≈ 233.33px, c = 100px. যোগফল 500 ✓.
200px: free space 200 − 300 = −100. c-এর shrink 0, তাই সে 100-এ অনড়। ঘাটতি 100 ভাগ হবে a আর b-তে, ওজন shrink × basis = 100 : 100, তাই প্রত্যেকে 50 ছাড়বে — a = 50px, b = 50px, c = 100px. (লেখা থাকলে a আর b-এর min-content 50-এর বেশি হলে তারা ততটা ছোট হবে না — তখন সারি container ছাপাবে; এটাই অংশ ৮-এর ফাঁদ।)
-
DevTools-এ flex overlay: এই পাতারই ওপরের হিরো অংশ বা যেকোনো পরিচিত সাইটের হেডারে ডান-ক্লিক করে Inspect চাপুন। Elements প্যানেলে “flex” ব্যাজ খুঁজে overlay চালু করুন। (ক) main axis কোন দিকে? (খ) gap আছে কি? (গ) Styles-এর flexbox editor থেকে
justify-contentবদলে কী হয়?বেশিরভাগ সাইটের হেডারে একটি flex container পাবেন, যার
flex-directionrow — overlay-তে item-গুলোর চারপাশে রঙিন দাগ আর মাঝে ডোরাকাটা অংশ (gap থাকলে) দেখা যাবে। কোথাও ডোরাকাটা না থেকে item-দের ভেতরে margin থাকলে বুঝবেন ফাঁক margin দিয়ে দেওয়া। flexbox editor-এspace-betweenচাপলে item-রা দুই কিনারায় ছড়িয়ে যাবে — এটি শুধু আপনার ব্রাউজারে, পাতা রিফ্রেশ করলেই আগের মতো। Firefox-এ একই পাতার Layout প্যানেলে কোনো item বেছে নিয়ে তার basis আর “কতটা বেড়েছে/কমেছে” পড়ে অংশ ৭-এর হিসাবের সাথে মিলিয়ে দেখুন। -
পুরোনো কোড আধুনিক করুন: একটি পুরোনো প্রজেক্টে মেনু এভাবে লেখা —
.menu li { float: left; margin-right: 12px; },.menu li:last-child { margin-right: 0; },.menu::after { content: ""; display: table; clear: both; }, আর লগইন লিংক ডানে নিতে.login { float: right; }. একই ফল Flexbox দিয়ে লিখুন।.menu { display: flex; gap: 12px; align-items: center; /* উচ্চতায় সবাই মাঝখানে — বোনাস */ list-style: none; padding: 0; } .login { margin-left: auto; } /* বাকি জায়গা খেয়ে ডানে */float,
:last-childআর clearfix — তিনটিই বাদ। float সরানোয় parent আর উচ্চতা হারায় না, তাই clearfix লাগে না;gapশুধু মাঝে ফাঁক দেয়, তাই শেষ item-এর জন্য আলাদা নিয়ম লাগে না। আরfloat: right-এর বিপরীতেmargin-left: autoHTML-এর ক্রম বদলায় না — float-এ একাধিক ডানের item চোখে উল্টো ক্রমে দেখা যেত। -
AI অডিট: যেকোনো AI-কে বলুন “একটি চ্যাট অ্যাপের বার্তার তালিকার HTML আর CSS দাও — বাঁয়ে প্রোফাইল ছবি, পাশে নাম আর শেষ বার্তা, ডানে সময়।” তারপর অংশ ১০-এর টেবিল আর চেকলিস্ট ধরে যাচাই করুন। কোন কোন সমস্যা পেলেন?
সাধারণত যা পাওয়া যায়:
- শেষ বার্তার লেখা এক লাইনে কাটতে
white-space: nowrap; text-overflow: ellipsisআছে, কিন্তু লেখার item-এmin-width: 0নেই — লম্বা বার্তায় সময়টি ডানে বাইরে চলে যায়। - প্রোফাইল ছবিতে
flex-shrink: 0নেই — ছোট পর্দায় গোল ছবি ডিম্বাকার হয়ে চেপে যায়। - নতুন বার্তা নিচে দেখাতে
flex-direction: column-reverse— screen reader আর Tab চলে উল্টো ক্রমে। - কখনো কখনো
-webkit-flexবা ফাঁকের জন্য প্রতিটি item-এ margin.
প্রতিটি সমস্যা DevTools-এর flex overlay আর 320px চওড়ায় দেখে প্রমাণ করুন, তারপর AI-কে নির্দিষ্ট করে বলুন কী বদলাতে হবে।
- শেষ বার্তার লেখা এক লাইনে কাটতে
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমflex item-দের মাপ ঠিক করতে ব্রাউজার যে ধাপগুলো পার হয়, সেগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- 📏 প্রতিটি item-এর শুরুর মাপ (flex-basis) ঠিক করা
- ➖ container-এর মাপ থেকে সব basis-এর যোগফল বাদ দিয়ে free space বের করা
- ⚖️ free space ধনাত্মক হলে flex-grow, ঋণাত্মক হলে flex-shrink × basis অনুপাতে ভাগ
- 🔒 min-width / max-width-এর সীমা ভাঙলে item আটকে বাকিদের মধ্যে আবার ভাগ
- ↔️ বাঁচা জায়গা auto margin আর justify-content দিয়ে সাজানো
একটি flex container-এ flex-direction: column দেওয়া আছে। এখন justify-content: center item-দের কোন দিকে মাঝখানে আনবে?
- আনুভূমিকভাবে (বাঁ-ডানে)
- উল্লম্বভাবে (ওপর-নিচে)
- দুই দিকেই
- কোনো দিকেই না, column-এ এটি কাজ করে না
CSS-এ flex: 1 লিখলে তিনটি মূল property-র মান কী হয় (grow shrink basis)?
- 0 1 auto
- 1 1 auto
- 1 1 0%
- 1 0 0
400px চওড়া একটি flex container-এ দুটি item, দুটিরই flex-basis: 100px; প্রথমটির flex-grow: 1, দ্বিতীয়টির flex-grow: 3. gap, padding, border নেই। দ্বিতীয় item-এর চূড়ান্ত চওড়া কত?
- 300px
- 200px
- 150px
- 250px
একটি flex item-এর ভেতরে লম্বা একটি ফাইলের নাম white-space: nowrap; overflow: hidden; text-overflow: ellipsis; দিয়ে কাটার চেষ্টা হয়েছে, কিন্তু “…” না দেখিয়ে লেখা container ছাপিয়ে যাচ্ছে। সবচেয়ে সম্ভাব্য সমাধান কোনটি?
- ওই flex item-এ
min-width: 0দেওয়া - item-এ
flex-grow: 1দেওয়া - container-এ
overflow-wrap: anywhereদেওয়া - container-এ
justify-content: centerদেওয়া
flex container-এ align-content: center লেখা হলো, কিন্তু কোনো পরিবর্তন দেখা গেল না। নিচের কোন অবস্থায় এটি স্বাভাবিক?
- container-এর
flex-directionহলোcolumn - container-এ
flex-wrap: nowrap(ডিফল্ট) - container-এ
gapদেওয়া আছে - item-গুলোর
flex-grow: 1
একটি flex container-এর চারটি বোতামের শেষটিকে order: -1 দিয়ে চোখে প্রথমে আনা হলো। কীবোর্ডে Tab চাপলে এই বোতামে focus কখন যাবে?
- প্রথম Tab-এ, কারণ চোখে সে প্রথম
- কখনোই না — ঋণাত্মক order-এ focus যায় না
- সবার শেষে, চতুর্থ Tab-এ
- ব্রাউজারভেদে এলোমেলো
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- parent-এ
display: flex→ সে container, শুধু সরাসরি child-রা item. item-দের margin মেশে না, float কাজ করে না। flex-directionঠিক করে main axis; justify-content = main, align-items / align-self = cross. ফাঁকের জন্যgap.flex-wrap: wrapদিলে একাধিক লাইন; তখনই align-content লাইনগুলোকে সাজায়।- free space = container − basis-এর যোগফল; + হলে grow-এর অনুপাতে, − হলে shrink × basis-এর অনুপাতে।
flex: 1=1 1 0%,flex: auto=1 1 auto,flex: none=0 0 auto. - লেখা ছাপিয়ে গেলে item-এ
min-width: 0;margin: autoবাড়তি জায়গা খায়;orderআর reverse শুধু চোখের ক্রম বদলায় — অর্থবহ ক্রম HTML-এ।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ২৬ · Flexbox দিয়ে বাস্তব নকশা — navbar, কার্ড আর মাঝখানে বসানোপরবর্তী পর্বএই পর্বের নিয়ম দিয়ে বাস্তব পাতার পরিচিত অংশগুলো বানানো।
- পর্ব ২৭ · CSS Grid — সারি আর কলামে দুই দিকের লেআউটদুই দিকের লেআউটFlexbox-এর সহকর্মী — যেখানে সারি আর কলাম দুটোই মেলাতে হয়।
- HTML ও CSS · কোর্স হোম৫৯টি পর্বপুরো কোর্সের রোডম্যাপ — কোন পর্ব কখন।
- JavaScript · DOM-এর ভিত্তিপাশের ট্র্যাকJavaScript দিয়ে element খুঁজে তার মাপ আর স্টাইল পড়া-বদলানো।