এই পর্বে যা শিখবেন
- দশটি filter ফাংশন কী করে, কোনটির মান কীভাবে পড়তে হয়, আর কেন তাদের ক্রম ফল বদলে দেয়
drop-shadow()আরbox-shadow-এর আসল পার্থক্য — স্বচ্ছ লোগো আর কাটা আকৃতিতেbackdrop-filterদিয়ে ঘষা কাচের হেডার, তার fallback, পাঠযোগ্যতা আর পারফরম্যান্সের হিসাব- multiply, screen, overlay, difference — রং মেশানোর গণিত, duotone ছবি আর
isolation clip-path-এর আকৃতি, polygon বিন্দু ধরে ধরে বানানো, reveal animation আর gradient বা ছবি দিয়েmask
১ · আঁকা শেষ, তারপর সম্পাদনা — ভিজ্যুয়াল ইফেক্টের চার পরিবার
মোবাইলে ছবি তুলে আপনি হয়তো একটু উজ্জ্বল করেন, সাদা-কালো করেন, বা গোল করে কেটে প্রোফাইল ছবি বানান। ওয়েবে এসব একসময় Photoshop-এ করে আলাদা ছবি আপলোড করতে হতো। আজ CSS নিজেই এই কাজগুলো পারে — মূল ছবি একটিই থাকে, আর ব্রাউজার দেখানোর সময় সম্পাদনা করে।
এই পর্বের মূল ধারণাটি একটি বাক্যে বলা যায়: ব্রাউজার প্রথমে element-টি তার সব সন্তানসহ সাধারণভাবে আঁকে, তারপর সেই আঁকা ছবির ওপর সম্পাদনা চালায়। পর্ব ১-এ দেখেছেন, পাতা দেখানোর ধাপগুলো হলো layout, paint আর compositing. ভিজ্যুয়াল ইফেক্ট বসে paint আর compositing-এর মাঝখানে। এগুলো layout বদলায় না — কোনো element একচুলও সরে না, শুধু চেহারা বদলায়।
পুরান ঢাকার একটি রিকশা-পেইন্টিং কারখানার কথা ভাবুন। শিল্পী প্রথমে টিনের পাতে পুরো ছবি আঁকলেন। তারপর চারভাবে সেটি বদলানো যায়। এক — ছবির ওপর রঙিন সেলোফেন কাগজ ধরা, পুরো ছবি লালচে বা ঝাপসা দেখায় (filter). দুই — কাঁচি দিয়ে ছবিটি তারার আকারে কেটে ফেলা, বাইরের অংশ একেবারে নেই (clip-path). তিন — ওপরে একটি স্টেনসিল রাখা, যার কোথাও পুরো ফুটো, কোথাও আধা-স্বচ্ছ কাপড় — কিনারা নরমভাবে মিলিয়ে যায় (mask). চার — ছবিটি একটি রঙিন দেয়ালের ওপর এমনভাবে বসানো যে দেয়ালের রং ছবির সাথে মিশে যায় (blend mode). চারটি কাজই আঁকা শেষ হওয়ার পরে।
filter
প্রতিটি পিক্সেলের রং, উজ্জ্বলতা বা স্বচ্ছতা বদলায়; blur আশেপাশের পিক্সেল মেশায়। সাথে আত্মীয় backdrop-filter, যা পেছনের জিনিসের ওপর কাজ করে।
clip-path
একটি আকৃতির রেখা ধরে কেটে দেয়। রেখার ভেতরে পুরো দেখা যায়, বাইরে কিছুই না — হ্যাঁ বা না, মাঝামাঝি নেই।
circle, inset, polygonmask
একটি ছবি বা gradient-এর স্বচ্ছতা দিয়ে ঠিক করে কোন অংশ কতটা দেখা যাবে। তাই কিনারা ধীরে ধীরে মিলিয়ে যেতে পারে।
mask-image, gradientblend mode
ওপরের রং নিচের রঙের সাথে কোন গাণিতিক নিয়মে মিশবে। স্বাভাবিক অবস্থায় ওপরেরটা নিচেরটাকে ঢেকে দেয়; blend mode দিলে মেশে।
multiply, screen, differenceচারটি ইফেক্টই element-কে একটি আলাদা “স্তরে” আঁকতে বাধ্য করে — অর্থাৎ নতুন একটি stacking context তৈরি করে (পর্ব ২৪). ফলে ভেতরের element-এর z-index বাইরের element-এর সাথে আর প্রতিযোগিতা করে না। ইফেক্ট দেওয়ার পর কোনো dropdown হঠাৎ অন্য কার্ডের নিচে চলে গেলে প্রথমেই এই কথাটি মনে করুন।
এই ইফেক্টগুলোর জন্ম আসলে SVG-এ। ২০০১ সালের SVG 1.0-তেই filter, clipPath আর mask ছিল — কিন্তু শুধু SVG-র ভেতরের আঁকায়। অন্যদিকে Internet Explorer নিজস্ব, মানহীন filter: progid:DXImageTransform… আর filter: alpha(opacity=50) চালু করেছিল, যা অন্য কোনো ব্রাউজারে চলত না। পরে CSS-এর Filter Effects আর CSS Masking নামের দুটি spec SVG-র সেই ক্ষমতা সাধারণ HTML element-এর জন্য সহজ ভাষায় নিয়ে আসে, আর Compositing and Blending spec আনে blend mode. তাই আজও filter: url(#id) লিখে HTML-এ একটি SVG filter ব্যবহার করা যায় — দুই জগৎ একই যন্ত্র ভাগ করে নেয়।
২ · filter — দশটি ফাংশনে ছবি-সম্পাদনা
filter property-তে এক বা একাধিক ফাংশন লেখা হয়, ফাঁকা জায়গা দিয়ে আলাদা করে (কমা নয়)। প্রতিটি ফাংশন পুরো element-এর ওপর কাজ করে — লেখা, বর্ডার, ব্যাকগ্রাউন্ড, ভেতরের ছবি, সন্তান element সব। কোন ফাংশন কী করে, আর মান কীভাবে পড়বেন:
| ফাংশন | কী করে | মান পড়ার নিয়ম |
|---|---|---|
blur(4px) | ঝাপসা করে | দৈর্ঘ্য; 0 মানে কিছুই না, বড় মান মানে বেশি ঝাপসা (শতাংশ চলে না) |
brightness(1.3) | উজ্জ্বলতা | 1 বা 100% = আগের মতো; 0 = পুরো কালো; 1-এর বেশি = বেশি উজ্জ্বল |
contrast(1.5) | আলো-ছায়ার পার্থক্য | 1 = আগের মতো; 0 = পুরো ধূসর একরঙা |
grayscale(1) | সাদা-কালো | 0 = আগের মতো; 1 বা 100% = পুরো সাদা-কালো |
sepia(1) | পুরোনো বাদামি ছবির মতো | 0 থেকে 1 |
saturate(2) | রঙের তীব্রতা | 1 = আগের মতো; 0 = ধূসর; 2 = দ্বিগুণ ঝলমলে |
hue-rotate(90deg) | রঙের চাকা ঘোরায় | কোণ; 0deg বা 360deg = আগের মতো |
invert(1) | রং উল্টে দেয় (সাদা ↔ কালো) | 0 থেকে 1; 0.5 দিলে সব ধূসর হয়ে যায় |
opacity(.5) | স্বচ্ছতা | 1 = পুরো দেখা যায়; 0 = অদৃশ্য |
drop-shadow(4px 4px 6px #0008) | আকৃতি ধরে ছায়া | x, y, blur, রং — spread আর inset নেই |
খেয়াল করুন, বেশিরভাগ ফাংশনে মান না দিলেও চলে — তখন ব্রাউজার “পুরো মাত্রা” ধরে নেয় (grayscale() মানে grayscale(1), কিন্তু blur() মানে blur(0)). পরিষ্কারের জন্য সবসময় মান লিখে দেওয়াই ভালো। নিচে একই ছবিতে নয়টি ফাংশন দেখুন — ছবিটি এই সাইটেরই একটি ব্লগ-কভার:
body {
display: grid; gap: 8px;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
font: 12px monospace;
}
figure { margin: 0; overflow: hidden; }
img { display: block; width: 100%; }
.f1 img { filter: blur(3px); }
.f2 img { filter: brightness(1.5); }
.f3 img { filter: contrast(1.8); }
.f4 img { filter: grayscale(1); }
.f5 img { filter: sepia(1); }
.f6 img { filter: saturate(2.5); }
.f7 img { filter: hue-rotate(120deg); }
.f8 img { filter: invert(1); }
.f9 img { filter: opacity(.35); }দশটি ছোট ছবি: প্রথমটি আসল, তারপর ঝাপসা, বেশি উজ্জ্বল, কড়া আলো-ছায়া, সাদা-কালো, পুরোনো বাদামি, ঝলমলে রং, লাল কোট সবুজাভ হয়ে যাওয়া (রঙের চাকা ১২০ ডিগ্রি ঘুরেছে), নেগেটিভের মতো উল্টো রং, আর প্রায় স্বচ্ছ। চেষ্টা করুন: .f7-এ 120deg-কে 180deg করুন, তারপর .f8-এ invert(1)-কে invert(.5) করুন — প্রায় পুরো ধূসর হয়ে যায় কেন, ভাবুন।
filter: opacity(.5) আর সাধারণ opacity: .5 দেখতে প্রায় এক; পার্থক্য হলো প্রথমটি filter-শিকলের একটি ধাপ, তাই ক্রমের সাথে বাঁধা। সাধারণ কাজে opacity property-ই যথেষ্ট।
filter মানে পুরো element. একটি কার্ডে filter: grayscale(1) দিলে শুধু ছবি নয়, কার্ডের লাল “অফার” ব্যাজ, নীল লিংক, সব সাদা-কালো হয়ে যায়। শুধু ছবিতে চাইলে selector-টি ছবির ওপর দিন (.card img). শুধু ব্যাকগ্রাউন্ড-ছবিতে filter চাইলে ছবিটিকে একটি ::before pseudo-element-এ রেখে সেটিতে filter দিন।
৩ · filter-এর শিকল — ক্রম কেন জরুরি, আর drop-shadow বনাম box-shadow
একাধিক ফাংশন লিখলে ব্রাউজার সেগুলোকে একটি কারখানার লাইনের মতো চালায়: প্রথম ফাংশনের ফল দ্বিতীয় ফাংশনে ঢোকে, তার ফল তৃতীয়তে। গণিতের ভাষায় এটি ফাংশনের composition — আর composition-এ ক্রম বদলালে ফল প্রায়ই বদলায়। যেমন কাপড় আগে রং করে তারপর ধুলে এক ফল, আগে ধুয়ে তারপর রং করলে আরেক। ধাপে ধাপে দেখুন:





- শুরুর ছবি। লাল কোট, নীল চেয়ার, পর্দায় চার্ট। এখনো কোনো filter নেই। এবার এই ছবিকে দুটি ফাংশনের লাইনে ঢোকাব।
- প্রথম ধাপ: grayscale(1). প্রতিটি পিক্সেলের রং বাদ দিয়ে শুধু উজ্জ্বলতা রাখা হলো। লাল কোট এখন মাঝারি ধূসর। এই ধূসর ছবিটিই পরের ফাংশনের “কাঁচামাল”।
- দ্বিতীয় ধাপ: তার ওপর sepia(1). sepia ধূসর ছবিকে বাদামি রঙে রাঙায় — পুরোনো দিনের পারিবারিক অ্যালবামের ছবির মতো। ফল: উষ্ণ বাদামি ছবি।
- ক্রম উল্টে দিলাম। এবার আগে sepia — ছবি বাদামি হলো, তারপর grayscale সেই বাদামি রংটাও মুছে দিল। ফল: পুরো ধূসর। একই দুটি শব্দ, শুধু ক্রম আলাদা — ফল সম্পূর্ণ ভিন্ন। শেষ ফাংশনের কথাই শেষ কথা।
- ছায়াও শিকলের অংশ। প্রথমে লাল
drop-shadowযোগ হলো, তারপরinvert(1)পুরো ফলটা উল্টে দিল — ছবির সাথে লাল ছায়াও উল্টে আকাশি (cyan) হয়ে গেল। ছায়া লাল রাখতে চাইলেinvert(1) drop-shadow(…)লিখতে হতো। নিয়ম: যেটা “শেষ রূপ”-এ অক্ষত চান, সেটি শিকলের শেষে রাখুন।
drop-shadow বনাম box-shadow — স্বচ্ছ লোগোয় পার্থক্য
পর্ব ২২-এ ছোট করে দেখেছেন: box-shadow element-এর আয়তাকার বাক্স ধরে ছায়া আঁকে, আর drop-shadow() আঁকা আসল আকৃতি ধরে — স্বচ্ছ পিক্সেল বাদ দিয়ে। স্বচ্ছ পটভূমির PNG বা WebP লোগো, SVG আইকন, বা clip-path দিয়ে কাটা আকৃতিতে পার্থক্যটা সবচেয়ে স্পষ্ট। নিচে এই সাইটের নিজের লোগো (স্বচ্ছ পটভূমির WebP) দিয়ে দেখুন, সাথে ক্রমের আরেকটি পরীক্ষা:
body { background: #eef3f8; }
img { width: 200px; margin: 14px; }
/* বাক্স ধরে ছায়া */
.bs { box-shadow: 6px 6px 6px rgb(0 0 0 / .45); }
/* আকৃতি ধরে ছায়া */
.ds { filter: drop-shadow(6px 6px 4px rgb(0 0 0 / .45)); }
/* ক্রম: আগে ছায়া, তারপর রং ঘোরানো */
.o1 { filter: drop-shadow(5px 5px 0 #f42a41) hue-rotate(200deg); }
/* ক্রম: আগে রং ঘোরানো, তারপর ছায়া */
.o2 { filter: hue-rotate(200deg) drop-shadow(5px 5px 0 #f42a41); }প্রথম লোগোর পেছনে একটি আয়তাকার ধূসর ছায়া — লোগোর স্বচ্ছ ফাঁকগুলো উপেক্ষা করে পুরো বাক্সের। দ্বিতীয়টির ছায়া প্রতিটি অক্ষর আর বর্গের কিনারা ধরে পড়েছে। নিচের সারিতে দুটি লোগোরই সবুজ অংশ রং ঘুরে গোলাপি হয়েছে, কিন্তু প্রথমটির ছায়াও রং বদলে নীলচে-সবুজ, আর দ্বিতীয়টির ছায়া খাঁটি লাল — কারণ সেখানে ছায়া যোগ হয়েছে রং ঘোরানোর পরে। চেষ্টা করুন: .ds-এ ছায়ার blur 4px-কে 0 করুন — ধারালো “স্টিকার” ধাঁচের ছায়া। তারপর .bs-এ border-radius: 12px; যোগ করুন — box-shadow বাঁক মানে, কিন্তু আকৃতি তবু ধরে না।
drop-shadow-এর দুটি সীমা। এক — এতে spread আর inset নেই, আর কমা দিয়ে কয়েকটি ছায়া দেওয়া যায় না; চাইলে drop-shadow(…) drop-shadow(…) শিকল লিখুন। দুই — এটি আঁকা প্রতিটি পিক্সেল ধরে, তাই বড় element-এ, বিশেষত animation-এ, দামি হতে পারে। সাধারণ আয়তাকার কার্ডে box-shadow-ই যথেষ্ট।
৪ · backdrop-filter — পেছনটা ঝাপসা করা ঘষা কাচ
বাসার বাথরুমের ঘষা কাচের জানালা মনে করুন: আলো আসে, ওপাশের রং বোঝা যায়, কিন্তু কোনো কিছু স্পষ্ট দেখা যায় না। backdrop-filter ঠিক এটাই করে। filter element-এর নিজের আঁকার ওপর কাজ করে; backdrop-filter কাজ করে element-এর পেছনে যা দেখা যাচ্ছে তার ওপর — শুধু element-এর সীমার ভেতরে। এখান থেকেই জনপ্রিয় glassmorphism নকশা: ঘষা কাচের মতো হেডার, মেনু বা কার্ড।
একটি শর্ত সবাই ভুলে যান: element-এর নিজের পটভূমি আধা-স্বচ্ছ হতে হবে। ব্রাউজার আগে পেছনের অংশটুকু ঝাপসা করে, তার ওপর element-এর নিজের ব্যাকগ্রাউন্ড আঁকে, তার ওপর লেখা। পটভূমি পুরো অস্বচ্ছ সাদা হলে ঝাপসা অংশটা ঢাকা পড়ে যায় — মনে হয় কাজই করছে না। আবার পুরো স্বচ্ছ হলে লেখার পেছনে শুধু ঝাপসা ছবি, contrast-এর কোনো নিশ্চয়তা নেই। মাঝামাঝি — যেমন ৫০–৭৫ শতাংশ অস্বচ্ছ সাদা বা কালো — সাধারণত ভালো কাজ করে।
.page {
height: 260px; overflow: auto;
font-family: sans-serif; border: 1px solid #ccc;
}
.page img { display: block; width: 100%; }
.page p { margin: 12px; line-height: 1.6; }
.glass {
position: sticky; top: 0;
height: 48px; margin-bottom: -48px; /* ছবির ওপরে ভাসবে */
display: flex; justify-content: space-between; align-items: center;
padding: 0 14px; font-size: 14px; color: #0b1a2a;
background: rgb(255 255 255 / .55);
backdrop-filter: blur(10px) saturate(1.4);
}
@supports not (backdrop-filter: blur(1px)) {
.glass { background: rgb(255 255 255 / .92); } /* fallback */
}ছবির ওপরের অংশে একটি আধা-সাদা হেডার; তার ভেতর দিয়ে নিচের মানুষ আর দেয়াল ঝাপসা, একটু বেশি রঙিন দেখা যাচ্ছে, অথচ গাঢ় লেখা পরিষ্কার পড়া যায়। বাক্সটি স্ক্রল করুন — হেডার sticky হয়ে ওপরে থাকে, আর নিচ দিয়ে যাওয়া লেখাও ঝাপসা হয়। চেষ্টা করুন: backdrop-filter-এর লাইনটি মুছে দিন — একই আধা-সাদা পটভূমিতে এখন পেছনের ছবির রেখা লেখার সাথে জট পাকায়, পড়া কঠিন। তারপর পটভূমির .55-কে .1 করুন — কাচ বেশি স্বচ্ছ, লেখার contrast দুর্বল।
সাপোর্ট, fallback আর তিনটি সাবধানতা
backdrop-filter প্রথম এনেছিল Apple-এর Safari, অনেক বছর শুধু -webkit-backdrop-filter উপসর্গ দিয়ে। উপসর্গ ছাড়া রূপটি সব প্রধান ব্রাউজারে আসে ২০২৪ সালে, তাই এটি Baseline Newly available. খুব পুরোনো iPhone-এর Safari সমর্থন করতে চাইলে উপসর্গওয়ালা লাইনটিও পাশাপাশি রাখা যায়; নতুন প্রজেক্টে উপসর্গ ছাড়া রূপই মূল। আর সবসময় এমন একটি fallback রাখুন যাতে ইফেক্ট না থাকলেও লেখা পড়া যায় — উপরের উদাহরণের @supports not অংশ ঠিক সেই কাজ করে (প্রায় অস্বচ্ছ পটভূমি)। এটাই progressive enhancement: সবাই কাজের জিনিস পান, নতুন ব্রাউজার পায় বাড়তি সৌন্দর্য।
- পাঠযোগ্যতা: blur ছবির রেখা নরম করে, কিন্তু উজ্জ্বল আর গাঢ় অংশ থেকেই যায়। তাই কাচের রং আর অস্বচ্ছতা এমন রাখুন যাতে সবচেয়ে খারাপ জায়গাতেও 4.5:1 থাকে (contrast, পর্ব ২০).
- পারফরম্যান্স: প্রতিটি ফ্রেমে ব্রাউজারকে পেছনের অংশ পড়ে নিয়ে নতুন করে ঝাপসা করতে হয়। sticky হেডারে এর মানে স্ক্রলের প্রতিটি মুহূর্তে কাজ। বড় blur ব্যাসার্ধ আর বড় এলাকা খরচ বাড়ায়।
- লুকোনো ফাঁদ: কাচের element-এর কোনো পূর্বপুরুষে
filter,opacity-র মান 1-এর কম,maskবাclip-pathথাকলে অনেক ক্ষেত্রে কাচ শুধু সেই পূর্বপুরুষের ভেতরের জিনিস ঝাপসা করে — তার বাইরের পাতা নয়। “blur কাজ করছে না” মনে হলে DevTools-এ ওপরের element-গুলো একবার দেখুন।
৫ · Blend mode — রং মেশানোর গণিত, duotone আর isolation
স্বাভাবিকভাবে একটি অস্বচ্ছ element তার নিচের সবকিছু ঢেকে দেয়। আধা-স্বচ্ছ হলে দুটি রং ওজন অনুযায়ী মেশে — এটুকু আমরা জানি। Blend mode আরেকটি প্রশ্নের উত্তর দেয়: ওপরের রং (source) আর নিচের রং (backdrop) — এই দুটি সংখ্যাকে কোন গাণিতিক সূত্রে মিলিয়ে নতুন রং হবে? Photoshop-এর “Multiply”, “Screen” নামগুলো চেনা লাগলে ঠিক — CSS-এ সেই একই সূত্র।
CSS-এ দুটি property:
mix-blend-mode— পুরো element (লেখা, ছবি, সব) তার নিচের পাতার সাথে মেশে।background-blend-mode— একটি element-এর নিজের ব্যাকগ্রাউন্ড স্তরগুলো (ছবি, gradient, রং) একে অপরের সাথে মেশে; বাইরের কিছুর সাথে নয়।
সূত্রগুলো বোঝার জন্য প্রতিটি রঙের চ্যানেলকে 0 (কালো) থেকে 1 (পূর্ণ উজ্জ্বল)-এর একটি সংখ্যা ভাবুন। নিচে সাদা পটভূমিতে একটি হলুদ আর একটি নীল বৃত্ত — নীলটির blend mode বদলে দেখুন:
- normal — কোনো মেশানো নেই। নীল বৃত্ত হলুদের ওপরে বসে তাকে ঢেকে দিয়েছে। ফল = ওপরের রং। এটাই ডিফল্ট।
- multiply — দুটি সংখ্যা গুণ। ফল = নিচ × ওপর। 1-এর চেয়ে ছোট দুটি সংখ্যা গুণ করলে ছোট হয়, তাই ফল সবসময় দুটোর চেয়ে গাঢ় — হলুদ আর নীলের মিলনে গাঢ় সবুজ। সাদা (1) দিয়ে গুণ করলে কিছু বদলায় না, তাই সাদা পটভূমিতে নীল বৃত্তের বাকি অংশ নীলই থাকে। স্বচ্ছ কাগজে দুটি রঙিন কালি একটির ওপর আরেকটি ছাপলে যা হয় — এজন্যই সাদা পটভূমির লোগো multiply দিলে সাদা অংশটা “উধাও” হয়ে যায়।
- screen — উল্টো দিক থেকে গুণ। ফল = 1 − (1 − নিচ) × (1 − ওপর)। দুটি প্রজেক্টরের আলো এক পর্দায় ফেলার মতো — ফল সবসময় উজ্জ্বল। এখানে গাঢ় নীল পটভূমিতে দেখাচ্ছি, কারণ কালো (0) দিয়ে screen করলে কিছুই বদলায় না; মিলনের জায়গাটা প্রায় সাদাটে ক্রিম রঙের। সাদার ওপর screen করলে সবকিছু সাদা হয়ে যেত।
- overlay — নিচের রং দেখে সিদ্ধান্ত। নিচের চ্যানেল অর্ধেকের কম (গাঢ়) হলে multiply, বেশি (হালকা) হলে screen. ফল: নিচের ছবির আলো-ছায়া বজায় রেখে ওপরের রং চাপানো। সাদা পটভূমিতে নীল বৃত্ত পুরো মুছে গেছে (সাদার ওপর screen মানে সাদা), আর উজ্জ্বল হলুদের ওপরেও রং প্রায় একই থাকে। overlay-এর প্রভাব সবচেয়ে বেশি মাঝারি আলোর জায়গায় — তাই ছবির আলো-ছায়া অক্ষত রেখে রঙিন আভা দিতে এটি জনপ্রিয়।
- difference — বিয়োগ, চিহ্ন বাদ। ফল = |নিচ − ওপর|। সাদার ওপর যেকোনো রং তার উল্টো রং হয়ে যায় (সাদা − নীল = কমলা), হলুদের ওপর নীল মিলে বেগুনি-গোলাপি, কালোর ওপর কিছুই বদলায় না, আর একই রং দুটি মিললে কালো। এজন্যই সাদা-কালো দুই ভাগের পটভূমিতে
differenceদেওয়া সাদা লেখা সবসময় দেখা যায় — কালো অংশে সাদা, সাদা অংশে কালো।
আরও কিছু মোড আছে — darken ও lighten (প্রতিটি চ্যানেলে ছোট বা বড়টি নেওয়া), color-dodge, color-burn, hard-light, soft-light, exclusion, আর চারটি রঙ-ভিত্তিক মোড hue, saturation, color, luminosity. সব মিলিয়ে ষোলোটি প্রচলিত মান; mix-blend-mode আর background-blend-mode দুটোই Baseline Widely available.
duotone — দুই রঙের ছবি
Duotone মানে ছবির অন্ধকার অংশ এক রঙে আর উজ্জ্বল অংশ আরেক রঙে — পোস্টার আর ব্যানারে খুব চলে, কারণ যেকোনো ছবিকে ব্র্যান্ডের রঙে মিলিয়ে নেওয়া যায়। কৌশলটি তিন ধাপের: (১) ছবিকে grayscale করুন, (২) একটি হালকা রঙের পটভূমির ওপর multiply করুন — সাদা অংশ সেই হালকা রং নেয়, কালো কালোই থাকে, (৩) ওপরে একটি গাঢ় রঙের স্তর lighten দিয়ে বসান — কালো অংশ গাঢ় রংটি নেয়। পাশে একটি ব্যানারে background-blend-mode দিয়ে ছবিকে রঙিন আভা দিয়ে লেখার পটভূমি বানানো হয়েছে:
.duo {
position: relative; margin: 0 0 14px; width: 320px;
background: #f4c83c; /* উজ্জ্বল অংশের রং */
isolation: isolate;
}
.duo img {
display: block; width: 100%;
filter: grayscale(1) contrast(1.1);
mix-blend-mode: multiply;
}
.duo::after {
content: ""; position: absolute; inset: 0;
background: #003c28; /* অন্ধকার অংশের রং */
mix-blend-mode: lighten;
}
.banner {
padding: 40px 16px 14px; color: white; font-family: sans-serif;
background: url("../image/bangladesh-startup-revolution.jpg") center / cover,
#1f3a93;
background-blend-mode: multiply;
}
.banner h2, .banner p { margin: 0; }ওপরের ছবিতে এখন মাত্র দুটি রং — ছায়া গাঢ় সবুজ, আলো সোনালি হলুদ; মানুষ আর পর্দা পরিষ্কার চেনা যায়। নিচের ব্যানারে ছবিটি নীল রঙের সাথে গুণ হয়ে গাঢ় নীল আভা পেয়েছে, তাই সাদা লেখা পড়া যায়। চেষ্টা করুন: #f4c83c-কে #ff8fb1 (গোলাপি) আর #003c28-কে #2a0a4a (গাঢ় বেগুনি) করুন — একেবারে অন্য মেজাজের পোস্টার। তারপর .banner-এ multiply-কে luminosity করুন — নীল পটভূমিতে ছবির শুধু আলো-ছায়া বসে, অন্য রকম আভা।
duotone-এর গোপন শর্ত: অন্ধকারের রংটির প্রতিটি চ্যানেল (লাল, সবুজ, নীল) উজ্জ্বলের রংটির চেয়ে ছোট হতে হবে। নাহলে lighten উজ্জ্বল অংশেও গাঢ় রঙের কোনো চ্যানেল তুলে আনবে, আর ছবি ঘোলাটে হবে। #003c28 (0, 60, 40) আর #f4c83c (244, 200, 60) — প্রতিটি সংখ্যায় প্রথমটি ছোট, তাই ফল পরিষ্কার।
isolation — মেশানো কোথায় থামবে (পর্ব ২৪-এর স্মৃতি)
mix-blend-mode element-কে তার নিচের সবকিছুর সাথে মেশায় — যতক্ষণ না একটি stacking context-এর সীমায় পৌঁছায়। উপরের duotone-এ .duo-তে isolation: isolate দিয়েছি যাতে ছবি শুধু হলুদ পটভূমির সাথে মেশে, পাতার বাকি অংশের সাথে নয়। পর্ব ২৪-এ isolation-কে z-index আটকে রাখার হাতিয়ার হিসেবে দেখেছিলেন; কিন্তু এটি আসলে এসেছিল Compositing and Blending spec থেকে, ঠিক এই “মেশানোর গণ্ডি” টানার জন্য।
.stripes {
padding: 12px; font-family: sans-serif;
background: linear-gradient(90deg, #111 50%, #fff 50%);
}
.diff {
margin: 0 0 12px; font-size: 34px; color: white;
mix-blend-mode: difference;
}
.card { margin: 8px 0; padding: 10px; color: #999;
border: 2px solid #888; }
.stamp { padding: 4px 8px; background: #f4b400;
mix-blend-mode: multiply; }
.iso { isolation: isolate; }বাঁ অর্ধেক কালো, ডান অর্ধেক সাদা পটভূমি। শিরোনামটি কালো অংশে সাদা, সাদা অংশে কালো — difference নিজে থেকে উল্টে দেয়। প্রথম কার্ডের হলুদ “multiply” ছাপটি কালো অংশে বসে প্রায় কালো হয়ে গেছে, কারণ সে কার্ড পেরিয়ে পাতার কালো পটভূমির সাথে মিশেছে (কার্ডের নিজের কোনো পটভূমি নেই)। দ্বিতীয় কার্ডে isolation: isolate থাকায় ছাপটির মেশার জগৎ কার্ডের ভেতরেই শেষ — সেখানে কিছু নেই, তাই ছাপ খাঁটি হলুদ। চেষ্টা করুন: .iso-র বদলে প্রথম কার্ডে background: white; দিন — এবার ছাপ সাদার সাথে মিশে হলুদই থাকে, কারণ নিচে এখন সাদা।
৬ · clip-path — কাঁচি দিয়ে আকৃতি কাটা
clip-path একটি রেখা টানে: রেখার ভেতরে element পুরো দেখা যায়, বাইরে একেবারেই না। আকৃতি দেওয়া হয় কয়েকটি basic shape ফাংশন দিয়ে, যাদের মাপ সাধারণত element-এর border-box ধরে হিসাব হয়:
| ফাংশন | উদাহরণ | মানে |
|---|---|---|
circle() | circle(40% at 50% 50%) | ব্যাসার্ধ আর কেন্দ্র; at না দিলে মাঝখানে |
ellipse() | ellipse(45% 30%) | আড়াআড়ি আর খাড়া দুটি ব্যাসার্ধ |
inset() | inset(10px 20px round 16px) | চার দিক থেকে কতটা ভেতরে কাটা (margin-এর মতো ক্রম), round দিয়ে গোল কোণ |
polygon() | polygon(50% 0, 100% 100%, 0 100%) | বিন্দুর তালিকা — প্রতিটি “x y”, কমা দিয়ে আলাদা; শেষ বিন্দু নিজে থেকে প্রথমটির সাথে জোড়া লাগে |
path() | path("M 0 0 L …") | SVG-র path ভাষা; বাঁকা আকৃতি সম্ভব, কিন্তু মাপ পিক্সেলে বাঁধা |
সবচেয়ে নমনীয় polygon(). এর বিন্দুগুলো element-এর ওপর-বাঁ কোণ থেকে মাপা হয় — 0 0 ওপর-বাঁ, 100% 0 ওপর-ডান, 100% 100% নিচ-ডান। এবার একটি “দামের ট্যাগ” বা তীর-আকৃতির ব্যাজ বিন্দু ধরে ধরে বানাই। ড্যাশ দেওয়া রেখাটি element-এর আসল বাক্স:
clip-path: none;
clip-path: polygon(0 0, 75% 0, 0 100%);
clip-path: polygon(0 0, 75% 0, 100% 50%, 0 100%);
clip-path: polygon(0 0, 75% 0, 100% 50%, 75% 100%, 0 100%);
clip-path: polygon(0 0, 75% 100%, 100% 50%, 75% 0, 0 100%);
- শুরু: কোনো কাটা নেই। সবুজ-নীল gradient-এর একটি সাধারণ আয়তক্ষেত্র, ২৪০ × ১১০ পিক্সেল। এর চার কোণ:
0 0,100% 0,100% 100%,0 100%. শতাংশ দিলে আকৃতি element-এর মাপের সাথে বড়-ছোট হবে। - তিনটি বিন্দু — ত্রিভুজ। ওপর-বাঁ কোণ, ওপরের রেখার ৭৫ শতাংশ, আর নিচ-বাঁ কোণ। ব্রাউজার বিন্দুগুলো ক্রম অনুযায়ী সরলরেখায় জোড়ে, আর শেষটিকে প্রথমটির সাথে জুড়ে আকৃতি বন্ধ করে। ভেতরের অংশ দেখা যায়, বাকি সব কাটা।
- চতুর্থ বিন্দু — ডান কিনারার মাঝখান।
100% 50%যোগ করলাম ৭৫%-এর পরে। এখন ওপরের রেখা থেকে একটি তির্যক রেখা ডান কিনারার মাঝে গিয়ে সেখান থেকে সোজা নিচ-বাঁ কোণে নামে — তীরের মাথা তৈরি হচ্ছে। - পঞ্চম বিন্দু — আকৃতি সম্পূর্ণ।
75% 100%যোগ হলো, ফলে নিচের রেখাটিও সমান্তরাল হলো। এই পাঁচ বিন্দুর ট্যাগ অনলাইন দোকানের “৳ ৪৫০” দামের ব্যাজ বা ধাপে ধাপে চলা প্রগ্রেস-বারে খুব চলে। - ক্রম বদলালে? একই পাঁচটি বিন্দু, শুধু দ্বিতীয় আর চতুর্থটির জায়গা বদল। রেখাগুলো এখন একে অপরকে কেটে যায়, ফলে প্রজাপতির মতো অদ্ভুত আকৃতি। polygon-এ বিন্দুর ক্রমই আকৃতি — ঘড়ির কাঁটার দিকে (বা উল্টো দিকে) একটানা ঘুরে বিন্দু লিখুন।
এবার আসল ছবিতে চারটি আকৃতি। শেষ ছবিটির সাথে একটি গুরুত্বপূর্ণ কৌশলও দেখুন — কাটা আকৃতিতে ছায়া:
body { background: #eef3f8; }
.s {
width: 140px; aspect-ratio: 1; object-fit: cover;
margin: 8px; vertical-align: middle;
}
.c1 { clip-path: circle(50%); }
.c2 { clip-path: ellipse(48% 32% at 50% 50%); }
.c3 { clip-path: inset(8% round 24px); }
/* ষড়ভুজ — ছায়া দিতে হলে filter বাবার ওপর */
.c4 { clip-path: polygon(50% 0, 100% 25%, 100% 75%,
50% 100%, 0 75%, 0 25%); }
.shadow-wrap {
display: inline-block;
filter: drop-shadow(4px 6px 4px rgb(0 0 0 / .45));
}চারটি ছবি: পূর্ণ বৃত্ত, চ্যাপ্টা উপবৃত্ত, চারদিক থেকে একটু কাটা গোল-কোণের বর্গ, আর একটি ষড়ভুজ, যার কিনারা ধরে নরম ছায়া। চেষ্টা করুন: filter-এর লাইনটি .shadow-wrap থেকে সরিয়ে সরাসরি .c4-এ দিন — ছায়া উধাও! কারণ একই element-এ ব্রাউজার আগে filter (ছায়া) আঁকে, তারপর clip-path কাটে — ছায়াটাও কাটা পড়ে যায়। তারপর .c1-এ circle(50%)-কে circle(35% at 30% 40%) করে দেখুন কেন্দ্র কীভাবে সরে।
কাটা অংশে ক্লিক পড়ে না, আর shape() নিয়ে একটি কথা
clip-path শুধু চোখের ব্যাপার নয়: কাটা অংশে মাউস বা আঙুল রাখলে সেটি element-এর ওপর পড়েছে বলে গণ্য হয় না — ব্রাউজারের hit testing কাটা আকৃতিই মানে। তাই বৃত্তাকার বোতামের কোণে ক্লিক করলে বোতাম চাপা পড়ে না। খুব সরু আকৃতির বোতাম তাই আঙুল দিয়ে চাপা কঠিন হয়ে যায় (WCAG 2.2-এর target size নিয়ম, পর্ব ৪৫)।
circle(), ellipse(), inset() আর polygon() দিয়ে clip-path Baseline Widely available; পুরোনো -webkit-clip-path উপসর্গ এখন আর লাগে না। path()-এর সমস্যা হলো মাপ পিক্সেলে বাঁধা, তাই রেসপন্সিভ হয় না। সেই সমস্যা মেটাতে নতুন shape() ফাংশন এসেছে, যেখানে বাঁকা রেখাও শতাংশে লেখা যায়। তবে এটি খুবই নতুন — কিছু ব্রাউজারে এসেছে, কিন্তু এই লেখার সময় সব প্রধান ব্রাউজারে নিশ্চিতভাবে নয় (Baseline নয়)। ব্যবহারের আগে Can I use দেখুন আর একটি সাধারণ polygon বা গোল কোণ fallback রাখুন। আর পুরোনো clip: rect(…) property দেখলে চিনে রাখুন — এটি পরিত্যক্ত (deprecated), শুধু absolute বাক্সে চলত।
clip-path animation — ধীরে ধীরে উন্মোচন
দুটি clip-path-এর মাঝে ব্রাউজার মসৃণভাবে বদলাতে পারে, যদি দুটি একই ধরনের আকৃতি হয় — circle থেকে circle, inset থেকে inset, বা সমান সংখ্যক বিন্দুর polygon থেকে polygon. ধরন না মিললে animation মসৃণ হয় না, হঠাৎ লাফ দেয়। পর্দা সরানোর মতো “reveal”, বা hover-এ ছোট বৃত্ত থেকে পুরো ছবি — দুটোই খুব জনপ্রিয় (transition আর @keyframes-এর বিস্তারিত পর্ব ৩৮ আর ৩৯-এ):
<style>
img { display: block; width: 300px; margin-bottom: 12px; }
.wipe { animation: wipe 1.4s ease-out both; }
@keyframes wipe {
from { clip-path: inset(0 100% 0 0); }
to { clip-path: inset(0 0 0 0); }
}
.spot { clip-path: circle(20% at 50% 50%);
transition: clip-path .5s ease; }
.spot:hover, .spot:focus-visible { clip-path: circle(75% at 50% 50%); }
@media (prefers-reduced-motion: reduce) {
.wipe { animation: none; }
.spot { transition: none; }
}
</style>
<img class="wipe" src="../image/bangladesh-startup-revolution.jpg" alt="সভাকক্ষে উপস্থাপনার দৃশ্য">
<img class="spot" tabindex="0" src="../image/bangladesh-startup-revolution.jpg" alt="একই দৃশ্য, মাউস রাখলে পুরোটা দেখা যায়">প্রিভিউ খোলার সাথে সাথে প্রথম ছবিটি বাঁ থেকে ডানে পর্দা সরানোর মতো উন্মোচিত হয়। দ্বিতীয়টিতে শুধু মাঝখানে একটি বৃত্ত — মাউস রাখলে (বা Tab চেপে focus দিলে) বৃত্ত বড় হয়ে পুরো ছবি দেখায়। যাঁরা অপারেটিং সিস্টেমে “motion কমাও” সেটিং চালু রেখেছেন, তাঁদের জন্য prefers-reduced-motion অংশে animation বন্ধ। চেষ্টা করুন: inset(0 100% 0 0)-কে inset(0 0 100% 0) করুন — এবার ওপর থেকে নিচে খোলে। তারপর .spot:hover-এর circle(…)-কে inset(0) করুন — ধরন না মেলায় মসৃণ বদলের বদলে লাফ দেবে। (animation আবার দেখতে কোডে যেকোনো কিছু বদলান — প্রিভিউ নতুন করে চলবে।)
৭ · mask — gradient আর ছবি দিয়ে নরম কিনারা
clip-path-এর রেখা ধারালো: প্রতিটি পিক্সেল হয় ভেতরে, নয় বাইরে। কিন্তু নকশায় প্রায়ই চাই কিনারা ধীরে ধীরে মিলিয়ে যাক — লম্বা লেখার শেষে “আরও পড়ুন”-এর আগে আবছা হয়ে যাওয়া, ছবির চারপাশ নরমভাবে মিশে যাওয়া। এর জন্য mask. mask-এর জন্য একটি ছবি দিতে হয় — আসল ছবির ফাইল, SVG বা gradient — আর সেই ছবির প্রতিটি পিক্সেলের স্বচ্ছতা (alpha) বলে দেয় element-এর সেই জায়গা কতটা দেখা যাবে:
mask-image: linear-gradient(black 60%, transparent)mask-এর রং কোনো ব্যাপার নয় — black, red বা #006a4e, অস্বচ্ছ হলে সবই এক। (ডিফল্ট mask-mode হলো ছবির alpha দেখা; চাইলে mask-mode: luminance দিয়ে উজ্জ্বলতা দেখতে বলা যায়, তখন সাদা = দেখা যায়, কালো = লুকায় — SVG-র পুরোনো mask এভাবেই কাজ করত।) mask-এর বাকি property-গুলো পর্ব ২২-এর background-এর যমজ: mask-size, mask-position, mask-repeat, আর shorthand mask. নিচে তিনটি প্রচলিত ব্যবহার:
body { font-family: sans-serif; }
/* ১. লেখার শেষ আবছা হয়ে মিলিয়ে যায় */
.fade {
width: 320px; height: 90px; overflow: hidden; line-height: 1.6;
mask-image: linear-gradient(to bottom, black 40%, transparent);
}
/* ২. ছবির চারপাশ নরম — radial gradient mask */
.soft {
display: block; width: 300px; margin: 10px 0;
mask-image: radial-gradient(ellipse, black 45%, transparent 72%);
}
/* ৩. SVG আকৃতিকে mask — ছবি তারার ভেতরে */
.star {
width: 150px; aspect-ratio: 1;
background: url("../image/bangladesh-startup-revolution.jpg") center / cover;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 3 62 37h36L69 59l11 36-30-22-30 22 11-36L2 37h36z'/%3E%3C/svg%3E") center / contain no-repeat;
}প্রথম অনুচ্ছেদের নিচের দিকের লাইনগুলো ধীরে ধীরে মিলিয়ে গেছে — যেন “বাকিটা পড়তে ক্লিক করুন”। তারপর একটি ছবি, যার চারপাশ ডিম্বাকৃতিতে নরমভাবে সাদা পটভূমিতে মিশেছে। সবশেষে একটি তারা, যার ভেতরে সভাকক্ষের ছবি — এখানে mask হিসেবে একটি ছোট SVG দেওয়া হয়েছে, যার কালো তারা-আকৃতির অংশ অস্বচ্ছ। চেষ্টা করুন: .fade-এ black 40%-কে black 80% করুন — আবছা অংশ ছোট হয়। তারপর .soft-এ ellipse-কে circle আর 72%-কে 50% করুন। চাইলে .star-এ no-repeat-এর বদলে repeat আর contain-এর বদলে 50px দিন — ছোট ছোট তারার টালি।
সাপোর্টের ইতিহাস: -webkit-mask থেকে Baseline
CSS mask প্রথম আনে WebKit, ২০০৮ সালের দিকে, -webkit-mask-image নামে — spec তৈরির অনেক আগে। Chrome ছিল WebKit-ভিত্তিক, তাই সেখানেও বহু বছর শুধু উপসর্গওয়ালা রূপ চলত, আর Firefox চালাত spec-এর উপসর্গ-ছাড়া রূপ। ফলে একসময় একই কথা দুবার লেখা নিয়ম হয়ে দাঁড়ায়। ২০২৩ সালের শেষ দিকে Chrome ও Edge উপসর্গ ছাড়া পূর্ণ mask চালু করলে এটি সব প্রধান ব্রাউজারে আসে — Baseline 2023. আজ নতুন কোডে উপসর্গ ছাড়া mask-image লিখুন। পুরোনো ব্রাউজার (বিশেষত কয়েক বছর আপডেট না হওয়া ফোন) নিয়ে চিন্তা থাকলে উপসর্গওয়ালা লাইনটি পাশে রাখতে পারেন। আর মনে রাখুন, mask না চললে element পুরো দেখা যায় — তাই mask এমন জায়গায় দিন, যেখানে না চললেও পাতা ভাঙে না।
ছবি-ফাইল দিয়ে mask, আর একটি সার্ভারের শর্ত। স্বচ্ছ পটভূমির PNG, WebP বা SVG ফাইলও mask হতে পারে: mask: url("logo.svg") center / contain no-repeat; — পটভূমির রং তখন লোগোর আকার নেয়, রং বদলালেই আইকনের রং বদলায় (পর্ব ৪৪)। তবে spec অনুযায়ী mask-এর ছবি CORS নিয়মে আনা হয়: অন্য ডোমেইন বা CDN থেকে mask-এর ছবি নিলে সেই সার্ভারকে অনুমতির header পাঠাতে হয়, নাহলে mask কাজ করে না। নিজের সাইটের ফাইল বা data: URL-এর ছোট SVG এই ঝামেলা এড়ায়।
আরও গভীরে: Filter Effects spec ক্রমটি নির্দিষ্ট করে দিয়েছে: element আর তার সব সন্তান আগে একটি আলাদা অদৃশ্য “ক্যানভাসে” আঁকা হয়, তারপর সেই ছবিতে প্রথমে filter, তারপর clip-path, তারপর mask, তারপর opacity প্রয়োগ হয়, আর শেষে blend mode মেনে ফলটি নিচের পাতার সাথে মেশে। এজন্যই একই element-এ drop-shadow আর clip-path দিলে ছায়া কাটা পড়ে, আর এজন্যই এই সব property (মান none বা ডিফল্ট না হলে) নতুন stacking context বানায় — আলাদা ক্যানভাস ছাড়া এই ক্রম মানা সম্ভব নয়। filter আরও একটি কাজ করে: ভেতরের position: fixed element-এর জন্য এটি নতুন containing block হয়ে যায় — filter দেওয়া বাক্সের ভেতরের “fixed” হেডার তাই জানালার বদলে সেই বাক্সের সাথে আটকে যায়, একটি পরিচিত বিভ্রান্তি।
৮ · ইফেক্টের দাম — অ্যাক্সেসিবিলিটি আর কম দামি ফোনের পারফরম্যান্স
অ্যাক্সেসিবিলিটি: সাজ যেন অর্থ না হয়ে দাঁড়ায়
- ছবির ওপর লেখার contrast: blend mode, ঘষা কাচ বা হালকা overlay — যা-ই দিন, লেখার পেছনের সবচেয়ে খারাপ জায়গায় contrast মাপুন। স্বয়ংক্রিয় টুল প্রায়ই ছবির ওপর contrast মাপতে পারে না; চোখ আর DevTools-এর রং-বাছাই প্যানেলই ভরসা।
- অর্থ ইফেক্টে লুকাবেন না: “স্টক শেষ” পণ্য শুধু
grayscaleকরে দেখালে বর্ণান্ধ পাঠক বা screen reader ব্যবহারকারী বুঝবেন না — পাশে লেখায় “স্টক শেষ” লিখুন। clip-path দিয়ে লুকানো অংশ কিন্তু screen reader ঠিকই পড়ে — কারণ চোখের আড়াল মানে অ্যাক্সেসিবিলিটি থেকে আড়াল নয়। এই বৈশিষ্ট্যটিই আধুনিক visually-hidden ক্লাসের ভিত্তি:clip-path: inset(50%)দিয়ে লেখা চোখ থেকে লুকিয়ে screen reader-এর জন্য রাখা হয় (পুরোনো কোডে একই কাজ করত পরিত্যক্তclip: rect(0 0 0 0)). - Forced colors: Windows-এর contrast থিমের মতো forced colors মোডে ব্রাউজার লেখা আর পটভূমির রং নিজের ছোট তালিকা থেকে বসায়, ছায়া বাদ দেয়। blend mode বা duotone দিয়ে বানানো “রঙিন” লেখা সেখানে অপ্রত্যাশিত দেখাতে পারে। DevTools-এর Rendering প্যানেলে forced-colors emulate করে দেখুন; দরকার হলে
@media (forced-colors: active)-এ ইফেক্টটি বন্ধ করুন। - স্বচ্ছতা কমানোর পছন্দ: iPhone, Mac আর Windows-এ “Reduce transparency” জাতীয় সেটিং আছে — অনেকের জন্য ঘষা কাচ পড়া কঠিন বা মাথাব্যথার কারণ। CSS-এ
prefers-reduced-transparencymedia feature এসেছে, কিন্তু এখনো সব প্রধান ব্রাউজারে নেই (Baseline নয়) — তাই এর ওপর নির্ভর না করে কাচকে শুরু থেকেই যথেষ্ট অস্বচ্ছ রাখুন। - ঝলকানি নয়:
hue-rotateবাinvertদ্রুত animate করলে পর্দা ঝলকায়। WCAG 2.2 সেকেন্ডে তিনবারের বেশি ঝলকানি এড়াতে বলে, কারণ তা কারও কারও খিঁচুনি (seizure) ঘটাতে পারে। reveal animation-এprefers-reduced-motionমানুন।
পারফরম্যান্স: ঢাকার ল্যাপটপে মসৃণ, গ্রামের ফোনে?
বাংলাদেশে অনেক পাঠক সাধারণ বা কম দামি Android ফোনে ওয়েব দেখেন — কম শক্তির প্রসেসর, কম শক্তির GPU, অল্প মেমরি। আপনার ডেভেলপমেন্ট ল্যাপটপে যা মাখনের মতো চলে, সেখানে তা স্পষ্টভাবে ঝাঁকুনি দিতে পারে। ইফেক্টগুলোর খরচ মোটামুটি এভাবে ভাবুন:
| ইফেক্ট | খরচ কেমন | কেন |
|---|---|---|
grayscale, brightness, sepia ইত্যাদি | সাধারণত কম | প্রতিটি পিক্সেলে আলাদা, সরল হিসাব |
clip-path (সাধারণ আকৃতি), gradient mask | সাধারণত কম থেকে মাঝারি | প্রতিটি পিক্সেল ভেতরে না বাইরে, বা কতটা — সরল প্রশ্ন |
blur(), drop-shadow() | মাঝারি থেকে বেশি, ব্যাসার্ধের সাথে বাড়ে | প্রতিটি পিক্সেলের জন্য আশেপাশের অনেক পিক্সেল মেশাতে হয় |
backdrop-filter: blur() | প্রায়ই সবচেয়ে বেশি | পেছনের অংশ পড়ে নিয়ে ঝাপসা করতে হয়, আর পেছনে কিছু নড়লেই আবার |
- স্থির ইফেক্ট বনাম animate করা ইফেক্ট: একবার আঁকা স্থির blur সাধারণত সমস্যা নয়। প্রতিটি ফ্রেমে বদলানো blur-এর মান (
blur(0)থেকেblur(20px)) বা স্ক্রলের সাথে চলা কাচ — সেখানেই খরচ। animation-এ যতটা পারেনopacityআরtransformবদলান (পর্ব ৩৮, ৪০)। - বিকল্প ভাবুন: ব্যাকগ্রাউন্ডের ছবি যদি স্থির হয়, তবে ছবিটিই আগে থেকে ঝাপসা করে সেভ করুন — CSS-এ blur-এর দরকারই নেই।
- মেপে দেখুন: DevTools-এর Performance প্যানেলে CPU throttling (৪ বা ৬ গুণ ধীর) চালু করে স্ক্রল রেকর্ড করুন; Rendering প্যানেলে “Frame Rendering Stats” আর “Paint flashing” দেখুন (পর্ব ৪৭, ৪৯)। সবচেয়ে ভালো পরীক্ষা: হাতের কাছের একটি সাধারণ দামের ফোনে নিজের পাতাটি খুলে স্ক্রল করা।
৯ · AI-এর যুগে — চোখ ধাঁধানো ইফেক্ট, কিন্তু যাচাই করা
“একটা glassmorphism কার্ড বানিয়ে দাও” বললে AI কয়েক সেকেন্ডে সুন্দর কোড দেয়। কিন্তু এই বিষয়ে AI-এর কিছু ভুল বারবার দেখা যায় — কারণ সে বহু বছরের পুরোনো টিউটোরিয়াল আর CodePen পড়ে শিখেছে, যেখানে সৌন্দর্য ছিল মূল লক্ষ্য, পাঠযোগ্যতা আর গতি নয়:
| AI প্রায়ই যা দেয় | সমস্যা | যা হওয়া উচিত |
|---|---|---|
শুধু -webkit-backdrop-filter, -webkit-mask, -webkit-clip-path | পুরোনো যুগের কোড; উপসর্গ ছাড়া রূপ বাদ পড়লে ভবিষ্যতে ভাঙতে পারে | উপসর্গ ছাড়া রূপ মূল; দরকার হলে উপসর্গ পাশে |
| প্রায় স্বচ্ছ কাচে সাদা লেখা, কোনো fallback নেই | উজ্জ্বল ছবির ওপর অপাঠ্য; সাপোর্ট না থাকলে আরও খারাপ | যথেষ্ট অস্বচ্ছ পটভূমি + @supports not |
পুরো পাতায় backdrop-filter: blur(40px), বা blur animate করা | কম দামি ফোনে স্ক্রল ঝাঁকুনি | ছোট এলাকা, ছোট ব্যাসার্ধ, স্থির ইফেক্ট |
একই element-এ clip-path আর filter: drop-shadow() | ছায়া কাটা পড়ে অদৃশ্য | ছায়া বাবার ওপর দিন |
“স্টক শেষ” বা “নিষ্ক্রিয়” বোঝাতে শুধু grayscale | অর্থ শুধু চেহারায়; screen reader জানে না | লেখা, disabled বা উপযুক্ত HTML |
ডার্ক মোডের জন্য পুরো পাতায় filter: invert(1) hue-rotate(180deg) | ছবি উল্টে যায়, রং ভুল, খরচও বেশি | CSS variable আর prefers-color-scheme (পর্ব ৩৬) |
AI-কে কাজ দেওয়ার সময়ই শর্তগুলো বলে দিন:
AI-এর লেখা ইফেক্টের CSS হাতে পেলে — যাচাইয়ের চেকলিস্ট
পরীক্ষা ও ইন্টারভিউতে — বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে:
filterআরbackdrop-filter-এর পার্থক্য? — প্রথমটি element-এর নিজের আঁকায় কাজ করে, দ্বিতীয়টি element-এর পেছনে যা দেখা যায় তার ওপর; দ্বিতীয়টির জন্য পটভূমি আধা-স্বচ্ছ লাগে।drop-shadow()আরbox-shadow-এর পার্থক্য? — box-shadow বাক্স ধরে, spread ও inset আছে; drop-shadow স্বচ্ছতা বাদ দিয়ে আসল আকৃতি ধরে।clip-pathআরmask-এর পার্থক্য? — clip-path ধারালো রেখায় হ্যাঁ/না কাটে; mask স্বচ্ছতার মাত্রা দিয়ে আংশিক দেখায়, তাই নরম কিনারা সম্ভব।mix-blend-modeআরbackground-blend-mode? — প্রথমটি পুরো element-কে নিচের পাতার সাথে মেশায়; দ্বিতীয়টি একই element-এর ব্যাকগ্রাউন্ড স্তরগুলোকে নিজেদের মধ্যে।- filter-এ ফাংশনের ক্রম কি গুরুত্বপূর্ণ? — হ্যাঁ, বাঁ থেকে ডানে একটির ফল পরেরটিতে যায়;
grayscale(1) sepia(1)বাদামি, উল্টোটা ধূসর।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১Internet Explorer-এর filter: progid:… থেকে আজকের মানসম্মত filter — এই পথচলা থেকে ওয়েব কী শিখেছে?
১৯৯০-এর দশকের শেষ দিকে Microsoft Internet Explorer-এ একটি নিজস্ব filter property যোগ করে। এর মান ছিল অদ্ভুত লম্বা — progid:DXImageTransform.Microsoft.Alpha(Opacity=50) বা ছোট রূপে alpha(opacity=50). ভেতরে এটি Windows-এর DirectX গ্রাফিক্স ব্যবস্থাকে ডাকত। এ দিয়ে স্বচ্ছতা, ছায়া, ঝাপসা, এমনকি পাতা বদলানোর সময় ঝিলমিল ট্রানজিশনও করা যেত — সময়ের তুলনায় চমকপ্রদ। কিন্তু এটি চলত শুধু Windows-এর IE-তে। অন্য ব্রাউজারের জন্য আলাদা কোড লিখতে হতো, আর IE-র পুরোনো সংস্করণগুলো চলে যাওয়ার পরও বহু বছর CSS ফাইলে এই অদ্ভুত লাইনগুলো রয়ে যায়।
অন্যদিকে মানসম্মত পথে filter আসে SVG থেকে। SVG-র filter অসাধারণ শক্তিশালী — feGaussianBlur, feColorMatrix, feTurbulence-এর মতো “primitive” জোড়া দিয়ে প্রায় যেকোনো ইফেক্ট বানানো যায় — কিন্তু লিখতে জটিল। CSS-এর Filter Effects spec তাই দুটি স্তর দিল: সহজ কাজের জন্য blur(), grayscale()-এর মতো ছোট ফাংশন (যেগুলোর সংজ্ঞাই দেওয়া আছে সমতুল্য SVG filter দিয়ে), আর জটিল কাজের জন্য filter: url(#id) দিয়ে পূর্ণ SVG filter. অর্থাৎ নতুন কিছু উদ্ভাবন না করে বিদ্যমান, পরীক্ষিত মডেলকে সহজ ভাষায় খুলে দেওয়া হলো।
এখান থেকে তিনটি শিক্ষা। এক — একটি ব্রাউজারের নিজস্ব ফিচার যত চমৎকারই হোক, মান (standard) না হলে শেষ পর্যন্ত তা বোঝা হয়ে দাঁড়ায়। দুই — ভালো API নকশায় সহজ কাজ সহজ, কঠিন কাজ সম্ভব থাকে; CSS filter-এর দুই স্তর এর সুন্দর উদাহরণ। তিন — নামের সংঘাতও ইতিহাস বহন করে: IE-র filter আর মানসম্মত filter একই নামের property, তাই পুরোনো ব্রাউজারকে নতুন মান না বুঝে বাদ দিতে হতো — CSS-এর “না বুঝলে উপেক্ষা করো” নিয়ম এখানে রক্ষাকর্তা।
মূল উপলব্ধি: আজকের এক শব্দের grayscale(1)-এর পেছনে আছে একটি মালিকানাধীন পরীক্ষা, একটি জটিল কিন্তু মানসম্মত SVG ব্যবস্থা, আর দুটিকে সহজে মেলানোর নকশা। পুরোনো কোডে progid দেখলে নির্দ্বিধায় মুছে ফেলুন।
প্র ০২ঘষা কাচের নকশা বারবার ফিরে আসে কেন — Windows Vista থেকে iOS 7 হয়ে আজ পর্যন্ত? আর এর বিরুদ্ধে সমালোচনা কী?
২০০৭ সালে Windows Vista আনে “Aero Glass” — জানালার কিনারা আধা-স্বচ্ছ, পেছনের জিনিস ঝাপসা। এটি চালাতে বেশ শক্তিশালী গ্রাফিক্স কার্ড লাগত; দুর্বল কম্পিউটারে Windows নিজেই ইফেক্টটি বন্ধ করে সাধারণ চেহারায় চলত। পরে Windows 8 প্রায় সমতল নকশায় চলে যায়। ২০১৩ সালে Apple iOS 7-এ skeuomorphism ছেড়ে সমতল নকশা আনলেও Control Center আর নোটিফিকেশনের পেছনে ঝাপসা কাচ রাখে। ওয়েবে এর প্রতিধ্বনি হিসেবেই Safari প্রথম -webkit-backdrop-filter আনে। ২০২০ সালের দিকে ডিজাইনাররা এর নাম দেন “glassmorphism”, আর Windows-এর Fluent নকশার “Acrylic” আর “Mica” উপকরণও একই চিন্তার। ২০২৫ সালে Apple তাদের সব প্ল্যাটফর্মে “Liquid Glass” নামে আরও গভীর কাচ-ধাঁচের নকশা ঘোষণা করে — আর সাথে সাথে পাঠযোগ্যতা নিয়ে ব্যাপক আলোচনা শুরু হয়।
কেন বারবার ফিরে আসে? কারণ কাচ একটি সমস্যার সুন্দর সমাধান: ওপরে ভাসা প্যানেল (মেনু, হেডার, নোটিফিকেশন) দেখেও ব্যবহারকারী বুঝতে পারেন নিচে কী আছে, তিনি কোথায় আছেন — প্রেক্ষাপট হারান না। এটি গভীরতা আর স্তরের অনুভূতিও দেয়, সমতল নকশায় যা প্রায়ই হারিয়ে যায়।
সমালোচনাও একই রকম পুরোনো। প্রথমত পাঠযোগ্যতা: লেখার পেছনের রং নির্ভর করে নিচে কী আছে তার ওপর, তাই contrast অনিশ্চিত, আর স্ক্রল বা ভিডিওর সাথে প্রতি মুহূর্তে বদলায়। কম দৃষ্টিশক্তির মানুষ, রোদে ফোন দেখা মানুষ বা মনোযোগের সমস্যা আছে এমন মানুষের জন্য এটি বাড়তি বোঝা। এজন্যই iOS, macOS আর Windows-এ “Reduce transparency” জাতীয় সেটিং আছে, আর CSS-এ prefers-reduced-transparency media feature প্রস্তাবিত হয়েছে (এখনো সব ব্রাউজারে নয়)। দ্বিতীয়ত খরচ: Vista-র সময়ে যেমন, আজও কম শক্তির যন্ত্রে ঝাপসা কাচ ব্যাটারি আর গতি খায়।
মূল উপলব্ধি: নকশার ফ্যাশন ঘুরে ফিরে আসে, কিন্তু পাঠযোগ্যতা আর গতির নিয়ম বদলায় না। কাচকে এমনভাবে বানান যেন blur মুছে দিলেও পাতাটি পুরো কাজের থাকে — তখন blur শুধু বাড়তি সৌন্দর্য।
প্র ০৩Blend mode-এর সূত্রগুলো কোথা থেকে এল? “স্তর একটির ওপর আরেকটি বসানো”-র গণিত কম্পিউটার গ্রাফিক্সে কেন এত গুরুত্বপূর্ণ?
শুরুটা চলচ্চিত্রে। ১৯৮৪ সালে Lucasfilm-এর দুই গবেষক Thomas Porter আর Tom Duff SIGGRAPH সম্মেলনে “Compositing Digital Images” নামে একটি গবেষণাপত্র প্রকাশ করেন। প্রশ্ন ছিল: আলাদা আলাদা আঁকা বা তোলা ছবির টুকরো — একটি স্পেসশিপ, পেছনের তারা, সামনের ধোঁয়া — কীভাবে নির্ভুলভাবে জোড়া লাগানো যায়, যখন প্রতিটির কিছু অংশ স্বচ্ছ বা আধা-স্বচ্ছ? তাঁদের উত্তর: প্রতিটি পিক্সেলের সাথে রঙের পাশাপাশি একটি স্বচ্ছতার সংখ্যা (alpha) রাখা, আর রংকে আগেই alpha দিয়ে গুণ করে রাখা (premultiplied alpha). এরপর “source over destination”-এর মতো বারোটি পরিষ্কার নিয়মে যেকোনো দুটি স্তর মেলানো যায়। এই Porter-Duff নিয়মগুলো আজও প্রায় সব গ্রাফিক্স সফটওয়্যার, অপারেটিং সিস্টেম আর ব্রাউজারের ভিত্তি; CSS-এর সাধারণ ওপর-নিচে বসানো হলো “source-over”.
Porter-Duff বলে কোন অংশ দেখা যাবে; blend mode বলে দুটি রং মিললে কী রং হবে। Multiply, screen-এর মতো সূত্রগুলো এসেছে ছবি-সম্পাদনা আর ছাপাখানার অভিজ্ঞতা থেকে — multiply হলো স্বচ্ছ কালি একটির ওপর আরেকটি ছাপা, screen হলো দুটি আলো একসাথে ফেলা। Photoshop-এর মতো সফটওয়্যার এগুলোকে জনপ্রিয় করে, আর W3C-র Compositing and Blending spec সেই সূত্রগুলোই হুবহু সংজ্ঞায়িত করে, যাতে ডিজাইনারের ফাইল আর ব্রাউজারের ফল মেলে।
এখানে একটি সূক্ষ্ম বিষয়ও আছে — কোন রঙ-জগতে হিসাব হচ্ছে। CSS blend mode sRGB-র সংখ্যায় হিসাব হয়, যা মানুষের চোখের অনুভূতির সাথে সমান তালে চলে না (পর্ব ২০)। আর isolation-এর ধারণাও Porter-Duff-এর জগৎ থেকে: একটি দলের স্তরগুলো আগে নিজেদের মধ্যে মিশিয়ে একটি ছবি বানাও, তারপর সেই ছবিকে বাইরের সাথে মেলাও।
মূল উপলব্ধি: ব্রাউজারের প্রতিটি পাতা আসলে হাজারো স্তরের compositing — হলিউডের স্পেশাল ইফেক্টের জন্য তৈরি সেই একই গণিতে। blend mode বুঝলে আপনি শুধু CSS নয়, ছবি-সম্পাদনা আর ভিডিও-সম্পাদনার সফটওয়্যারকেও ভেতর থেকে বুঝবেন।
প্র ০৪গোল ছবি বানাতে border-radius + overflow: hidden, clip-path আর mask — তিনটিই পারে। কখন কোনটি বেছে নেবেন?
তিনটির ফল দেখতে এক, কিন্তু ভেতরের কাজ আর পার্শ্বফল আলাদা। border-radius বাক্সের নিজের আকৃতিই বদলায়: বর্ডার, ব্যাকগ্রাউন্ড, box-shadow, outline — সবাই সেই বাঁক মেনে চলে। ছায়াসহ গোল প্রোফাইল ছবি চাইলে এটিই সবচেয়ে সহজ আর সস্তা, আর এটি নতুন stacking context-ও তৈরি করে না। সীমাবদ্ধতা: শুধু গোল কোণ আর উপবৃত্ত — তারা বা ষড়ভুজ নয়।
clip-path যেকোনো বহুভুজ, বৃত্ত বা path-এ কাটে, আর animate করা যায় — reveal ইফেক্টের জন্য আদর্শ। কিন্তু এটি পুরো আঁকাকে কাটে, ছায়া ও outline-সহ: element-এর নিজের box-shadow বা focus-এর outline কাটা পড়ে যায়। clip-path দেওয়া বোতামের focus রিং দেখা না গেলে কিবোর্ড ব্যবহারকারী পথ হারান — তখন focus-এর সংকেত বাবার ওপর দিতে হয়। আর এর কিনারা সবসময় ধারালো।
mask সবচেয়ে নমনীয়: যেকোনো ছবির আকৃতি, আর নরম কিনারা। কিন্তু mask-এর ছবিও একটি সম্পদ — ফাইল হলে ডাউনলোড লাগে, অন্য ডোমেইন থেকে হলে CORS-এর শর্ত, আর ব্রাউজারকে প্রতিটি পিক্সেলে mask-এর মান পড়তে হয়।
সিদ্ধান্তের সহজ নিয়ম: গোল কোণ বা বৃত্ত → border-radius. সরলরেখার আকৃতি বা আকৃতি-বদলের animation → clip-path. নরম কিনারা, ফেড-আউট, বা জটিল ছবির আকৃতি → mask. আর তিনটির কোনোটিতেই অর্থ লুকাবেন না — কাটা অংশের লেখা screen reader ঠিকই পড়ে।
মূল উপলব্ধি: একই চেহারায় পৌঁছানোর একাধিক পথ থাকলে প্রশ্ন করুন — ছায়া, focus, animation, খরচ আর fallback-এ কী হয়? সবচেয়ে সরল যে হাতিয়ার কাজটা করে, সেটিই সাধারণত সঠিক।
প্র ০৫blur(4px) আর blur(40px)-এর খরচে এত পার্থক্য কেন? আর কম দামি ফোনের কথা ভেবে ইফেক্টের সিদ্ধান্ত কীভাবে নেবেন?
ব্রাউজারের blur মূলত Gaussian blur: প্রতিটি পিক্সেলের নতুন রং হলো তার আশেপাশের পিক্সেলগুলোর ওজনদার গড়, যেখানে কাছের পিক্সেলের ওজন বেশি, দূরেরটির কম — ঘণ্টার মতো বক্ররেখায়। CSS-এ blur()-এর মান সেই ঘণ্টার বিস্তার (standard deviation). বিস্তার বড় হলে প্রতিটি পিক্সেলের জন্য অনেক বেশি প্রতিবেশী দেখতে হয়। সরল হিসাবে খরচ ব্যাসার্ধের বর্গের সাথে বাড়ে; বাস্তবে ব্রাউজার চালাকি করে — আগে আড়াআড়ি, পরে খাড়া, দুই ধাপে blur করে, বা ছবি ছোট করে blur করে আবার বড় করে। তবু ব্যাসার্ধ আর এলাকা বাড়লে কাজ বাড়েই।
backdrop-filter-এ আরও একটি খরচ যোগ হয়: ব্রাউজারকে আগে element-এর পেছনের সবকিছু আঁকা শেষ করে সেই অংশটুকু পড়ে নিতে হয়, তারপর ঝাপসা করে, তারপর ওপরে element আঁকে। পেছনে কিছু নড়লে — স্ক্রল, ভিডিও, animation — পুরো প্রক্রিয়া প্রতিটি ফ্রেমে আবার। সেকেন্ডে ৬০ ফ্রেম মানে প্রতি ফ্রেমে মাত্র ১৬ মিলিসেকেন্ডের মতো সময়; শক্তিশালী GPU-তে যা সহজ, দুর্বল GPU-তে তা সময় ছাড়িয়ে যায়, আর ফ্রেম বাদ পড়ে ঝাঁকুনি দেখা দেয়।
সিদ্ধান্তের একটি কাঠামো: (১) দরকার আছে কি? ইফেক্টটি কি কোনো কাজ করছে (পেছনের প্রেক্ষাপট বোঝানো), না শুধু সাজ? (২) স্থির করা যায় কি? স্থির ব্যাকগ্রাউন্ডের ঝাপসা রূপ আগেই ছবিতে বানিয়ে রাখা যায়। (৩) ছোট করা যায় কি? ছোট এলাকা, ছোট ব্যাসার্ধ, animate নয়। (৪) ধীরে ধীরে যোগ — আগে অস্বচ্ছ, কাজের নকশা; তার ওপর @supports দিয়ে ইফেক্ট। (৫) মাপুন — DevTools-এ CPU throttling, আর আসল সাধারণ দামের ফোন। কারণ বাংলাদেশের মতো বাজারে আপনার পাঠকের বড় অংশ এই ধরনের ফোনেই পাতা খোলেন; ডেভেলপারের দামি ল্যাপটপ তাঁদের অভিজ্ঞতার প্রতিনিধি নয়।
মূল উপলব্ধি: প্রতিটি ইফেক্টের একটি অদৃশ্য দাম আছে, যা দেয় আপনার পাঠকের ফোন। সুন্দরের সিদ্ধান্ত তাই প্রকৌশলের সিদ্ধান্তও — মেপে, ছোট করে, আর সবার জন্য কাজের ভিত্তি রেখে।
অনুশীলন
প্রথমটিতে সামান্য CSS লিখবেন; বাকিগুলো দেখা আর ভাবার কাজ।
-
“স্টক শেষ” পণ্য-কার্ড: একটি অনলাইন দোকানের কার্ডে ছবি, নাম আর দাম আছে। পণ্যটি স্টকে না থাকলে ছবি সাদা-কালো আর একটু ফিকে হবে, ছবির নিচের কিনারা নরমভাবে মিলিয়ে যাবে, আর কার্ডে স্পষ্ট লেখায় “স্টক শেষ” থাকবে। HTML আর CSS লিখুন — কোনো অর্থ যেন শুধু ইফেক্টে না থাকে।
ইফেক্ট শুধু ছবিতে, অর্থ লেখায়:
<article class="card is-out"> <img src="shari.jpg" alt="লাল-সবুজ জামদানি শাড়ি"> <h3>জামদানি শাড়ি</h3> <p>৳ ৮,৫০০ · <strong class="badge">স্টক শেষ</strong></p> </article>.card img { display: block; width: 100%; } .card.is-out img { filter: grayscale(1) opacity(.7); mask-image: linear-gradient(black 70%, transparent); } .badge { color: #b3122e; } /* লাল, কিন্তু লেখাতেই অর্থ */এখানে
filterআরmaskএকই ছবিতে — কোনো সমস্যা নেই, কারণ কোনো ছায়া কাটা পড়ছে না। কিনতে না পারার বোতাম থাকলে তাতেdisabledদিন, শুধু ধূসর রং নয়। -
বাস্তব সাইটে কাচ খুঁজুন: যেকোনো বড় প্রযুক্তি কোম্পানির ওয়েবসাইট (অনেকের হেডার স্ক্রল করলে ঘষা কাচের মতো হয়) খুলে হেডারে ডান-ক্লিক করে Inspect করুন।
backdrop-filter-এর মান আর পটভূমির অস্বচ্ছতা কত? লাইনটির পাশের চেকবক্স তুলে দিলে কী বদলায়?-webkit-উপসর্গওয়ালা লাইনও আছে কি?সাধারণত দেখবেন blur-এর মান ছোট (প্রায় ১০ থেকে ৩০ পিক্সেলের মধ্যে), সাথে প্রায়ই
saturate()— যাতে ঝাপসা পটভূমি নিষ্প্রভ না দেখায়। পটভূমির রং মাঝারি অস্বচ্ছ, আর ভালো সাইটে blur বন্ধ করলেও লেখা পড়া যায় — অর্থাৎ পটভূমির রংটিই আসল ভরসা। অনেক সাইটে উপসর্গওয়ালা লাইনও পাবেন — পুরোনো Safari-র জন্য, বা কোনো build টুল (যেমন Autoprefixer, পর্ব ৫০) নিজে থেকে যোগ করেছে। -
forced colors আর reduced motion পরীক্ষা: DevTools-এর Rendering প্যানেলে “Emulate CSS media feature forced-colors”-কে
activeকরুন, তারপর এই পর্বের duotone আর difference লেখার লাইভ এডিটর দেখুন। এরপরprefers-reduced-motion: reduceemulate করে reveal-এর এডিটরটি দেখুন। কী থাকে, কী হারায়?forced colors মোডে লেখা আর পটভূমির রং সিস্টেমের রঙে বদলে যায়, তাই difference লেখার “উল্টে যাওয়া” কৌশল আর অর্থবহ থাকে না — কিন্তু লেখাটি সিস্টেম রঙে পড়া যায়, এটাই গুরুত্বপূর্ণ। ছবির ভেতরের পিক্সেল ব্রাউজার বদলায় না, তাই duotone ছবি সাধারণত ছবির মতোই থাকে। reduced motion চালু করলে প্রথম ছবিটি পর্দা-সরানো ছাড়াই সরাসরি দেখা যায়, আর বৃত্ত বড় হওয়া হঠাৎ হয় — তথ্য কিছুই হারায় না — লক্ষ্য এটাই।
-
ষড়ভুজ প্রোফাইল ছবির পরিকল্পনা: একজন ডিজাইনার চান টিম পেজে প্রতিটি সদস্যের ছবি ষড়ভুজ আকারে কাটা থাকবে, নিচে নরম ছায়া, আর মাউস রাখলে (বা কিবোর্ডে focus দিলে) ছবিটি ধীরে ধীরে রঙিন হবে (শুরুতে সাদা-কালো)। কোন property কোথায় দেবেন, আর কোন তিনটি ফাঁদ এড়াবেন?
গঠন: বাইরের
<a>বা<figure>-এfilter: drop-shadow(…), ভেতরের<img alt="নাম">-এclip-path: polygon(…)আরfilter: grayscale(1); hover আর:focus-visible-এgrayscale(0)সাথেtransition: filter .3s. তিনটি ফাঁদ: (১) ছায়া আর clip-path একই element-এ দিলে ছায়া কাটা পড়ে — তাই ছায়া বাবার ওপর। (২) clip-path focus-এর outline-ও কাটে — তাই focus দেখানোর outline বাইরের লিংক বা figure-এ দিন। (৩)blurনয়, শুধুgrayscaleanimate হচ্ছে — তুলনামূলক সস্তা, তবু অনেক ছবির গ্রিডে কম দামি ফোনে পরীক্ষা করুন, আরprefers-reduced-motion-এ transition বন্ধ রাখুন।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি element-এ filter, clip-path, mask, opacity আর mix-blend-mode সব থাকলে ব্রাউজার কোন ক্রমে কাজ করে — প্রথম থেকে শেষ পর্যন্ত সাজান (▲▼ চেপে সরান)
- element আর তার সব সন্তান একটি আলাদা স্তরে আঁকা
filterপ্রয়োগclip-pathদিয়ে কাটাmaskপ্রয়োগopacityপ্রয়োগmix-blend-modeমেনে নিচের পাতার সাথে মেশানো
একটি ছবিতে filter: sepia(1) grayscale(1); দিলে ছবিটি দেখতে কেমন হবে?
- বাদামি, পুরোনো অ্যালবামের ছবির মতো
- সম্পূর্ণ সাদা-কালো (ধূসর)
- অর্ধেক বাদামি, অর্ধেক ধূসর মেশানো রং
- ঘোষণাটি অবৈধ, তাই কোনো filter কাজ করবে না
একটি হেডারে backdrop-filter: blur(10px) দেওয়া হয়েছে, কিন্তু পেছনের ছবি একটুও ঝাপসা দেখা যাচ্ছে না। হেডারের background হলো #ffffff. সবচেয়ে সম্ভাব্য কারণ কী?
- blur-এর মান খুব ছোট
- উপসর্গ
-webkit-না দেওয়া - হেডারের পটভূমি পুরো অস্বচ্ছ, তাই ঝাপসা অংশটা ঢাকা পড়ছে
- হেডারটি
position: fixedনয়
একটি <img>-এ একসাথে clip-path: polygon(…) আর filter: drop-shadow(…) দেওয়া হলো। ছায়া দেখা যাচ্ছে না। ঠিক করার প্রচলিত উপায় কোনটি?
- drop-shadow ফিল্টারটি ছবির বাবা (wrapper) element-এ সরানো
- drop-shadow-এর বদলে
box-shadowদেওয়া - CSS-এ
filter-এর লাইনclip-path-এর আগে লেখা - ছবিতে
z-index: 10দেওয়া
mask-image: linear-gradient(to bottom, black 50%, transparent); দেওয়া একটি অনুচ্ছেদ দেখতে কেমন হবে?
- পুরো লেখা কালো হয়ে যাবে
- ওপরের অর্ধেক লুকাবে, নিচের অর্ধেক দেখা যাবে
- ঠিক মাঝখানে একটি ধারালো রেখায় নিচের অর্ধেক কাটা পড়বে
- ওপরের অর্ধেক পুরো দেখা যাবে, তারপর নিচের দিকে লেখা ধীরে ধীরে মিলিয়ে যাবে
সাদা পটভূমির একটি লোগো-ছবিকে হলুদ ব্যানারের ওপর বসালে সাদা চারকোনা অংশটা দেখা যায়। কোন mix-blend-mode দিলে সাদা অংশ “উধাও” হয়ে হলুদ দেখা যাবে, কিন্তু লোগোর গাঢ় অংশ থাকবে?
screenmultiplydifferencenormal
একটি কার্ডের ভেতরের ব্যাজে mix-blend-mode: multiply আছে, আর সেটি কার্ড পেরিয়ে পাতার গাঢ় ব্যাকগ্রাউন্ডের সাথেও মিশে যাচ্ছে। শুধু কার্ডের ভেতরে মেশানো সীমাবদ্ধ রাখতে কার্ডে কী দেবেন?
overflow: hiddenposition: relativeisolation: isolatebackground-blend-mode: normal
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- ইফেক্ট বসে আঁকার পরে: আগে filter, তারপর clip-path, mask, opacity, শেষে blend. কেউ layout বদলায় না, সবাই নতুন stacking context বানায়।
filter-এর ফাংশন বাঁ থেকে ডানে শিকলে চলে — ক্রম ফল বদলায়;drop-shadow()আকৃতি ধরে,box-shadowবাক্স।backdrop-filterপেছনটা ঝাপসা করে — পটভূমি আধা-স্বচ্ছ রাখুন,@supports notfallback দিন, contrast মাপুন; Baseline Newly available, কিন্তু খরচ বেশি।- Blend mode = রং মেশানোর সূত্র: multiply গাঢ় করে (সাদা উধাও), screen উজ্জ্বল, difference উল্টায়; duotone = grayscale + multiply + lighten;
isolation: isolateমেশানোর গণ্ডি টানে। clip-pathধারালো (circle, ellipse, inset round, polygon — বিন্দুর ক্রমই আকৃতি), একই ধরনের আকৃতির মধ্যে animate হয়;maskস্বচ্ছতা দিয়ে নরম কিনারা দেয়। কাটা অংশে ক্লিক পড়ে না, কিন্তু screen reader পড়ে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৪২ · স্ক্রল ইফেক্ট — scroll-snap, smooth scroll আর scroll-driven animationপরবর্তী পর্বস্ক্রলের সাথে চলা নকশা — ক্যারোসেল, reveal আর প্রগ্রেস বার।
- HTML ও CSS · কোর্স হোম৫৯টি পর্বপুরো কোর্সের রোডম্যাপ — প্রথম পেজ থেকে আধুনিক রেসপন্সিভ ডিজাইন।
- কম্পিউটার ও ICT · ছবি, শব্দ আর ভিডিওর ডেটাপাশের ট্র্যাকপিক্সেল, রঙের চ্যানেল আর স্বচ্ছতা (alpha) — filter আর blend mode-এর হিসাব বুঝতে।
- JavaScript · DOM-এর ভিত্তিগভীরে যানJavaScript দিয়ে class বদলে ইফেক্ট চালু-বন্ধ করা, বা clip-path-এর মান মাউসের সাথে বদলানো।