কার্ড তৈরি করুন

এক নজরে

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

নির্দেশিকা

কন্টেন্ট ও তার ইন্টার‍্যাকশনের জন্য আলাদাভাবে সিম্যান্টিক বেছে নিন:

  • কার্ডের রুট হিসেবে <article> ব্যবহার করুন, এটি কোনও গন্তব্যের সাথে লিঙ্ক করুক বা না করুক;
  • নেভিগেশনের জন্য নেটিভ লিঙ্ক ব্যবহার করুন। পুরো কার্ডটি একটি গন্তব্য হলে, কার্ডে অন্য কোনও ইন্টার‍্যাক্টিভ এলিমেন্ট (a, button, input, select, textarea) না থাকলে, একটি লিঙ্ক <article>-কে র‍্যাপ করতে পারে;
  • স্বাধীন অ্যাকশনের জন্য লিঙ্ক ও বোতাম আলাদা নেটিভ কন্ট্রোল হিসেবে রাখুন;
  • কার্ডটি একটি পছন্দ হলে, সংশ্লিষ্ট <label> সহ একটি রেডিও বোতাম বা চেকবক্স ব্যবহার করুন, অথবা নেটিভ <select>-এ একটি option ব্যবহার করুন।

মিডিয়া, শীর্ষক, সহায়ক কন্টেন্ট ও অ্যাকশন অর্থপূর্ণ সোর্স অর্ডারে রাখুন; এর বিরোধিতা করতে CSS order ব্যবহার করবেন না (CSS লেআউট ও রেসপন্সিভ ডিজাইন দেখুন)।

প্রয়োগ

মার্কআপ যতটা সম্ভব কম রাখুন এবং CSS বাছাইকারীকে প্রতিটি অঞ্চল শনাক্ত করতে দিন, যাতে সাধারণ কার্ডগুলি সাধারণ থাকে এবং আরও সমৃদ্ধ কার্ডগুলি সম্ভব হয়। একটি কার্ডে সর্বাধিক চারটি অঞ্চল থাকে, এই সোর্স অর্ডারে এবং এর মধ্যে যেকোনও একটি বাদ দেওয়া যেতে পারে। অঞ্চলগুলি কার্ডের সরাসরি চাইল্ড, .card__body-এর মতো র‍্যাপার এলিমেন্টে গ্রুপ করা নেই, যা সিলেক্টর দ্বারা অঞ্চলগুলি স্থাপন এবং স্টাইল করা থেকে বিরত রাখে। একটি এলিমেন্ট সহ অঞ্চল হল সেই এলিমেন্টটি নিজেই, র‍্যাপ করা নয়: একটি একা প্যারাগ্রাফ হল <p>। কোনও অঞ্চলে একাধিক এলিমেন্ট থাকলে তবেই র‍্যাপার ব্যবহার করুন।

  • মিডিয়া: প্রথম চাইল্ড হিসেবে <img>, <picture>, <video> বা <svg>। শুধুমাত্র সেইসব হিরো কন্টেন্টে .media ক্লাস যোগ করুন যেগুলি এইসব এলিমেন্টের মধ্যে পড়ে না এবং কখনও .media এলিমেন্টের মধ্যে সাধারণ <img> র‍্যাপ করবেন না।
  • হেডার: এটি নিজেই একটি হেডিং। শিরোনামে সাবটাইটেল বা ট্যাগলাইন থাকলে তবেই <hgroup> ব্যবহার করুন এবং অঞ্চলে বাইলাইন বা ব্যাজের মতো শিরোনামের চেয়ে বেশি কিছু থাকলে <header> ব্যবহার করুন। কার্ডের কোনও প্রাথমিক গন্তব্য থাকলে, লিঙ্কটি শিরোনামের মধ্যে থাকে।
  • কন্টেন্ট: একটি <p>, <ul> বা <dl> স্বতন্ত্রভাবে দেখানো হয়। কন্টেন্টে একাধিক এলিমেন্ট থাকলে, যেমন একাধিক অনুচ্ছেদ বা একটি অনুচ্ছেদ ও একটি তালিকা, সেগুলিকে একটি <div>-এ গ্রুপ করুন যাতে অঞ্চলটি একটি গ্রিড আইটেম হয়।
  • ফুটার: একটি <footer> যা নেটিভ লিঙ্ক এবং বোতাম হিসাবে স্বাধীন অ্যাকশন ধরে রাখে। "আরও পড়ুন" লিঙ্কে হেডিং লিঙ্কের URL শেয়ার করা হতে পারে, তবে এটিকে একটি বর্ণনামূলক অ্যাক্সেসযোগ্য নাম দিন যা দৃশ্যমান টেক্সট দিয়ে শুরু হয় এবং ভিজ্যুয়ালি লুকানো টেক্সট (যেমন, Read more<span> about poached eggs</span>) ব্যবহার করে, কারণ স্ক্রিন রিডারের লিঙ্ক তালিকায় একই ধরনের "আরও পড়ুন" লিঙ্ক অস্পষ্ট হয়। শিরোনামের URL-এর পুনরাবৃত্তি করে এমন অন্যান্য ফুটার লিঙ্ক যোগ করবেন না।

সবচেয়ে সহজ কার্ড হল একটি <article> যাতে একটি শিরোনাম ও একটি অনুচ্ছেদ থাকে। কার্ডের আচরণের সাথে মেলে এমন লিঙ্ক এবং অ্যাকশন প্যাটার্ন বেছে নিন; ইন্টার‍্যাকশন মডেল দেখুন।

কার্ডের ছবি বা ভিডিওর জন্য যা একটি নির্দিষ্ট-অনুপাত এলাকা পূরণ করা উচিত, <img> বা <video>-এ aspect-ratio এবং object-fit: cover সেট করুন, যাতে এটি বিকৃতি ছাড়াই এলাকাটি পূরণ করে (ক্রপ করা হতে পারে)। শুধুমাত্র অন্যান্য হিরো কন্টেন্টের জন্য .media কন্টেনারের aspect-ratio ব্যবহার করুন। অন্যথায়, মিডিয়ার নিজস্ব অনুপাত বজায় রাখুন। তথ্যপূর্ণ ছবির জন্য উপযুক্ত বিকল্প টেক্সট দিন; অলঙ্করণ করা ছবির জন্য alt="" ব্যবহার করুন।

উপলভ্য স্পেস অনুযায়ী

কার্ডের উপলভ্য স্পেসের উপর ভিত্তি করে লেআউট তৈরি করুন, ভিউপোর্টের উপর ভিত্তি করে নয়। কার্ডের ডিসেন্ডেন্ট (মিডিয়া, টেক্সট, অ্যাকশন) অ্যাডাপ্ট করতে, কার্ডটিকে সাইজ কন্টেনার (container-type: inline-size) হিসেবে সেট করুন এবং এর চিলড্রেনের জন্য @container নিয়ম লিখুন। গ্রিড বা লিস্ট পেরেন্ট থেকে সাইজ করা এড়িয়ে চলুন: কার্ডের আসল প্রস্থ কলামের সংখ্যা, ফাঁক ইত্যাদির উপর নির্ভর করতে পারে, যার ফলে পেরেন্ট-ভিত্তিক ব্রেকপয়েন্টগুলি গোলমেলে হয়ে যায়।

একটি সরু কন্টেনারে, সোর্স ক্রম অনুযায়ী অঞ্চলগুলি স্ট্যাক করুন। একটি চওড়া কন্টেনারে, অন্যান্য অঞ্চলের পাশে একটি সাইড কলামে মিডিয়া রাখুন, তবে শুধুমাত্র সেই কার্ডগুলির জন্য যেগুলিতে মিডিয়া আছে: মিডিয়ার চাইল্ডে :has() সহ সেই নিয়মগুলি প্রয়োগ করুন (যেমন .card:has(> img)) যাতে কলামের সংজ্ঞা এবং grid-column প্লেসমেন্ট কখনই মিডিয়া ছাড়া কার্ডে প্রযোজ্য না হয়। মিডিয়া ছাড়া কার্ড সব প্রস্থে সিঙ্গল-কলাম হিসেবে থাকে এবং খালি মিডিয়া কলাম রিজার্ভ করে রাখা যাবে না।

গ্রিডে কার্ড সাজান

যখন একটি সারির কার্ডগুলি তাদের অঞ্চলের উচ্চতা শেয়ার করবে, তখন subgrid ব্যবহার করুন: প্রতিটি কার্ডকে চারটি শেয়ার করা সারি ট্র্যাক (মিডিয়া, হেডার, কন্টেন্ট, ফুটার) জুড়ে দিন এবং এলিমেন্ট সিলেক্টর দ্বারা অঞ্চলগুলি রাখুন, মিডিয়া, হেডিং বা <footer> নয় এমন সবকিছুকে কন্টেন্ট হিসাবে বিবেচনা করুন। যে কার্ডে কোনও অঞ্চল বাদ দেওয়া হয়, সেটির ট্র্যাক খালি থাকে, তাই বাকি অঞ্চলগুলি এখনও আশেপাশের কার্ডের সাথে সারিবদ্ধ থাকে। প্রতিটি ট্র্যাকে একটি গ্রিড আইটেম থাকে, তাই কন্টেন্ট অঞ্চলটি শুধুমাত্র তখনই <div>-এ র‍্যাপ করুন যখন এতে একাধিক এলিমেন্ট থাকে এবং কার্ডগুলি ট্র্যাক শেয়ার করে। যেসব কার্ড ভাইবোনদের সাথে সারিবদ্ধ নয় সেগুলির জন্য র‍্যাপার বা সাবগ্রিড প্রয়োজন হয় না।

ইন্টার‍্যাকশন মডেল

কন্টেন্ট কার্ড

কার্ডের রুট হিসেবে <article> ব্যবহার করুন। লিঙ্ক ও বোতাম আলাদা নেটিভ কন্ট্রোল হিসেবে রাখুন।

একটি গন্তব্যের কার্ড

পুরো কার্ডটি একটি গন্তব্য হলে এবং কোনও স্বাধীন অ্যাকশন না থাকলে, একটি নেটিভ লিঙ্ক ব্যবহার করুন। লিঙ্কটি <article>-কে র‍্যাপ করতে পারে। লিঙ্কের মধ্যে অন্য লিঙ্ক, বোতাম বা ফর্ম কন্ট্রোল নেস্ট করবেন না এবং "আরও পড়ুন" টেক্সটকে সাধারণ <p> বা <span> হিসেবে রাখুন। লিঙ্কের অ্যাক্সেসযোগ্য নাম কার্ডের সব টেক্সট হওয়ার কারণে, কন্টেন্ট ছোট রাখুন; কার্ডে অনেক টেক্সট বা অন্যান্য অ্যাকশন থাকলে, নিচে দেখানো স্ট্রেচড-লিঙ্ক প্যাটার্ন ব্যবহার করুন যাতে শুধু শীর্ষকটিই লিঙ্ক হয়:

<a href="/recipes/poached-eggs">
  <article class="card">
    <h3>Poached eggs</h3>
    <p>Two poached eggs served on toasted sourdough.</p>
  </article>
</a>

ক্লিক করা যায় এমন কার্ড, যাতে স্বতন্ত্র অ্যাকশন আছে

কার্ডে ক্লিক করলে নেভিগেট করার পরিবর্তে কোনও অ্যাকশন ট্রিগার হলে, লিঙ্কের পরিবর্তে <button> ব্যবহার করুন।

যখন কোনও কন্টেন্ট কার্ড প্রাইমারি ডেস্টিনেশনের সাথে লিঙ্ক করে, অন্যান্য ইন্টার‍্যাক্টিভ এলিমেন্টও থাকে এবং সম্পূর্ণভাবে ক্লিক করার মতো হতে হয়:

  • প্রাথমিক লিঙ্কে একটিই অপ্ট-ইন ব্যবহার করুন: প্রতিটি কার্ডের ঠিক একটি লিঙ্কে (শিরোনামের লিঙ্ক) .card-link রাখুন। ফুটার এবং অন্যান্য লিঙ্ক কখনই এটি পায় না, অথবা প্রতিটি তার নিজস্ব ওভারলে প্রসারিত করবে এবং শেষটি পুরো কার্ডটি ক্যাপচার করবে।
  • ::after-এর মাধ্যমে এর শীর্ষক লিঙ্ক করুন এবং কার্ড জুড়ে পয়েন্টার হিট এরিয়া প্রসারিত করুন
.card:has(a.card-link) {
    position: relative;
}

.card a.card-link::after {
    content: "";
    position: absolute;
    inset: 0;
}
  • position: relative; z-index: 1-এর মাধ্যমে ইন্টার‌্যাক্টিভ এলিমেন্টকে আরও উন্নত করুন যাতে সেগুলি কাজ করতে পারে। ক্লাসের মাধ্যমে অপ্ট-ইন করার পরিবর্তে এলিমেন্টের ধরন (যেমন, a, button) টার্গেট করুন।
  • সম্পূর্ণ কন্টেনারে z-index প্রয়োগ করবেন না, কারণ এর ফলে কন্টেনার এমন পয়েন্টার ইভেন্ট ক্যাপচার করবে যা কোনও অ্যাকশন তৈরি করে না।
.card:has(a.card-link) {
    /* Keep other interactive elements above the overlay */
    a:not(.card-link), button, input, x-button {
        position: relative;
        z-index: 1;
    }
}
  • স্ট্রেচ করা লিঙ্কের পরিবর্তে হোভার/ফোকাস করার সময় কার্ডটি স্টাইল করুন:
.card {
    a.card-link {
        &:focus-visible {
            outline: none; /* Draw it on the card instead */
        }
    }
    
    &:has(a.card-link:focus-visible) {
        /* Focus ring */
    }

    &:has(a.card-link:hover) {
        /* Hover styles */
    }
}

চয়েস কার্ড

আগে থেকে নির্ধারিত পছন্দ দেখায় এমন কার্ডের জন্য, সরাসরি চাইল্ড হিসেবে চেকবক্স বা রেডিও সহ <label class="card"> ব্যবহার করুন।

:has(:checked) দিয়ে বেছে নেওয়া কার্ড স্টাইল করুন। বেছে নেওয়ার সময় border-width, padding বা font-weight-এর মতো লেআউটকে প্রভাবিত করে এমন প্রপার্টি কখনই পরিবর্তন করবেন না, কারণ কার্ড ও তার আশেপাশের এলিমেন্টগুলি জাম্প করে; outline, box-shadow বা একটি স্বচ্ছ বর্ডার দিয়ে জোর দিন যা শুধুমাত্র রঙ পরিবর্তন করে:

.card {
  border: 2px solid transparent;

  &:has(> :checked) {
    border-color: var(--accent);
  }
}

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

যখন পছন্দগুলি একটি ড্রপডাউন পিকারের অন্তর্গত হয় যার বিকল্পগুলি কার্ড হিসাবে সাজানো থাকে, তখন <div> কার্ডের সাথে নির্বাচন প্রতিস্থাপন করার পরিবর্তে appearance: base-select এবং স্টাইল ::picker(select) এবং <option> উপাদানগুলির সাথে একটি নেটিভ <select> ব্যবহার করুন; আরও বিবরণ এবং ফলব্যাকের জন্য কাস্টম সিলেক্ট পিকার লেআউট দেখুন।