সিএসএস গ্রিড

by borhan

সতর্কতা:

CSS Grid Bangla এটা কোন প্রফেশনাল লেখা নয় । অনেকটা পার্সোনাল নোট করতে গিয়ে করে ফেলা । তাই, এটতেও ভুল অবশ্যই আছে । "এটাই বাস্তব, কিছু করার নেই" । প্রয়োজনে নিজ দায়িত্বে সংশোধন হয়ে নিবেন এবং চাইলে আমাকেও ভুলগুলো ধরে দিতে পারেন ।

CSS Grid (1). Photo: Internet
CSS Grid (2). Photo: Internet

সিএসএস গ্রিড কী?

ওয়েবসাইট বানানোর জন্য আমাদের সবার আগে প্রয়োজন হয় লে-আউটের । ওয়েবসাইটের জন্য বিভিন্ন রকমের লেআউট তৈরীর জন্যই এই গ্রিড । সিএসএসের গ্রিডের মাধ্যমে আমরা একসাথেই সারি (row) এবং কলামে (column) ভাগ করে কাজ করতে পারি বলে যেকোন লেআউট তৈরী করা অনেক সহজ হয় ।

কিভাবে ব্যবহার করব ?

এটা ব্যবহার করার জন্য আমাদের একটি প্যারেন্ট এবং এক বা একাধিক চাইল্ড এলিমেন্ট থাকতে হবে । প্রথম কাজ হচ্ছে আমাদের প্যারেন্ট সেকশনকে display:grid; বা display:inline-grid; দিয়ে দেওয়া । grid দিয়েই আমরা শুরু করি inline-grid নিয়ে পরে জানা যাবে ।

<div class="grid" >
<div class="single-grid" > </div>
<div class="single-grid" > </div>
<div class="single-grid" > </div>
<div class="single-grid" > </div>
....
</div>
.grid{ display:grid; }

এখনো কিছু পরিবর্তন হবে না । পরিবর্তনের জন্য আমাদের পরবর্তী ধাপে যেতে হবে ।

কলামে ভাগ করা

কলামে ভাগ করতে চাইলে আমাদের প্রথম কাজ প্যারেন্ট সেকশনকে grid-template-columns: 100px 100px 100px ; দেওয়া । ১০০ পিক্সেলের মানে কী ? এখানে তিনটা ১০০ পিক্সেল দেওয়া আছে যার মানে এখানে তিনটা কলাম তৈরি হবে । এবং প্রত্যেকটির দৈর্ঘ্য ১০০ পিক্সেল করে । যেমন grid-template-columns: 100px 200px 100px 300px ; এর মাধ্যমে বুঝানো হয়েছে চারটি কলাম তৈরি করতে, যেখানে ১ম, ২য়, ৩য় এবং ৪র্থ কলামের দৈর্ঘ্য যথাক্রমে ১০০ পিক্সেল, ২০০ পিক্সেল, ১০০ পিক্সেল এবং ৩০০ পিক্সেল । আমরা আমাদের ইচ্ছামতো কলামে ভাগ করতে পারি, সাথে দিয়ে দিতে পারি দৈর্ঘ্যও ! আর display:grid; তো অবশ্যই দিতে হবে ।

<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
<div class="single-grid">3</div>
<div class="single-grid">4</div>
<div class="single-grid">5</div>
<div class="single-grid">6</div>
</div>
.grid{
display:grid;
grid-template-columns: 100px 100px 100px;
}
.single-grid{
background:lightgray;
padding:10px;
}

single-grid ক্লাসে স্টাইলগুলো শুধুমাত্র বোঝার সুবিধার জন্য দেওয়া হয়েছে ।

1
2
3
4
5
6
7
8
9
দেখা যাচ্ছে, তিনটা কলামে ভাগ হয়ে গিয়েছে এবং সবার সাইজ সমান, কারণ আমরা তিনটা কলামকেই 100px করেই দিয়েছি । আর এখানে নয়টা দেখানোর কারণ আমি চাইল্ড ডিব আরো তিনটা দিয়েছি শেষে । Grid Gap নিয়ে পরে বলা হবে ।

সারিতে ভাগ করা

সারিতে (row) ভাগ করার জন্য আমাদের যে সিএসএস property ব্যবহার করা লাগবে তা হচ্ছে grid-template-rows । যেমন, grid-template-rows:100px 200px; দিয়ে বোঝানো হচ্ছে এখানে দুইটি row তৈরী হবে যেখানে ১ম এবং ২য় সারির প্রস্থ যথাক্রমে 100px এবং 200px

<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
<div class="single-grid">3</div>
<div class="single-grid">4</div>
<div class="single-grid">5</div>
<div class="single-grid">6</div>
</div>
.grid{
display:grid;
grid-template-rows: 80px 50px;
grid-template-columns:100px 80px 100px;
}
1
2
3
4
5
6
এখানে দুইটা সারি তৈরি হয়েছে ৮০ এবং ৫০ পিক্সেলের । পাশাপাশি তিনটি কলাম হয়েছে ১০০, ৮০ এবং ১০০ পিক্সেলের । কেননা, আমরা তাই দিয়েছিলাম ।
grid-template-rows: 80px 50px;
grid-template-columns:100px 80px 100px;
 এই দুই লাইনকে একসাথে লিখা যায় grid-template: 80px 50px / 100px 80px 100px;

গ্রিড গ্যাপ

গ্রিডের মাঝে গ্যাপ দেওয়ার জন্য সারি হলে grid-row-gap এবং কলামে দিতে চাইলে grid-column-gap ব্যবহার করা হয় । আমরা চাইলে আলাদাভাবে না করে একলাইনে দিয়ে দিতে পারি grid-gap:row column; মাধ্যমে ।

<div class="grid">
<div class="single-grid">1</div>
...
<div class="single-grid">6</div>
</div>
.grid{
display:grid;
grid-template-rows: 80px 50px;
grid-template-columns:100px 80px 100px;
grid-row-gap:20px;
grid-column-gap:10px;
}
1
2
3
4
5
6
কলামগুলোর মাঝে ১০ পিক্সেলের এবং রো'র মাঝে ২০ পিক্সেলের গ্যাপ দেখা যায় ।
grid-row-gap:20px;
grid-column-gap:10px;
 একলাইনে লিখলে হয় grid-gap:20px 10px;

ফ্রাকশনাল ইউনিট এবং রিপিট

এমনও হতে পারে যে আমরা সরাসরি পিক্সল ব্যবহার করতে চাই না । আমরা বলতে চাই আমাদের কলামের সাইজ হবে কন্টেইনার/প্যারেন্টের তিন ভাগের এক ভাগ ইত্যাদি । ঠিক এই জন্যই ব্যবহৃত হয় fr । ধরা যাক, আমরা বললাম grid-template-columns:1fr 1fr 2fr; । এর মাধ্যমে এইটা বোঝায় আমরা কন্টেইনার/প্যারেন্টের মোট width কে (1fr + 1fr + 2fr)=4 মানে 4 ভাগে ভাগ করেছি । সেখান থেকে ১ম, ২য়, ৩য় কলামকে দিয়েছি যথাক্রমে ১,১ এবং ২ ভাগ ।

আবার দেখা যায়, আমরা 1fr টা দুইবার লিখেছি । যদি আমরা দশটা কলাম/রো চাইতাম তাহলে আমাদের 1fr টা লিখতে হতো মোট দশবার । এই সমস্যা থেকে বাঁচার জন্য আমরা ব্যবহার করবো repeat(কত বার রিপিট হবে, কত px, fr, %) । যেমন, grid-template-columns:1fr 1fr 2fr; আমরা এই লাইনটা লিখতে পারি এইভাবে grid-template-columns:repeat(2, 1fr) 2fr; । যদি আমাদের 1fr সাইজের দশটা কলাম লাগতো তাহলে আমরা লিখতাম grid-template-columns:repeat(10, 1fr);

1
2
3
4
5
6
.grid{
display:grid;
grid-template-columns:repeat(2, 1fr) 2fr;
grid-gap:20px 10px ;
}
১.
grid-template-columns:200px 1fr 100px 1fr;
 এই ক্ষেত্রে প্রথমে ১ম এবং ৩য় কলামকে ২০০ পিক্সেল এবং ১০০ পিক্সেল দেওয়ার পর বাকি অংশ ২ (1fr + 1fr) ভাগে ভাগ হয়ে যাবে, তারপরই ২য় এবং ৪র্থ কলাম ১ ভাগ করে পারে ।
 অর্থাৎ, পিক্সেলের কাজ আগে করার পরই fr এ যাবে ।
২.
grid-template-columns:minmax(100px, 350px) 1fr 100px 1fr;
minmax(সর্বনিম্ন সাইজ, সর্বোচ্চ সাইজ) এটা দিয়ে কোন কলাম বা রো এর সর্বোচ্চ সাইজ এবং সর্বনিম্ন সাইজ দিয়ে দেওয়া যাবে । যদি আমরা চাই সর্বনিম্ন সাইজ হবে 100px আর সর্বোচ্চ সাইজের কোন শর্ত থাকবে না, তাহলে লিখতে পারি minmax(100px, auto)
গ্রিড লাইন (১) । ডান থেকে বাম পাশে কলাম এবং উপর থেকে নিচে রো নির্দেশ করছে ।

গ্রিড লাইন (১)

কোন কলাম বা রো কোথায় শুরু হয়েছে আর কোথায় শেষ হয়েছে সেটাই নির্দেশ করে মূলত গ্রিড লাইন । ছবিতে দেখা যায়, কলামের ক্ষেত্রে ডান পাশ থেকে শুরু করে একদম বাম পাশের লাইনটাতে গিয়ে শেষ হয় । আবার, রো এর জন্য উপর থেকে শুরু করে একদম নিচে গিয়ে শেষ হয় । আর আমরা এভাবে চিনতে পারি কোন চাইল্ড কত নাম্বার লাইনে আছে ।

গ্রিড লাইন (২) : চাইল্ডের স্থান পরিবর্তন

আমাদের ছয়টা চাইল্ড আইটেম আছে । আমরা আমাদের ছয় নাম্বারকে দুই নাম্বারের আইটেমের জায়গায় নিয়ে আসতে চাই । কোন আইটেমের স্থান পরিবর্তন করার জন্যে আমাদের উক্ত আইটেমের গ্রিড লাইনটাকেই পরিবর্তন করতে হবে । যদি আমরা আমাদের ছয় নাম্বার আইটেমের রো শুরু হয়েছে ২ নং এবং শেষ হয়েছে ৩ নং লাইনে, কলাম শুরু হয়েছে ৩ নং এবং শেষ হয়েছে ৪ নং লাইনে । আমরা এটাকে নিয়ে আসতে চাই ২ নাম্বার আইটেমে যার রো লাইনে শুরু এবং শেষ হয়েছে যথাক্রমে ১ এবং ২ নং লাইনে আর কলাম লাইন শুরু হয়েছে ২ নং এবার শেষ হয়েছে ৩ নং ।

তাই আমরা যেই চাইল্ড / আইটেমকে সরাতে চাই তাকে সিলেক্ট করে এর গ্রিড লাইন চেঞ্জ করে দিতে হবে । রো যে জায়গায় শুরু এবং শেষ হবে তার সিএসএস প্রোপার্টি হচ্ছে grid-row-start এবং grid-row-end । কলাম শুরু এবং শেষ লাইন পরিবর্তন করতে grid-column-start এবং grid-column-end

গ্রিড লাইন (২)
1
2
3
4
5
6
আমাদের সর্বশেষ এলিমেন্টটি ২ নাম্বারের জায়গায় চলে এসেছে । আমরা চাইলে এভাবে কোন একটা এলিমেন্টকে অন্য এলিমেন্টের জায়গায় বা এর সাইজ বড়-ছোট করতে পারি ।
<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
...
<div class="single-grid" id="last-item">6</div>
</div>
.grid{
display:grid;
grid-template-rows: 80px 50px;
grid-template-columns:100px 80px 100px;
}
#last-item{
grid-row-start:1;
grid-row-end:2;
grid-column-start:2;
grid-column-end:3;
}
১.
grid-row-start:1;
grid-row-end:2;
এই দুটোকে একলাইনে লেখা যায় grid-row:1 / 2;
২.
grid-column-start:2;
grid-column-end:3;
এই দুটোকে একলাইনে লেখা যায় grid-column:2 / 3;
৩.
grid-row:1 / 2;
grid-column:2 / 3;
 এই দুটোকে একলাইনে লেখা যায় grid-area:1 / 2 / 2 / 3;
grid-area: row-start / column-start / row-end / column-end;

অ্যালাইন করা (১) : আইটেমের সাপেক্ষে

আমরা চাইলে আমাদের আইটেমসমূহকে (নিজেদের সাপেক্ষে) মাঝখানে, ডানে, বামে ইত্যাদি নানাভাবে সরাতে পারি । যদি আমরা অনুভূমিকভাবে (horizontally) সাজাতে চাই তাহলে ব্যবহার করব justify-items:...; । আর উল্লম্ব বা vertically অ্যালাইন করতে চাই তাহলে ব্যবহার করা লাগবে align-items:...;

<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
<div class="single-grid">3</div>
<div class="single-grid">4</div>
</div>
.grid {
display: grid;
justify-items: center;
grid-gap: 10px;
grid-template-columns: 50px 50px 100px 50px;
}
Horizontally আইটেমগুলো (নিজের সাপেক্ষে) center এ চলে এসেছে । ছবিতে দেখলে, 100px দেওয়া কলামটা তার দৈঘ্য অনুযায়ী এসেছে । তেমনি 50px কলামগুলোও তাদের দৈঘ্যের সাপেক্ষে সেন্টার হয়ে গিয়েছে । আর মাঝখানে কমলা রঙের লাইন দিয়ে গ্রিড গ্যাপ বোঝানো হচ্ছে । তাই ভেবে নেওয়ার দরকার নেই যে কলামের দৈর্ঘ্য কমে গেছে, আইটেমগুলোর ভেতর টেক্সট অনুযায়ী এর সাইজ পরিবর্তন হয়েছে শুধু ।
Vertically আইটেমগুলো (নিজের সাপেক্ষে) center এ চলে এসেছে । ছবিতে দেখলে, 100px দেওয়া সারিটার তার হাইট অনুযায়ী সেন্টারে এসেছে । তেমনি 50px রো'গুলো তাদের সাইজের সাপেক্ষে সেন্টার হয়ে গিয়েছে । আর মাঝখানে লাল রঙের লাইন দিয়ে গ্রিড গ্যাপ বোঝানো হচ্ছে । তাই ভেবে নেওয়ার দরকার নেই যে রো'এর সাইজ কমে গেছে, আইটেমগুলোর ভেতর টেক্সট অনুযায়ী এর সাইজ পরিবর্তন হয়েছে শুধু ।
<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
<div class="single-grid">3</div>
<div class="single-grid">4</div>
</div>
.grid {
display: grid;
align-items: center;
grid-gap: 10px;
grid-template-rows: 50px 50px 100px 50px;
}
align-items/justify-items এ শুধু যে সবসময় center করতে হবে এমন না । আমরা চাইলে start, end, stretch (default value) ইত্যাদি প্রয়োজন অনুযায়ী ব্যবহার করতে পারি ।

অ্যালাইন করা (২) : প্যারেন্টের সাপেক্ষে

যদি আমরা পুরো প্যারেন্ট/কন্টেইনারের সাপেক্ষে আমাদের আইটেম/চাইল্ডগুলোকে মাঝখানে, একদম বামে, ডানে ইত্যাদিতে সাজাতে চাই তাহলে ব্যবহার করতে হবে justify-content (horizontally) এবং align-content (vertically) ।

1
2
3
4
5
6
7
8
9
Grid-gap না দিয়েই এরা দূরে সরে গিয়েছে । কারণ আমরা justify-content এবং align-content এ বলে দিয়েছি এদের মাঝে স্পেস করে নিতে । তাই প্রথমে এরা নিজেদের সাইজ (50px) নিয়ে প্যারেন্টের (300px X 200px) বাকি অংশগুলোতে স্পেস করেছে ।
<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
....
<div class="single-grid">9</div>
</div>
.grid {
display: grid;
grid-template: repeat(3, 50px) / repeat(3, 50px);
justify-content: space-between;
align-content: space-around;
width: 300px;
height: 200px;
}
space-between ছাড়াও আরো ব্যবহার করা যেতে পারে space-around, space-evenly, center, start, end, center ইত্যাদি ।

অ্যালাইন করা (৩) : নির্দিষ্ট আইটেমকে

যদি নির্দিষ্ট কোন আইটেমকে আমরা তার সাপেক্ষে মাঝখানে, একদম বামে, ডানে ইত্যাদিতে সাজাতে চাই তাহলে ব্যবহার করতে হবে justify-self (horizontally) এবং align-self (vertically) ।

1
2
3
4
5
6
7
8
9
৯ নং আইটেমটা নিজের সাপেক্ষে vertically শেষে/নিচে (end) এবং horizontally মাঝখানে (center) এসেছে ।
<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
....
<div class="single-grid" id="single-grid-9">9</div>
</div>
.grid {
.....
}
#single-grid-9 {
align-self: end;
justify-self: center;
}
justify-items/align-items এ যেসব ভ্যালু ব্যবহার করা যেতো এখানেও তা ব্যবহার করা যাবে

গ্রিড নাকি ইনলাইন গ্রিড?

display:grid;
display:inline-grid;
যদি আমরা রো বা কলামের নির্দিষ্ট সাইজ বলে না দিই, তাহলে grid যা উইডথ নিতে পারে নিয়ে নেয় এবং অন্যদিকে inline-grid শুধুমাত্র এর চাইল্ডের কন্টেটের জন্য সর্বোচ্চ যতটুকু নেওয়া যায় ঠিক ততটুকুই নেয় । এটাই প্রাইমারি পার্থক্য ।

অটো ফ্লো

ধরা যাক, আমরা বলেছি grid-template-rows:repeat(3,100px) । অর্থাৎ ১০০ পিক্সেলের তিনটি রো করতে । কিন্তু এই তিনটি ছাড়া যদি আমাদের আরো আইটেম থাকে তাহলে তাদের কী হবে ? এরাও কি রো হবে নাকি কলাম ? এইটা ঠিক করে দিতে চাইলে grid-auto-flow: row নাকি column; সেটা বলে দিতে পারি । আমরা চাইলে এই অটো রো বা কলাম হয়ে যাওয়া আইটেমগুলোর সাইজও ঠিক করে দিতে পারি grid-auto-columns এবং grid-auto-rows প্রোপার্টিতে ।

<div class="grid">
<div class="single-grid">1</div>
<div class="single-grid">2</div>
....
<div class="single-grid">6</div>
</div>

.grid{
display: grid;
grid-template-columns: repeat(2, 30px);
grid-auto-flow: column;
grid-auto-columns: 1fr;
grid-gap: 2px;
}
1
2
3
4
5
6
এখানে প্রথম দুইটি কলাম ৩০পিক্সেল করে পেয়েছে এবং বাকিগুলো কন্টেইনারের বাকি অংশ সমানভাগে ভাগ করে ১ ভাগ করে পেয়েছে ।

গ্রিড অ্যারিয়া নির্ধারণ/নাম দেওয়া

ভাবুন আমরা কন্টেইনারকে রো বরাবর ছয়ভাগে ভাগ করবো ।

  • প্রথম রো'তে হেডার থাকবে এবং পুরো অংশই পাবে ।
  • দ্বিতীয় রো তিনভাগ হবে । মাঝখানে কনটেন্ট, দুই পাশে দুইটা সাইডবার । সাইডবার দুটো পাবে এক ভাগ করে করে, বাকি (৪ ভাগ) অংশ পাবে কন্টেন্ট ।
  • এইটা ফুটার । ফুটারের দুইটি অংশ থাকবে । footer left (৪ ভাগ) এবং footer right (২ ভাগ) ।

এভাবে করার জন্য আমাদের CSS Grid দিয়ে দিয়েছে grid-template-areas property । একটা উদাহরণ দেওয়া যাক ।

grid-template-areas:
"header header header"
"sidebar1 contnt siderbar1"
"footer footer footer" ;

এখানে আমরা আমাদের পুরো কন্টেইনারকে তিনটি কলাম এবং তিনটি রো'তে ভাগ করেছি । প্রথম রো'তে পুরোটাই হেডার । দ্বিতীয় রো এর প্রথম কলামে সাইডবার১, দ্বিতীয় কলামে কন্টেন্ট এবং তৃতীয় কলামে সাইডবার২ । আর তিন নাম্বার রো'র সব কলাম জুড়ে আছে ফুটার ।

এবার আমরা যে আইটেমকে হেডার হিসেবে দেখতে চাই তাকে একটা ক্লাস দিয়ে অথবা inline css এ লিখে দিতে পারি grid-area:header । এভাবে বাকিগুলোও ...

<div class="grid">
<div class="header">Header</div>
<div class="sidebar1">S1</div>
<div class="content">Content</div>
<div class="sidebar2">S2</div>
<div class="f-left">Footer Left</div>
<div class="f-right">Footer Right</div>
</div>
.grid{
display: grid;
grid-template-areas:
'h h h h h h'
's1 c c c c s2'
'fl fl fl fr fr fr';
grid-gap: 2px;
grid-template-rows:
50px 1fr 50px;
}
.header{
grid-area:h;
}
.sidebar1{
grid-area:s1;
}
.content{
grid-area:c;
}
.sidebar2{
grid-area:s2;
}
.f-left{
grid-area:fl;
}
.f-right{
grid-area:fr;
}
Header
S-1
contnet
grid-template-rows: 50px 1fr 50px; এ দিয়ে বলা হয়েছে প্রথম এবং তৃতীয় রো (হেডার এবং ফুটার) 50px করে পাবে এবং বাকি অংশ জুড়ে থাকবে সেকেন্ড রো ।

এছাড়াও গ্রিডের আরো ব্যবহার রয়েছে ...