পপ-আপগুলি: তারা একটি পুনরুত্থান করছে!

ওপেন ইউআই উদ্যোগের লক্ষ্য হলো ডেভেলপারদের জন্য চমৎকার ইউজার এক্সপেরিয়েন্স তৈরি করা সহজ করে তোলা। এটি করার জন্য, আমরা ডেভেলপারদের সম্মুখীন হওয়া অধিক সমস্যাজনক প্যাটার্নগুলো মোকাবেলা করার চেষ্টা করছি। আমরা আরও উন্নত প্ল্যাটফর্ম বিল্ট-ইন এপিআই এবং কম্পোনেন্ট সরবরাহ করার মাধ্যমে এটি করতে পারি।

এরকম একটি সমস্যা হলো পপ-আপ, যা ওপেন ইউআই-তে 'পপওভার' নামে পরিচিত।

দীর্ঘদিন ধরেই পপওভারের একটি বিতর্কিত ভাবমূর্তি রয়েছে। এর একটি কারণ হলো, এগুলো তৈরি এবং প্রয়োগ করার পদ্ধতি। এই প্যাটার্নটি ভালোভাবে তৈরি করা সহজ নয়, কিন্তু ব্যবহারকারীদের নির্দিষ্ট কোনো জিনিসের দিকে পরিচালিত করে বা আপনার সাইটের বিষয়বস্তু সম্পর্কে তাদের সচেতন করে তোলার মাধ্যমে এটি অনেক মূল্যবান ফল দিতে পারে—বিশেষ করে যখন এটি রুচিসম্মতভাবে ব্যবহার করা হয়।

পপওভার তৈরি করার সময় প্রায়শই দুটি প্রধান উদ্বেগ থাকে:

  • কীভাবে নিশ্চিত করবেন যে এটি আপনার বাকি কন্টেন্টের উপরে একটি উপযুক্ত স্থানে স্থাপন করা হয়।
  • কীভাবে এটিকে ব্যবহারযোগ্য করা যায় (কিবোর্ড-বান্ধব, ফোকাসযোগ্য, ইত্যাদি)।

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

  • ডকুমেন্টের বাকি অংশের উপরে কোনো এলিমেন্ট এবং তার অধীনস্থ এলিমেন্টগুলোকে সহজে প্রদর্শন করার ব্যবস্থা করুন।
  • এটিকে সহজলভ্য করুন।
  • বেশিরভাগ সাধারণ আচরণের জন্য (যেমন লাইট ডিসমিস, সিঙ্গেলটন, স্ট্যাকিং ইত্যাদি) জাভাস্ক্রিপ্টের প্রয়োজন হয় না।

আপনি OpenUI সাইটে পপ-আপের সম্পূর্ণ স্পেসিফিকেশন দেখে নিতে পারেন।

ব্রাউজার সামঞ্জস্যতা

আপনি এখন বিল্ট-ইন পপওভার এপিআই কোথায় ব্যবহার করতে পারবেন? এই প্রতিবেদন লেখার সময়, এটি ক্রোম ক্যানারিতে 'এক্সপেরিমেন্টাল ওয়েব প্ল্যাটফর্ম ফিচারস' ফ্ল্যাগের অধীনে সমর্থিত।

ওই ফ্ল্যাগটি সক্রিয় করতে, Chrome Canary খুলুন এবং chrome://flags যান। তারপর "Experimental web platform features" ফ্ল্যাগটি সক্রিয় করুন।

যেসব ডেভেলপার প্রোডাকশন পরিবেশে এটি পরীক্ষা করে দেখতে চান, তাদের জন্য একটি অরিজিন ট্রায়ালও রয়েছে।

সবশেষে, এপিআই-টির জন্য একটি পলিফিল তৈরি করা হচ্ছে। github.com/oddbird/popup-polyfill - এই রিপোটি অবশ্যই দেখে নেবেন।

আপনি নিম্নলিখিত উপায়ে পপ-আপ সমর্থনের বিষয়টি যাচাই করতে পারেন:

const supported = HTMLElement.prototype.hasOwnProperty("popover");

বর্তমান সমাধান

অন্য সবকিছুর উপরে আপনার কন্টেন্টকে তুলে ধরতে আপনি বর্তমানে কী করতে পারেন? যদি আপনার ব্রাউজারে এটি সমর্থিত হয়, তাহলে আপনি HTML Dialog এলিমেন্টটি ব্যবহার করতে পারেন। আপনাকে এটি "Modal" ফর্মে ব্যবহার করতে হবে। আর এটি ব্যবহার করার জন্য জাভাস্ক্রিপ্ট প্রয়োজন।

Dialog.showModal();

কিছু প্রবেশগম্যতা সংক্রান্ত বিষয় বিবেচনা করার আছে। উদাহরণস্বরূপ, সাফারি ১৫.৪-এর নিচের সংস্করণের ব্যবহারকারীদের জন্য পরিষেবা দেওয়ার ক্ষেত্রে a11y-dialog ব্যবহার করার পরামর্শ দেওয়া হয়।

আপনি পপওভার, অ্যালার্ট বা টুলটিপ ভিত্তিক অনেক লাইব্রেরির মধ্যে যেকোনো একটিও ব্যবহার করতে পারেন। এগুলোর বেশিরভাগই প্রায় একই রকমভাবে কাজ করে।

  • পপওভার দেখানোর জন্য বডিতে একটি কন্টেইনার যুক্ত করুন।
  • এমনভাবে সাজান যাতে এটি অন্য সবকিছুর উপরে থাকে।
  • পপওভার দেখানোর জন্য একটি এলিমেন্ট তৈরি করে সেটিকে কন্টেইনারে যুক্ত করুন।
  • DOM থেকে পপওভার এলিমেন্টটি সরিয়ে দিয়ে এটিকে লুকান।

এর জন্য একটি অতিরিক্ত নির্ভরতা এবং ডেভেলপারদের জন্য আরও বেশি সিদ্ধান্তের প্রয়োজন হয়। এছাড়াও, আপনার প্রয়োজনীয় সবকিছু সরবরাহ করে এমন একটি অফার খুঁজে বের করার জন্য গবেষণার প্রয়োজন হয়। পপওভার এপিআই টুলটিপসহ বিভিন্ন পরিস্থিতি সামাল দেওয়ার লক্ষ্য রাখে। এর উদ্দেশ্য হলো এই সমস্ত সাধারণ পরিস্থিতিগুলো অন্তর্ভুক্ত করা, যাতে ডেভেলপারদের আরেকটি সিদ্ধান্ত নিতে না হয় এবং তারা তাদের অভিজ্ঞতা তৈরিতে মনোযোগ দিতে পারেন।

আপনার প্রথম পপ-আপ

আপনার শুধু এটুকুই প্রয়োজন।

<div id="my-first-popover" popover>Popover Content!</div>
<button popovertoggletarget="my-first-popover">Toggle Popover</button>

কিন্তু, এখানে কী ঘটছে?

  • পপওভার এলিমেন্টটিকে কোনো কন্টেইনার বা অন্য কিছুর ভেতরে রাখার প্রয়োজন নেই—এটি ডিফল্টভাবেই লুকানো থাকে।
  • এটি দেখানোর জন্য আপনাকে কোনো জাভাস্ক্রিপ্ট লিখতে হবে না। সেই কাজটি popovertoggletarget অ্যাট্রিবিউট দ্বারা সম্পন্ন হয়।
  • যখন এটি প্রদর্শিত হয়, তখন এটি শীর্ষ স্তরে উন্নীত হয়। এর মানে হলো, এটি ভিউপোর্টে document উপরে স্থান পায়। আপনাকে z-index পরিচালনা করতে হবে না বা আপনার পপওভারটি DOM-এর কোথায় আছে তা নিয়েও চিন্তা করতে হবে না। এটি ক্লিপিং অ্যানসেস্টর সহ DOM-এর গভীরে নেস্টেড থাকতে পারে। আপনি DevTools-এর মাধ্যমে বর্তমানে কোন এলিমেন্টগুলো শীর্ষ স্তরে আছে তাও দেখতে পারেন। শীর্ষ স্তর সম্পর্কে আরও জানতে, এই নিবন্ধটি দেখুন

ডেভটুলস টপ লেয়ার সাপোর্ট প্রদর্শনের জিআইএফ

  • আপনি ডিফল্টভাবেই "লাইট ডিসমিস" সুবিধাটি পাবেন। এর মানে হলো, আপনি কোনো ক্লোজ সিগন্যালের মাধ্যমে পপওভারটি বন্ধ করতে পারবেন, যেমন—পপওভারের বাইরে ক্লিক করে, কিবোর্ডের সাহায্যে অন্য কোনো এলিমেন্টে নেভিগেট করে, অথবা Esc কী চেপে। এটি আবার খুলুন এবং ব্যবহার করে দেখুন!

পপওভারের সাথে আর কী কী পাওয়া যায়? চলুন উদাহরণটি আরও খতিয়ে দেখি। পেজে কিছু কন্টেন্ট সহ এই ডেমোটি বিবেচনা করুন।

ওই ভাসমান অ্যাকশন বাটনটির পজিশনিং স্থির এবং এর z-index উচ্চ।

.fab {
  position: fixed;
  z-index: 99999;
}

পপওভারের কন্টেন্টটি DOM-এর মধ্যে নেস্টেড থাকে, কিন্তু যখন আপনি পপওভারটি খোলেন, তখন এটি ওই ফিক্সড পজিশন এলিমেন্টটির উপরে উঠে আসে। এর জন্য আপনার কোনো স্টাইল সেট করার প্রয়োজন নেই।

আপনি আরও লক্ষ্য করতে পারেন যে পপওভারটিতে এখন একটি ::backdrop সিউডো-এলিমেন্ট রয়েছে। উপরের স্তরে থাকা সমস্ত এলিমেন্ট একটি স্টাইলযোগ্য ::backdrop সিউডো-এলিমেন্ট পায়। এই উদাহরণটিতে একটি হ্রাসকৃত আলফা ব্যাকগ্রাউন্ড কালার এবং একটি ব্যাকড্রপ ফিল্টার দিয়ে ::backdrop স্টাইল করা হয়েছে, যা নিচের কন্টেন্টকে ঝাপসা করে দেয়।

পপওভারের স্টাইলিং

এবার পপওভারের স্টাইলিংয়ের দিকে নজর দেওয়া যাক। ডিফল্টভাবে, একটি পপওভারের একটি নির্দিষ্ট অবস্থান (fixed position) এবং কিছু প্যাডিং (padding) থাকে। এছাড়াও, এতে display: none সেট করা থাকে। আপনি একটি পপওভার দেখানোর জন্য এটি ওভাররাইড করতে পারেন। কিন্তু, তাতে এটি টপ লেয়ারে (top layer) উন্নীত হবে না।

[popover] { display: block; }

আপনি আপনার পপওভারকে যেভাবে প্রমোট করুন না কেন, একবার সেটিকে টপ লেয়ারে প্রমোট করলে, আপনাকে হয়তো সেটিকে লেআউট বা পজিশন করতে হতে পারে। আপনি টপ লেয়ারকে টার্গেট করে এরকম কিছু করতে পারবেন না।

:open {
  display: grid;
  place-items: center;
}

ডিফল্টরূপে, margin: auto ব্যবহার করে একটি পপওভার ভিউপোর্টের কেন্দ্রে বিন্যস্ত হয়। কিন্তু, কিছু ক্ষেত্রে, আপনি এর অবস্থান সুনির্দিষ্টভাবে নির্ধারণ করতে চাইতে পারেন। উদাহরণস্বরূপ:

[popover] {
  top: 50%;
  left: 50%;
  translate: -50%;
}

আপনি যদি CSS গ্রিড বা ফ্লেক্সবক্স ব্যবহার করে আপনার পপওভারের ভিতরে কন্টেন্ট সাজাতে চান, তবে এটিকে একটি `</div>` এলিমেন্টের মধ্যে রাখা বুদ্ধিমানের কাজ হতে পারে। অন্যথায়, আপনাকে একটি আলাদা রুল ডিক্লেয়ার করতে হবে যা পপওভারটি টপ লেয়ারে আসার পর এর display পরিবর্তন করবে। এটিকে `default` হিসেবে সেট করলে, এটি display: none ওভাররাইড করে ডিফল্টভাবে প্রদর্শিত হবে।

[popover]:open {
 display: flex;
}

আপনি যদি ওই ডেমোটি চালিয়ে দেখেন, তাহলে লক্ষ্য করবেন যে পপওভারটি এখন ভেতরে ও বাইরে আসা-যাওয়া করছে। আপনি :open সিউডো-সিলেক্টরটি ব্যবহার করে পপওভার ভেতরে ও বাইরে আনতে পারেন। :open সিউডো-সিলেক্টরটি সেইসব পপওভারকে ম্যাচ করে যেগুলো প্রদর্শিত হচ্ছে (এবং সেই কারণে টপ লেয়ারে রয়েছে)।

এই উদাহরণটিতে ট্রানজিশনটি চালনা করার জন্য একটি কাস্টম প্রপার্টি ব্যবহার করা হয়েছে। এবং আপনি পপওভারের ::backdrop এও একটি ট্রানজিশন প্রয়োগ করতে পারেন।

[popover] {
  --hide: 1;
  transition: transform 0.2s;
  transform: translateY(calc(var(--hide) * -100vh))
            scale(calc(1 - var(--hide)));
}

[popover]::backdrop {
  transition: opacity 0.2s;
  opacity: calc(1 - var(--hide, 1));
}


[popover]:open::backdrop  {
  --hide: 0;
}

এখানে একটি পরামর্শ হলো, মোশনের জন্য ট্রানজিশন এবং অ্যানিমেশনগুলোকে একটি মিডিয়া কোয়েরির অধীনে গ্রুপ করা। এটি আপনার টাইমিং ঠিক রাখতেও সাহায্য করতে পারে। এর কারণ হলো, আপনি কাস্টম প্রপার্টির মাধ্যমে popover এবং ::backdrop মধ্যে ভ্যালু শেয়ার করতে পারবেন না।

@media(prefers-reduced-motion: no-preference) {
  [popover] { transition: transform 0.2s; }
  [popover]::backdrop { transition: opacity 0.2s; }
}

এই পর্যন্ত আপনি একটি পপওভার দেখানোর জন্য popovertoggletarget এর ব্যবহার দেখেছেন। এটিকে বন্ধ করার জন্য আমরা 'Light dismiss' ব্যবহার করছি। কিন্তু, আপনি popovershowtarget এবং popoverhidetarget অ্যাট্রিবিউটগুলোও ব্যবহার করতে পারেন। চলুন, একটি পপওভারে এমন একটি বাটন যোগ করি যা এটিকে লুকিয়ে ফেলবে এবং টগল বাটনটিকে popovershowtarget ব্যবহার করার জন্য পরিবর্তন করি।

<div id="code-popover" popover>
  <button popoverhidetarget="code-popover">Hide Code</button>
</div>
<button popovershowtarget="code-popover">Reveal Code</button>

যেমনটি আগে উল্লেখ করা হয়েছে, পপওভার এপিআই শুধুমাত্র আমাদের পপ-আপ সম্পর্কিত প্রচলিত ধারণার চেয়েও বেশি কিছু অন্তর্ভুক্ত করে। আপনি নোটিফিকেশন, মেনু, টুলটিপ ইত্যাদির মতো সব ধরনের পরিস্থিতির জন্য এটি তৈরি করতে পারেন।

এই দৃশ্যকল্পগুলোর কয়েকটির জন্য ভিন্ন ধরনের ইন্টার‍্যাকশন প্যাটার্ন প্রয়োজন। যেমন হোভারের মতো ইন্টার‍্যাকশন। popoverhovertarget অ্যাট্রিবিউটের ব্যবহার নিয়ে পরীক্ষা-নিরীক্ষা করা হয়েছিল, কিন্তু বর্তমানে এটি প্রয়োগ করা হয়নি।

<div popoverhovertarget="hover-popover">Hover for Code</div>

মূল ধারণাটি হলো, কোনো এলিমেন্টের উপর মাউস হোভার করলে সেটি প্রদর্শিত হবে। এই আচরণটি CSS প্রোপার্টির মাধ্যমে কনফিগার করা যেত। এই CSS প্রোপার্টিগুলো একটি এলিমেন্টের উপর হোভার করা এবং তা থেকে সরে যাওয়ার সময়সীমা নির্ধারণ করে দিত, যার উপর ভিত্তি করে একটি পপওভার প্রতিক্রিয়া দেখাত। পরীক্ষিত ডিফল্ট আচরণটিতে, একটি পপওভার নির্দিষ্ট 0.5s :hover কমান্ডের পর প্রদর্শিত হতো। এরপর এটিকে ডিসমিস করার জন্য একটি লাইট ডিসমিস অথবা অন্য একটি পপওভার খোলার প্রয়োজন হতো (এ বিষয়ে আরও আলোচনা আসছে)। এর কারণ ছিল পপওভারের হাইড ডিউরেশন বা লুকানোর সময়কালকে Infinity ) হিসেবে সেট করা।

এর মধ্যে, আপনি জাভাস্ক্রিপ্ট ব্যবহার করে সেই কার্যকারিতাটি পলিফিল করতে পারেন।

let hoverTimer;
const HOVER_TRIGGERS = document.querySelectorAll("[popoverhovertarget]");
const tearDown = () => {
  if (hoverTimer) clearTimeout(hoverTimer);
};
HOVER_TRIGGERS.forEach((trigger) => {
  const popover = document.querySelector(
    `#${trigger.getAttribute("popoverhovertarget")}`
  );
  trigger.addEventListener("pointerenter", () => {
    hoverTimer = setTimeout(() => {
      if (!popover.matches(":open")) popover.showPopover();
    }, 500);
    trigger.addEventListener("pointerleave", tearDown);
  });
});

কোনো কিছুকে সুস্পষ্ট হোভার উইন্ডো হিসেবে সেট করার সুবিধা হলো, এটি নিশ্চিত করে যে ব্যবহারকারীর কাজটি ইচ্ছাকৃত (উদাহরণস্বরূপ, একজন ব্যবহারকারী কোনো লক্ষ্যের উপর তার পয়েন্টার নিয়ে যান)। ব্যবহারকারীর উদ্দেশ্য তা না হলে আমরা পপ-আপটি দেখাতে চাই না।

এই ডেমোটি ব্যবহার করে দেখুন, যেখানে উইন্ডোটি 0.5s সেট করা অবস্থায় আপনি টার্গেটের উপর মাউস রাখতে পারবেন।


কিছু সাধারণ ব্যবহার ও উদাহরণ জানার আগে, চলুন কয়েকটি বিষয় আলোচনা করা যাক।


পপওভারের প্রকারভেদ

আমরা নন-জাভাস্ক্রিপ্ট ইন্টারঅ্যাকশন আচরণ নিয়ে আলোচনা করেছি। কিন্তু সামগ্রিকভাবে পপওভারের আচরণ কেমন? যদি আপনি "লাইট ডিসমিস" না চান? অথবা আপনার পপওভারগুলোতে একটি সিঙ্গেলটন প্যাটার্ন প্রয়োগ করতে চান?

পপওভার এপিআই আপনাকে তিন ধরনের পপওভার নির্দিষ্ট করার সুযোগ দেয়, যেগুলোর আচরণ ভিন্ন।

[popover=auto]/[popover] :

  • নেস্টিং সাপোর্ট। এর মানে শুধু DOM-এর ভেতরে নেস্টেড থাকাই নয়। একটি অ্যানসেস্ট্রাল পপওভারের সংজ্ঞা হলো এমন একটি যা:
    • DOM অবস্থান (শিশু) দ্বারা সম্পর্কিত।
    • চাইল্ড এলিমেন্টগুলিতে popovertoggletarget , popovershowtarget ইত্যাদির মতো অ্যাট্রিবিউট ট্রিগার করার মাধ্যমে সম্পর্কিত।
    • anchor অ্যাট্রিবিউটের মাধ্যমে সম্পর্কিত (উন্নয়নাধীন সিএসএস অ্যাঙ্করিং এপিআই)।
  • আলো খারিজ।
  • এটি খুললে অন্যান্য পপওভারগুলো বন্ধ হয়ে যায়, যেগুলো মূল পপওভার নয়। নিচের ডেমোটি ব্যবহার করে দেখুন, যেখানে মূল পপওভারের সাথে নেস্টিং কীভাবে কাজ করে তা তুলে ধরা হয়েছে। দেখুন, popoverhidetarget / popovershowtarget এর কিছু ইনস্ট্যান্সকে popovertoggletarget এ পরিবর্তন করলে কী রকম পরিবর্তন আসে।
  • লাইট দিয়ে একটিকে ডিসমিস করলে সবগুলোই ডিসমিস হয়ে যায়, কিন্তু স্ট্যাকের মধ্যে একটিকে ডিসমিস করলে শুধু তার উপরেরগুলোই ডিসমিস হয়।

[popover=manual] :

  • অন্যান্য পপওভারগুলো বন্ধ করে না।
  • কোন আলো নেই বরখাস্ত।
  • ট্রিগার এলিমেন্ট অথবা জাভাস্ক্রিপ্টের মাধ্যমে সুস্পষ্টভাবে ডিসমিস করা প্রয়োজন।

জাভাস্ক্রিপ্ট এপিআই

যখন আপনার পপওভারগুলির উপর আরও বেশি নিয়ন্ত্রণের প্রয়োজন হয়, তখন আপনি জাভাস্ক্রিপ্ট ব্যবহার করতে পারেন। আপনি showPopover এবং hidePopover উভয় মেথডই পাবেন। এছাড়াও, শোনার জন্য popovershow এবং popoverhide ইভেন্টও রয়েছে:

একটি পপওভার দেখান js popoverElement.showPopover() একটি পপওভার লুকান:

popoverElement.hidePopover()

একটি পপওভার দেখানো হচ্ছে তা শুনুন:

popoverElement.addEventListener('popovershow', doSomethingWhenPopoverShows)

একটি পপওভার প্রদর্শিত হওয়ার জন্য অপেক্ষা করুন এবং এর প্রদর্শন বাতিল করুন:

popoverElement.addEventListener('popovershow',event => {
  event.preventDefault();
  console.warn(We blocked a popover from being shown);
})

একটি পপওভার লুকানোর শব্দ শুনুন:

popoverElement.addEventListener('popoverhide', doSomethingWhenPopoverHides)

আপনি লুকানো পপওভার বাতিল করতে পারবেন না:

popoverElement.addEventListener('popoverhide',event => {
  event.preventDefault();
  console.warn("You aren't allowed to cancel the hiding of a popover");
})

পপওভারটি শীর্ষ স্তরে আছে কিনা তা পরীক্ষা করুন:

popoverElement.matches(':open')

এটি কিছু বিরল পরিস্থিতির জন্য অতিরিক্ত ক্ষমতা প্রদান করে। উদাহরণস্বরূপ, কিছু সময় নিষ্ক্রিয় থাকার পর একটি পপওভার দেখানো।

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

প্রবেশগম্যতা

Popover API-এর ক্ষেত্রে অ্যাক্সেসিবিলিটি বা প্রবেশগম্যতাকেই সবচেয়ে বেশি গুরুত্ব দেওয়া হয়। প্রয়োজন অনুযায়ী, অ্যাক্সেসিবিলিটি ম্যাপিং পপওভারকে তার ট্রিগার এলিমেন্টের সাথে যুক্ত করে। এর মানে হলো, আপনি যদি popovertoggletarget মতো কোনো একটি ট্রিগারিং অ্যাট্রিবিউট ব্যবহার করেন, তাহলে আপনার aria-haspopup মতো aria-* অ্যাট্রিবিউট ডিক্লেয়ার করার প্রয়োজন নেই।

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

এটি কীভাবে কাজ করে তা দেখতে আপনাকে এই ডেমোটির " ফুল স্ক্রিন ভার্সন " খুলতে হবে।

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

অ্যাঙ্করিং (নির্মাণাধীন)

পপওভারের ক্ষেত্রে, এলিমেন্টটিকে তার ট্রিগারের সাথে অ্যাঙ্কর করা একটি জটিল বিষয়। উদাহরণস্বরূপ, যদি একটি টুলটিপ তার ট্রিগারের উপরে দেখানোর জন্য সেট করা থাকে কিন্তু ডকুমেন্টটি স্ক্রল করা হয়, তাহলে সেই টুলটিপটি ভিউপোর্টের কারণে কেটে যেতে পারে। এই সমস্যা সমাধানের জন্য বর্তমানে জাভাস্ক্রিপ্টে " ফ্লোটিং ইউআই" (Floating UI )-এর মতো কিছু সমাধান রয়েছে। এই সমস্যাটি এড়ানোর জন্য এগুলি আপনার হয়ে টুলটিপের অবস্থান পরিবর্তন করে দেয় এবং একটি নির্দিষ্ট পজিশন অর্ডারের উপর নির্ভর করে।

কিন্তু, আমরা চাই আপনি আপনার স্টাইলের মাধ্যমে এটি নির্ধারণ করতে সক্ষম হন। এই কাজটি করার জন্য পপওভার এপিআই-এর পাশাপাশি একটি সহযোগী এপিআই তৈরি করা হচ্ছে। " সিএসএস অ্যাঙ্কর পজিশনিং " এপিআই আপনাকে এলিমেন্টগুলোকে অন্য এলিমেন্টের সাথে যুক্ত করতে দেবে, এবং এটি এমনভাবে এলিমেন্টগুলোর অবস্থান পরিবর্তন করবে যাতে সেগুলো ভিউপোর্টের কারণে কেটে না যায়।

এই ডেমোটি অ্যাঙ্করিং এপিআই-এর বর্তমান অবস্থা ব্যবহার করে। ভিউপোর্টে অ্যাঙ্করের অবস্থানের ওপর ভিত্তি করে নৌকার অবস্থান নির্ধারিত হয়।

এই ডেমোটি কার্যকর করার জন্য ব্যবহৃত CSS কোডের একটি অংশ এখানে দেওয়া হলো। কোনো জাভাস্ক্রিপ্টের প্রয়োজন নেই।

.anchor {
  --anchor-name: --anchor;
}
.anchored {
  position: absolute;
  position-fallback: --compass;
}
@position-fallback --compass {
  @try {
    bottom: anchor(--anchor top);
    left: anchor(--anchor right);
  }
  @try {
    top: anchor(--anchor bottom);
    left: anchor(--anchor right);
  }
}

আপনি এখানে স্পেকটি দেখে নিতে পারেন। এই এপিআই-এর জন্য একটি পলিফিলও থাকবে।

উদাহরণ

এখন যেহেতু আপনি পপওভার কী এবং কীভাবে কাজ করে সে সম্পর্কে পরিচিত, চলুন কিছু উদাহরণ দেখা যাক।

বিজ্ঞপ্তি

এই ডেমোটিতে একটি 'ক্লিপবোর্ডে কপি করুন' নোটিফিকেশন দেখানো হয়েছে।

  • [popover=manual] ব্যবহার করে।
  • কোনো কিছু ঘটলে showPopover ব্যবহার করে পপওভার দেখান।
  • 2000ms টাইমআউটের পর hidePopover ব্যবহার করে এটিকে লুকিয়ে ফেলুন।

টোস্ট

এই ডেমোটি টোস্ট স্টাইলের নোটিফিকেশন দেখানোর জন্য টপ লেয়ার ব্যবহার করে।

  • manual টাইপের একটি পপওভার কন্টেইনার হিসেবে কাজ করে।
  • নতুন নোটিফিকেশনগুলো পপওভারে যুক্ত করা হয় এবং পপওভারটি দেখানো হয়।
  • ওয়েব অ্যানিমেশন এপিআই ব্যবহার করে ক্লিক করার মাধ্যমে এগুলোকে DOM থেকে সরিয়ে দেওয়া হয়।
  • দেখানোর মতো কোনো টোস্ট না থাকলে পপওভারটি লুকানো থাকে।

নেস্টেড মেনু

এই ডেমোটি দেখায় যে একটি নেস্টেড নেভিগেশন মেনু কীভাবে কাজ করতে পারে।

  • [popover=auto] ব্যবহার করুন, কারণ এটি নেস্টেড পপওভারের সুবিধা দেয়।
  • কিবোর্ড ব্যবহার করে নেভিগেট করার জন্য প্রতিটি ড্রপডাউনের প্রথম লিঙ্কে autofocus ব্যবহার করুন।
  • এটি CSS অ্যাঙ্করিং এপিআই (CSS Anchoring API)-এর জন্য একটি উপযুক্ত ক্ষেত্র। কিন্তু, এই ডেমোর জন্য আপনি কাস্টম প্রোপার্টি ব্যবহার করে অবস্থানগুলো আপডেট করতে অল্প পরিমাণ জাভাস্ক্রিপ্ট ব্যবহার করতে পারেন।
const ANCHOR = (anchor, anchored) => () => {
  const { top, bottom, left, right } = anchor.getBoundingClientRect();
  anchored.style.setProperty("--top", top);
  anchored.style.setProperty("--right", right);
  anchored.style.setProperty("--bottom", bottom);
  anchored.style.setProperty("--left", left);
};

PRODUCTS_MENU.addEventListener("popovershow", ANCHOR(PRODUCT_TARGET, PRODUCTS_MENU));

মনে রাখবেন, যেহেতু এই ডেমোটি autofocus ব্যবহার করে, তাই কিবোর্ড নেভিগেশনের জন্য এটিকে ' ফুল স্ক্রিন ভিউ' -তে খুলতে হবে।

মিডিয়া পপওভার

এই ডেমোটি দেখায় যে আপনি কীভাবে মিডিয়া পপ-আপ করতে পারেন।

  • লাইট ডিসমিস করার জন্য [popover=auto] ব্যবহার করা হয়।
  • জাভাস্ক্রিপ্ট ভিডিওটির play ইভেন্টের জন্য অপেক্ষা করে এবং ভিডিওটি পপ-আপ করে দেখায়।
  • `popovers popoverhide ইভেন্টটি ভিডিওটি থামিয়ে দেয়।

উইকি স্টাইলের পপওভার

এই ডেমোতে দেখানো হয়েছে, কীভাবে আপনি মিডিয়া সম্বলিত ইনলাইন কন্টেন্ট টুলটিপ তৈরি করতে পারেন।

  • [popover=auto] ব্যবহার করে। একটি দেখালে অন্যগুলো লুকিয়ে যায়, কারণ সেগুলো পূর্বপুরুষের নয়।
  • জাভাস্ক্রিপ্টে pointerenter চাপলে দেখানো হয়।
  • CSS অ্যাঙ্করিং এপিআই-এর জন্য আরও একটি উপযুক্ত প্রার্থী।

এই ডেমোটি একটি পপওভার ব্যবহার করে একটি নেভিগেশন ড্রয়ার তৈরি করে।

  • লাইট ডিসমিস করার জন্য [popover=auto] ব্যবহার করা হয়।
  • প্রথম নেভিগেশন আইটেমটিতে ফোকাস করার জন্য autofocus ব্যবহার করে।

পটভূমি পরিচালনা

এই ডেমোটি দেখায় যে, একাধিক পপওভারের জন্য ব্যাকড্রপ কীভাবে পরিচালনা করা যেতে পারে, যেখানে আপনি কেবল একটি ::backdrop দৃশ্যমান রাখতে চান।

  • দৃশ্যমান পপওভারগুলোর একটি তালিকা বজায় রাখতে জাভাস্ক্রিপ্ট ব্যবহার করুন।
  • শীর্ষ স্তরের সর্বনিম্ন পপওভারে একটি ক্লাস নেম প্রয়োগ করুন।

কাস্টম কার্সার পপওভার

এই ডেমোতে দেখানো হয়েছে কীভাবে popover ব্যবহার করে একটি canvas শীর্ষ স্তরে উন্নীত করা যায় এবং এর মাধ্যমে একটি কাস্টম কার্সার প্রদর্শন করা যায়।

  • showPopover এবং [popover=manual] ব্যবহার করে canvas শীর্ষ স্তরে উন্নীত করুন।
  • অন্যান্য পপওভার খোলা থাকলে, canvas পপওভারটি লুকান ও দেখান, যাতে এটি সবার উপরে থাকে।

অ্যাকশনশিট পপওভার

এই ডেমোটি দেখায় কিভাবে আপনি একটি পপওভারকে অ্যাকশনশিট হিসেবে ব্যবহার করতে পারেন।

  • display ওভাররাইড করে পপওভারটি ডিফল্টরূপে দেখানো হোক।
  • পপওভার ট্রিগারের মাধ্যমে অ্যাকশনশিটটি খোলা হয়।
  • যখন পপওভারটি দেখানো হয়, তখন এটিকে শীর্ষ স্তরে উন্নীত করা হয় এবং দৃশ্যমান করা হয়।
  • এটিকে ফেরত দিতে লাইট ডিসমিস ব্যবহার করা যেতে পারে।

কিবোর্ড দ্বারা সক্রিয় পপওভার

এই ডেমোটি দেখায় যে, কমান্ড প্যালেট স্টাইলের UI-এর জন্য কীভাবে পপওভার ব্যবহার করা যেতে পারে।

  • পপওভারটি দেখানোর জন্য cmd + j ব্যবহার করুন।
  • autofocus মাধ্যমে input ফোকাস করা হয়।
  • কম্বো বক্সটি হলো মূল ইনপুটের নিচে অবস্থিত একটি দ্বিতীয় popover
  • ড্রপডাউন উপস্থিত না থাকলে লাইট ডিসমিস প্যালেটটি বন্ধ করে দেয়।
  • অ্যাঙ্করিং এপিআই-এর জন্য আরেকটি সম্ভাব্য প্রার্থী

টাইমড পপওভার

এই ডেমোটি চার সেকেন্ড পর একটি নিষ্ক্রিয়তা পপওভার দেখায়। এটি একটি UI প্যাটার্ন যা প্রায়শই ব্যবহারকারীর সুরক্ষিত তথ্য ধারণকারী অ্যাপগুলিতে লগআউট মোডাল দেখানোর জন্য ব্যবহৃত হয়।

  • কিছুক্ষণ নিষ্ক্রিয় থাকার পর পপওভারটি দেখানোর জন্য জাভাস্ক্রিপ্ট ব্যবহার করুন।
  • পপওভার প্রদর্শিত হলে, টাইমারটি রিসেট করুন।

স্ক্রিনসেভার

আগের ডেমোটির মতোই, আপনি আপনার সাইটে একটু ভিন্নতা আনতে একটি স্ক্রিনসেভার যোগ করতে পারেন।

  • কিছুক্ষণ নিষ্ক্রিয় থাকার পর পপওভারটি দেখানোর জন্য জাভাস্ক্রিপ্ট ব্যবহার করুন।
  • টাইমারটি লুকাতে ও রিসেট করতে লাইটটি বন্ধ করুন।

ক্যারেট অনুসরণ করুন

এই ডেমোটি দেখায় কিভাবে একটি পপওভারকে ইনপুট ক্যারেট অনুসরণ করানো যায়।

  • নির্বাচন, কী ইভেন্ট বা বিশেষ অক্ষর ইনপুটের উপর ভিত্তি করে পপওভারটি দেখান।
  • জাভাস্ক্রিপ্ট ব্যবহার করে স্কোপড কাস্টম প্রোপার্টির সাহায্যে পপওভারের অবস্থান আপডেট করুন।
  • এই বিন্যাসটির জন্য প্রদর্শিত বিষয়বস্তু এবং প্রবেশগম্যতা সম্পর্কে সুচিন্তিত ভাবনার প্রয়োজন হবে।
  • এটি প্রায়শই টেক্সট এডিটিং UI এবং ট্যাগ করার সুবিধাযুক্ত অ্যাপগুলিতে দেখা যায়।

ভাসমান অ্যাকশন বাটন মেনু

এই ডেমোটি দেখায় যে কীভাবে জাভাস্ক্রিপ্ট ছাড়াই পপওভার ব্যবহার করে একটি ফ্লোটিং অ্যাকশন বাটন মেনু তৈরি করা যায়।

  • showPopover মেথড ব্যবহার করে একটি manual টাইপ পপওভার প্রদর্শন করুন। এটিই মূল বাটন।
  • মেনুটি হলো আরেকটি পপওভার, যা মূল বাটনটির লক্ষ্যবস্তু।
  • popovertoggletarget দিয়ে মেনুটি খোলা হয়।
  • প্রদর্শিত প্রথম মেনু আইটেমটিতে ফোকাস করতে autofocus ব্যবহার করুন।
  • লাইট ডিসমিস মেনুটি বন্ধ করে দেয়।
  • আইকন টুইস্টে :has() ব্যবহৃত হয়। আপনি এই আর্টিকেলটিতে :has() সম্পর্কে আরও পড়তে পারেন।

এই তো!

তো, এই হলো পপওভারের পরিচিতি, যা ওপেন ইউআই উদ্যোগের অংশ হিসেবে ভবিষ্যতে আসছে। বিচক্ষণতার সাথে ব্যবহার করা হলে, এটি ওয়েব প্ল্যাটফর্মের জন্য একটি চমৎকার সংযোজন হবে।

অবশ্যই Open UI দেখে নেবেন। API-এর বিবর্তনের সাথে সাথে পপওভার এক্সপ্লেনারটিও হালনাগাদ করা হয়। আর এখানে রয়েছে সমস্ত ডেমোগুলোর সংগ্রহ

আসার জন্য ধন্যবাদ!