আইওএস এবং অ্যান্ড্রয়েড অ্যাপে পাওয়া ট্যাবগুলির অনুরূপ একটি ট্যাব উপাদান কীভাবে তৈরি করা যায় তার একটি মৌলিক ওভারভিউ।
এই পোস্টে আমি ওয়েবের জন্য একটি ট্যাব উপাদান তৈরি করার চিন্তাভাবনা শেয়ার করতে চাই যা প্রতিক্রিয়াশীল, একাধিক ডিভাইস ইনপুট সমর্থন করে এবং ব্রাউজার জুড়ে কাজ করে। ডেমো চেষ্টা করুন.
আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:
ওভারভিউ
ট্যাবগুলি ডিজাইন সিস্টেমের একটি সাধারণ উপাদান কিন্তু অনেক আকার এবং ফর্ম নিতে পারে। প্রথমে <frame>
উপাদানে তৈরি ডেস্কটপ ট্যাব ছিল, এবং এখন আমাদের কাছে বাটারি মোবাইল উপাদান রয়েছে যা পদার্থবিজ্ঞানের বৈশিষ্ট্যের উপর ভিত্তি করে বিষয়বস্তুকে অ্যানিমেট করে। তারা সবাই একই জিনিস করার চেষ্টা করছে: স্থান বাঁচান।
আজ, একটি ট্যাব ব্যবহারকারীর অভিজ্ঞতার অপরিহার্য বিষয় হল একটি বোতাম নেভিগেশন এলাকা যা একটি ডিসপ্লে ফ্রেমে বিষয়বস্তুর দৃশ্যমানতা টগল করে। অনেক ভিন্ন বিষয়বস্তু এলাকা একই স্থান ভাগ করে, কিন্তু শর্তসাপেক্ষে নেভিগেশন নির্বাচিত বোতাম উপর ভিত্তি করে উপস্থাপন করা হয়.
ওয়েব কৌশল
সব মিলিয়ে আমি এই উপাদানটিকে তৈরি করার জন্য বেশ সহজবোধ্য পেয়েছি, কয়েকটি সমালোচনামূলক ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্যগুলির জন্য ধন্যবাদ:
- উপযুক্ত স্ক্রোল স্টপ অবস্থানের সাথে মার্জিত সোয়াইপ এবং কীবোর্ড ইন্টারঅ্যাকশনের জন্য
scroll-snap-points
- ব্রাউজারের জন্য ইউআরএল হ্যাশের মাধ্যমে গভীর লিঙ্কগুলি ইন-পেজ স্ক্রোল অ্যাঙ্করিং এবং শেয়ারিং সমর্থন পরিচালনা করে
-
<a>
এবংid="#hash"
উপাদান মার্কআপ সহ স্ক্রিন রিডার সমর্থন - ক্রসফেড ট্রানজিশন এবং ইনস্ট্যান্ট ইন-পেজ স্ক্রোলিং সক্ষম করার জন্য
prefers-reduced-motion
- ইন-ড্রাফ্ট
@scroll-timeline
ওয়েব বৈশিষ্ট্যটি নির্বাচিত ট্যাবটিকে গতিশীলভাবে আন্ডারলাইন এবং রঙ পরিবর্তন করার জন্য
এইচটিএমএল
মৌলিকভাবে, এখানে UX হল: একটি লিঙ্কে ক্লিক করুন, ইউআরএলটি নেস্টেড পৃষ্ঠার অবস্থার প্রতিনিধিত্ব করুন এবং তারপরে ব্রাউজার ম্যাচিং এলিমেন্টে স্ক্রোল করার সাথে সাথে বিষয়বস্তু এলাকা আপডেট দেখুন।
সেখানে কিছু স্ট্রাকচারাল কন্টেন্ট মেম্বার আছে: লিঙ্ক এবং :target
এস। আমাদের লিঙ্কগুলির একটি তালিকা প্রয়োজন, যেগুলির জন্য একটি <nav>
দুর্দান্ত, এবং <article>
উপাদানগুলির একটি তালিকা, যার জন্য একটি <section>
দুর্দান্ত। প্রতিটি লিঙ্ক হ্যাশ একটি বিভাগের সাথে মিলবে, ব্রাউজারকে অ্যাঙ্করিংয়ের মাধ্যমে জিনিসগুলি স্ক্রোল করতে দেয়।
উদাহরণস্বরূপ, একটি লিঙ্কে ক্লিক করলে তা স্বয়ংক্রিয়ভাবে ক্রোম 89-এ :target
নিবন্ধে ফোকাস করে, কোন JS প্রয়োজন হয় না। ব্যবহারকারী তারপর বরাবরের মতো তাদের ইনপুট ডিভাইস দিয়ে নিবন্ধের বিষয়বস্তু স্ক্রোল করতে পারেন। এটি প্রশংসাসূচক বিষয়বস্তু, যা মার্কআপে নির্দেশিত।
আমি ট্যাবগুলি সংগঠিত করতে নিম্নলিখিত মার্কআপ ব্যবহার করেছি:
<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>
আমি এই মত href
এবং id
বৈশিষ্ট্য সহ <a>
এবং <article>
উপাদানগুলির মধ্যে সংযোগ স্থাপন করতে পারি:
<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>
আমি পরবর্তীতে নিবন্ধগুলিকে মিশ্র পরিমাণে লরেমের সাথে এবং লিঙ্কগুলিকে একটি মিশ্র দৈর্ঘ্য এবং শিরোনামগুলির সেট দিয়ে পূরণ করেছি। বিষয়বস্তুর সাথে কাজ করার জন্য, আমরা লেআউট শুরু করতে পারি।
স্ক্রলিং লেআউট
এই উপাদানটিতে 3টি বিভিন্ন ধরণের স্ক্রোল এলাকা রয়েছে:
- নেভিগেশন (গোলাপী) অনুভূমিকভাবে স্ক্রোলযোগ্য
- বিষয়বস্তু এলাকা (নীল) অনুভূমিকভাবে স্ক্রোলযোগ্য
- প্রতিটি নিবন্ধ আইটেম (সবুজ) উল্লম্বভাবে স্ক্রোলযোগ্য।
স্ক্রোলিং এর সাথে জড়িত 2টি বিভিন্ন ধরণের উপাদান রয়েছে:
- একটি জানালা
সংজ্ঞায়িত মাত্রা সহ একটি বাক্স যাতেoverflow
সম্পত্তি শৈলী রয়েছে। - একটি oversized পৃষ্ঠ
এই লেআউটে, এটি তালিকার ধারক: নেভি লিঙ্ক, বিভাগ নিবন্ধ এবং নিবন্ধের বিষয়বস্তু।
<snap-tabs>
লেআউট
আমি যে শীর্ষ স্তরের বিন্যাসটি বেছে নিয়েছি তা হল ফ্লেক্স (ফ্লেক্সবক্স)। আমি column
দিকনির্দেশ সেট করেছি, তাই শিরোনাম এবং বিভাগ উল্লম্বভাবে অর্ডার করা হয়েছে। এটি আমাদের প্রথম স্ক্রোল উইন্ডো, এবং এটি ওভারফ্লো লুকিয়ে সবকিছু লুকিয়ে রাখে। শিরোনাম এবং বিভাগ শীঘ্রই ওভারস্ক্রোল নিয়োগ করবে, পৃথক অঞ্চল হিসাবে।
<snap-tabs> <header></header> <section></section> </snap-tabs>
snap-tabs { display: flex; flex-direction: column; /* establish primary containing box */ overflow: hidden; position: relative; & > section { /* be pushy about consuming all space */ block-size: 100%; } & > header { /* defend againstneeding 100% */ flex-shrink: 0; /* fixes cross browser quarks */ min-block-size: fit-content; } }
রঙিন 3-স্ক্রোল ডায়াগ্রামে ফিরে ইঙ্গিত করা:
-
<header>
এখন (গোলাপী) স্ক্রোল কন্টেইনার হতে প্রস্তুত। -
<section>
(নীল) স্ক্রোল কন্টেইনার হতে প্রস্তুত।
VisBug-এর সাহায্যে আমি নীচে যে ফ্রেমগুলি হাইলাইট করেছি সেগুলি আমাদের স্ক্রোল কন্টেনারগুলি তৈরি করা উইন্ডোগুলি দেখতে সাহায্য করে৷
ট্যাব <header>
লেআউট
পরবর্তী লেআউট প্রায় একই: আমি উল্লম্ব ক্রম তৈরি করতে ফ্লেক্স ব্যবহার করি।
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
লিঙ্কগুলির গ্রুপের সাথে অনুভূমিকভাবে ভ্রমণ করা উচিত এবং এই হেডার লেআউটটি সেই পর্যায়টি সেট করতে সহায়তা করে। এখানে কোন পরম অবস্থান উপাদান!
পরবর্তী, স্ক্রোল শৈলী. দেখা যাচ্ছে যে আমরা আমাদের 2টি অনুভূমিক স্ক্রোল এলাকার (শিরোনাম এবং বিভাগ) মধ্যে স্ক্রোল শৈলী ভাগ করতে পারি, তাই আমি একটি ইউটিলিটি ক্লাস তৈরি করেছি, .scroll-snap-x
।
.scroll-snap-x {
/* browser decide if x is ok to scroll and show bars on, y hidden */
overflow: auto hidden;
/* prevent scroll chaining on x scroll */
overscroll-behavior-x: contain;
/* scrolling should snap children on x */
scroll-snap-type: x mandatory;
@media (hover: none) {
scrollbar-width: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
প্রতিটির প্রয়োজন x অক্ষে ওভারফ্লো, ওভারস্ক্রোলকে আটকাতে স্ক্রোল কন্টেনমেন্ট, টাচ ডিভাইসের জন্য লুকানো স্ক্রলবার এবং সবশেষে বিষয়বস্তু উপস্থাপনা এলাকা লক করার জন্য স্ক্রোল-স্ন্যাপ। আমাদের কীবোর্ড ট্যাব অর্ডার অ্যাক্সেসযোগ্য এবং যেকোনো ইন্টারঅ্যাকশন গাইড স্বাভাবিকভাবেই ফোকাস করে। স্ক্রোল স্ন্যাপ কন্টেইনারগুলি তাদের কীবোর্ড থেকে একটি সুন্দর ক্যারোজেল শৈলী মিথস্ক্রিয়াও পায়।
ট্যাব হেডার <nav>
লেআউট
নেভি লিঙ্কগুলিকে একটি লাইনে বিছিয়ে দিতে হবে, কোন লাইন বিরতি ছাড়াই, উল্লম্বভাবে কেন্দ্রীভূত, এবং প্রতিটি লিঙ্ক আইটেম স্ক্রোল-স্ন্যাপ কন্টেইনারে স্ন্যাপ করা উচিত। 2021 CSS-এর জন্য দ্রুত কাজ!
<nav> <a></a> <a></a> <a></a> <a></a> </nav>
nav { display: flex; & a { scroll-snap-align: start; display: inline-flex; align-items: center; white-space: nowrap; } }
প্রতিটি লিঙ্ক শৈলী এবং মাপ নিজেই, তাই নেভি লেআউট শুধুমাত্র দিক এবং প্রবাহ নির্দিষ্ট করতে হবে। এনএভি আইটেমগুলিতে অনন্য প্রস্থগুলি ট্যাবগুলির মধ্যে পরিবর্তনকে মজাদার করে তোলে কারণ সূচকটি তার প্রস্থকে নতুন লক্ষ্যের সাথে সামঞ্জস্য করে। এখানে কতগুলি উপাদান রয়েছে তার উপর নির্ভর করে, ব্রাউজার একটি স্ক্রলবার রেন্ডার করবে কি না।
ট্যাব <section>
লেআউট
এই বিভাগটি একটি ফ্লেক্স আইটেম এবং স্থানের প্রভাবশালী ভোক্তা হতে হবে। এটিতে নিবন্ধগুলি স্থাপন করার জন্য কলাম তৈরি করতে হবে। আবার, CSS 2021 এর জন্য দ্রুত কাজ! block-size: 100%
এই উপাদানটিকে যতটা সম্ভব প্যারেন্ট পূরণ করতে প্রসারিত করে, তারপর তার নিজস্ব লেআউটের জন্য, এটি অভিভাবকের প্রস্থের 100%
কলামের একটি সিরিজ তৈরি করে। শতাংশ এখানে দুর্দান্ত কাজ করে কারণ আমরা অভিভাবকদের উপর শক্তিশালী সীমাবদ্ধতা লিখেছি।
<section> <article></article> <article></article> <article></article> <article></article> </section>
section { block-size: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 100%; }
এটা যেন আমরা বলছি "যতটা সম্ভব উল্লম্বভাবে প্রসারিত করুন, একটি চাপের উপায়ে" (হেডারটি মনে রাখবেন যেটি আমরা flex-shrink: 0
: এটি এই সম্প্রসারণ পুশের বিরুদ্ধে একটি প্রতিরক্ষা), যা একটি সারির উচ্চতা নির্ধারণ করে সম্পূর্ণ উচ্চতার কলামের সেট। auto-flow
শৈলী গ্রিডকে সবসময় একটি অনুভূমিক রেখায় বাচ্চাদের বাইরে রাখতে বলে, কোন মোড়ক নেই, ঠিক আমরা যা চাই; অভিভাবক জানালা উপচে পড়া.
আমার মাঝে মাঝে মাথা গুটিয়ে রাখা কঠিন লাগে! এই বিভাগের উপাদানটি একটি বাক্সে ফিট করা হয়েছে, তবে বাক্সের একটি সেটও তৈরি করেছে৷ আমি আশা করি ভিজ্যুয়াল এবং ব্যাখ্যা সাহায্য করছে.
ট্যাব <article>
লেআউট
ব্যবহারকারীর নিবন্ধের বিষয়বস্তু স্ক্রোল করতে সক্ষম হওয়া উচিত, এবং স্ক্রলবারগুলি কেবলমাত্র ওভারফ্লো হলেই দেখানো উচিত। এই নিবন্ধ উপাদান একটি ঝরঝরে অবস্থানে আছে. তারা একই সাথে একটি স্ক্রোল পিতামাতা এবং একটি স্ক্রোল শিশু। ব্রাউজার সত্যিই এখানে আমাদের জন্য কিছু জটিল স্পর্শ, মাউস এবং কীবোর্ড মিথস্ক্রিয়া পরিচালনা করছে।
<article> <h2></h2> <p></p> <p></p> <h2></h2> <p></p> <p></p> ... </article>
article { scroll-snap-align: start; overflow-y: auto; overscroll-behavior-y: contain; }
আমি নিবন্ধগুলি তাদের পিতামাতার স্ক্রলারের মধ্যে স্ন্যাপ করা বেছে নিয়েছি। আমি সত্যিই পছন্দ করি যে কীভাবে নেভিগেশন লিঙ্ক আইটেম এবং নিবন্ধ উপাদানগুলি তাদের নিজ নিজ স্ক্রোল কন্টেইনারগুলির ইনলাইন-শুরুতে স্ন্যাপ করে। এটি একটি সুরেলা সম্পর্কের মতো দেখায় এবং অনুভব করে।
নিবন্ধটি একটি গ্রিড চাইল্ড, এবং এটির আকার আমরা স্ক্রোল UX প্রদান করতে চাই এমন ভিউপোর্ট এলাকা হিসাবে পূর্বনির্ধারিত। এর মানে আমার এখানে কোন উচ্চতা বা প্রস্থের শৈলীর প্রয়োজন নেই, আমাকে শুধু সংজ্ঞায়িত করতে হবে কিভাবে এটি ওভারফ্লো হয়। আমি অটোতে ওভারফ্লো-ওয়াই সেট করেছি, এবং তারপরে সহজ ওভারস্ক্রোল-আচরণ বৈশিষ্ট্যের সাথে স্ক্রোল ইন্টারঅ্যাকশনগুলিও আটকেছি।
3টি স্ক্রোল এলাকা সংকলন
নীচে আমি আমার সিস্টেম সেটিংসে "সর্বদা স্ক্রলবার দেখাতে" বেছে নিয়েছি। আমি মনে করি লেআউটের জন্য এই সেটিংটি চালু করার সাথে কাজ করা দ্বিগুণ গুরুত্বপূর্ণ, কারণ লেআউট এবং স্ক্রোল অর্কেস্ট্রেশন পর্যালোচনা করা আমার জন্য।
আমি মনে করি এই কম্পোনেন্টে স্ক্রলবার নর্দমা দেখা স্পষ্টভাবে দেখাতে সাহায্য করে যে স্ক্রোল এলাকাগুলি কোথায়, তারা যে দিকটি সমর্থন করে এবং তারা কীভাবে একে অপরের সাথে যোগাযোগ করে। বিবেচনা করুন কিভাবে এই স্ক্রোল উইন্ডো ফ্রেমগুলির প্রতিটি একটি লেআউটে ফ্লেক্স বা গ্রিড পিতামাতা হয়।
DevTools আমাদের এটি কল্পনা করতে সাহায্য করতে পারে:
স্ক্রোল লেআউট সম্পূর্ণ: স্ন্যাপিং, গভীর লিঙ্কযোগ্য, এবং কীবোর্ড অ্যাক্সেসযোগ্য। UX বর্ধন, শৈলী এবং আনন্দের জন্য শক্তিশালী ভিত্তি।
বৈশিষ্ট্য হাইলাইট
স্ক্রোল করা শিশুরা আকার পরিবর্তনের সময় তাদের লক করা অবস্থান বজায় রাখে। এর মানে ডিভাইস রোটেট বা ব্রাউজার রিসাইজ করার সময় JavaScript-এর কিছু দেখার দরকার নেই। রেসপন্সিভ ব্যতীত অন্য যেকোনো মোড নির্বাচন করে এবং তারপর ডিভাইস ফ্রেমের আকার পরিবর্তন করে Chromium DevTools ডিভাইস মোডে এটি ব্যবহার করে দেখুন। লক্ষ্য করুন উপাদানটি দৃশ্যে থাকে এবং এর বিষয়বস্তু সহ লক করা থাকে। Chromium স্পেকের সাথে মেলে তাদের বাস্তবায়ন আপডেট করার পর থেকে এটি উপলব্ধ। এখানে এটি সম্পর্কে একটি ব্লগ পোস্ট .
অ্যানিমেশন
এখানে অ্যানিমেশন কাজের লক্ষ্য হল স্পষ্টভাবে UI প্রতিক্রিয়ার সাথে মিথস্ক্রিয়া লিঙ্ক করা। এটি ব্যবহারকারীকে তাদের (আশা করি) সমস্ত বিষয়বস্তুর নিরবচ্ছিন্ন আবিষ্কারের মাধ্যমে গাইড বা সহায়তা করে। আমি উদ্দেশ্য এবং শর্তসাপেক্ষে গতি যোগ করা হবে. ব্যবহারকারীরা এখন তাদের অপারেটিং সিস্টেমে তাদের গতি পছন্দগুলি নির্দিষ্ট করতে পারে, এবং আমি আমার ইন্টারফেসে তাদের পছন্দগুলির প্রতিক্রিয়া জানাতে পুরোপুরি উপভোগ করি।
আমি নিবন্ধ স্ক্রোল অবস্থানের সাথে একটি ট্যাব আন্ডারলাইন লিঙ্ক করা হবে. স্ন্যাপিং শুধুমাত্র সুন্দর সারিবদ্ধতা নয়, এটি একটি অ্যানিমেশনের শুরু এবং শেষকেও নোঙ্গর করে। এটি <nav>
কে রাখে, যা একটি মিনি-ম্যাপের মত কাজ করে, বিষয়বস্তুর সাথে সংযুক্ত থাকে। আমরা CSS এবং JS উভয় থেকে ব্যবহারকারীর গতি পছন্দ পরীক্ষা করব। বিবেচনা করা কয়েক মহান জায়গা আছে!
স্ক্রোল আচরণ
:target
এবং element.scrollIntoView()
উভয়ের গতি আচরণ উন্নত করার সুযোগ রয়েছে। ডিফল্টরূপে, এটা তাত্ক্ষণিক. ব্রাউজার শুধু স্ক্রোল অবস্থান সেট করে। আচ্ছা, যদি আমরা সেই স্ক্রোল পজিশনে ট্রানজিশন করতে চাই, সেখানে পলক ফেলার পরিবর্তে?
@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}
যেহেতু আমরা এখানে মোশন প্রবর্তন করছি, এবং গতি যা ব্যবহারকারী নিয়ন্ত্রণ করে না (যেমন স্ক্রোলিং), আমরা শুধুমাত্র এই স্টাইলটি প্রয়োগ করি যদি ব্যবহারকারীর অপারেটিং সিস্টেমে হ্রাসকৃত গতির আশেপাশে কোন পছন্দ না থাকে। এইভাবে, আমরা শুধুমাত্র যারা এটির সাথে ঠিক আছে তাদের জন্য স্ক্রোল মোশন চালু করি।
ট্যাব সূচক
এই অ্যানিমেশনের উদ্দেশ্য হল বিষয়বস্তুর অবস্থার সাথে সূচককে যুক্ত করতে সাহায্য করা। আমি সিদ্ধান্ত নিয়েছি যে ব্যবহারকারীরা কম গতি পছন্দ করেন তাদের জন্য ক্রসফেড border-bottom
শৈলী এবং একটি স্ক্রোল লিঙ্কযুক্ত স্লাইডিং + কালার ফেইড অ্যানিমেশন ব্যবহারকারীদের জন্য যারা গতির সাথে ঠিক আছে।
Chromium Devtools-এ, আমি পছন্দ টগল করতে পারি এবং 2টি ভিন্ন রূপান্তর শৈলী প্রদর্শন করতে পারি। আমি এটি নির্মাণ মজা একটি টন ছিল.
@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;
&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}
snap-tabs .snap-indicator {
visibility: hidden;
}
}
আমি .snap-indicator
লুকিয়ে রাখি যখন ব্যবহারকারী কম গতি পছন্দ করে যেহেতু আমার আর এটির প্রয়োজন নেই। তারপর আমি এটিকে border-block-end
শৈলী এবং একটি transition
দিয়ে প্রতিস্থাপন করি। এছাড়াও ট্যাব মিথস্ক্রিয়ায় লক্ষ্য করুন যে সক্রিয় নেভি আইটেমটিতে শুধুমাত্র একটি ব্র্যান্ড আন্ডারলাইন হাইলাইট নেই, তবে এটির পাঠ্যের রঙও গাঢ়। সক্রিয় উপাদানটিতে উচ্চতর পাঠ্য রঙের বৈসাদৃশ্য এবং একটি উজ্জ্বল আন্ডারলাইট অ্যাকসেন্ট রয়েছে।
CSS-এর মাত্র কয়েকটি অতিরিক্ত লাইন কাউকে দেখা অনুভব করবে (এই অর্থে যে আমরা চিন্তাভাবনা করে তাদের গতি পছন্দকে সম্মান করছি)। আমি এটা ভালোবাসি.
@scroll-timeline
উপরের বিভাগে আমি আপনাকে দেখিয়েছি কিভাবে আমি হ্রাসকৃত গতির ক্রসফেড শৈলীগুলি পরিচালনা করি এবং এই বিভাগে আমি আপনাকে দেখাব কিভাবে আমি সূচক এবং একটি স্ক্রোল এলাকা একসাথে সংযুক্ত করেছি। এটি পরবর্তী কিছু মজার পরীক্ষামূলক জিনিস। আমি আশা করি আপনি আমার মতোই উত্তেজিত।
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);
আমি প্রথমে জাভাস্ক্রিপ্ট থেকে ব্যবহারকারীর গতি পছন্দ চেক করি। যদি এর ফলাফল false
হয়, যার অর্থ ব্যবহারকারী হ্রাস গতি পছন্দ করে, তাহলে আমরা স্ক্রোল লিঙ্কিং মোশন প্রভাবগুলির কোনোটি চালাব না।
if (motionOK) {
// motion based animation code
}
এটি লেখার সময়, @scroll-timeline
এর জন্য ব্রাউজার সমর্থন কোনটিই নয়। এটি শুধুমাত্র পরীক্ষামূলক বাস্তবায়ন সহ একটি খসড়া বৈশিষ্ট্য । যদিও এটিতে একটি পলিফিল রয়েছে, যা আমি এই ডেমোতে ব্যবহার করি।
ScrollTimeline
যদিও CSS এবং JavaScript উভয়ই স্ক্রোল টাইমলাইন তৈরি করতে পারে, আমি জাভাস্ক্রিপ্টে নির্বাচন করেছি যাতে আমি অ্যানিমেশনে লাইভ উপাদান পরিমাপ ব্যবহার করতে পারি।
const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // scroll in the direction letters flow
fill: 'both', // bi-directional linking
});
আমি চাই 1টি জিনিস অন্যের স্ক্রোল পজিশন অনুসরণ করুক, এবং একটি ScrollTimeline
তৈরি করে আমি স্ক্রোল লিঙ্কের ড্রাইভারকে সংজ্ঞায়িত করি, scrollSource
। সাধারণত ওয়েবে একটি অ্যানিমেশন একটি গ্লোবাল টাইম ফ্রেম টিক এর বিপরীতে চলে, কিন্তু মেমরিতে একটি কাস্টম sectionScrollTimeline
সহ, আমি সেগুলি পরিবর্তন করতে পারি।
tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
অ্যানিমেশনের কীফ্রেমে প্রবেশ করার আগে, আমি মনে করি স্ক্রোলিং-এর অনুসরণকারীকে নির্দেশ করা গুরুত্বপূর্ণ, tabindicator
, একটি কাস্টম টাইমলাইনের উপর ভিত্তি করে অ্যানিমেটেড হবে, আমাদের বিভাগের স্ক্রোল৷ এটি সংযোগটি সম্পূর্ণ করে, কিন্তু চূড়ান্ত উপাদানটি অনুপস্থিত, মধ্যে অ্যানিমেট করার জন্য স্টেটফুল পয়েন্ট, যা কীফ্রেম নামেও পরিচিত।
ডায়নামিক কীফ্রেম
@scroll-timeline
সাথে অ্যানিমেট করার জন্য সত্যিই একটি শক্তিশালী বিশুদ্ধ ঘোষণামূলক CSS উপায় আছে, কিন্তু আমি যে অ্যানিমেশনটি বেছে নিয়েছি তা খুব গতিশীল ছিল। auto
প্রস্থের মধ্যে স্থানান্তর করার কোন উপায় নেই, এবং শিশুদের দৈর্ঘ্যের উপর ভিত্তি করে গতিশীলভাবে বেশ কয়েকটি কীফ্রেম তৈরি করার কোন উপায় নেই।
জাভাস্ক্রিপ্ট জানে কিভাবে সেই তথ্যটি পেতে হয়, তাই আমরা নিজেরাই শিশুদের উপর পুনরাবৃত্তি করব এবং রানটাইমে গণনা করা মানগুলি ধরব:
tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
প্রতিটি tabnavitem
জন্য, offsetLeft
অবস্থানটি ধ্বংস করুন এবং একটি স্ট্রিং প্রদান করুন যা এটিকে একটি translateX
মান হিসাবে ব্যবহার করে। এটি অ্যানিমেশনের জন্য 4টি রূপান্তর কীফ্রেম তৈরি করে। প্রস্থের জন্যও একই কাজ করা হয়, প্রত্যেককে জিজ্ঞাসা করা হয় এর গতিশীল প্রস্থ কত এবং তারপর এটি একটি কীফ্রেম মান হিসাবে ব্যবহৃত হয়।
আমার ফন্ট এবং ব্রাউজার পছন্দের উপর ভিত্তি করে এখানে উদাহরণ আউটপুট:
TranslateX কীফ্রেম:
[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)
// results in 4 array items, which represent 4 keyframe states
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]
প্রস্থ কীফ্রেম:
[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
// results in 4 array items, which represent 4 keyframe states
// ["121px", "117px", "226px", "67px"]
কৌশলটি সংক্ষিপ্ত করার জন্য, ট্যাব সূচকটি এখন সেকশন স্ক্রলারের স্ক্রোল স্ন্যাপ অবস্থানের উপর নির্ভর করে 4টি কীফ্রেম জুড়ে অ্যানিমেট করবে। স্ন্যাপ পয়েন্টগুলি আমাদের কীফ্রেমের মধ্যে স্পষ্ট বর্ণনা তৈরি করে এবং সত্যিই অ্যানিমেশনের সিঙ্ক্রোনাইজড অনুভূতি যোগ করে।
ব্যবহারকারী তাদের ইন্টারঅ্যাকশনের মাধ্যমে অ্যানিমেশনটি চালায়, সূচকের প্রস্থ এবং অবস্থান এক বিভাগ থেকে অন্য বিভাগে পরিবর্তিত হয়, স্ক্রোল দিয়ে পুরোপুরি ট্র্যাক করে।
আপনি হয়তো লক্ষ্য করেননি, কিন্তু হাইলাইট করা নেভিগেশন আইটেমটি নির্বাচিত হওয়ার কারণে আমি রঙের পরিবর্তনের জন্য খুব গর্বিত।
যখন হাইলাইট করা আইটেমটিতে আরও বৈসাদৃশ্য থাকে তখন অনির্বাচিত হালকা ধূসরটি আরও বেশি পুশ ব্যাক দেখায়। পাঠ্যের জন্য রঙ পরিবর্তন করা সাধারণ, যেমন হোভারে এবং যখন নির্বাচন করা হয়, তবে স্ক্রলে সেই রঙটি রূপান্তর করার পরবর্তী স্তর, আন্ডারলাইন নির্দেশকের সাথে সিঙ্ক্রোনাইজ করা হয়।
আমি এটি কিভাবে করেছি তা এখানে:
tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});
প্রতিটি ট্যাব নেভি লিঙ্কের জন্য এই নতুন রঙের অ্যানিমেশন প্রয়োজন, আন্ডারলাইন নির্দেশকের মতো একই স্ক্রোল টাইমলাইন ট্র্যাক করা। আমি আগের মতো একই টাইমলাইন ব্যবহার করি: যেহেতু এটির ভূমিকা হল স্ক্রলে একটি টিক নির্গত করা, তাই আমরা যেকোন ধরনের অ্যানিমেশনে সেই টিকটি ব্যবহার করতে পারি। আমি আগে যেমন করেছিলাম, আমি লুপে 4টি কীফ্রেম তৈরি করি এবং রঙ ফেরত দিই।
[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
// results in 4 array items, which represent 4 keyframe states
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]
কালার var(--text-active-color)
সহ কীফ্রেম লিঙ্কটিকে হাইলাইট করে, এবং অন্যথায় এটি একটি আদর্শ পাঠ্য রঙ। সেখানে নেস্টেড লুপ এটিকে তুলনামূলকভাবে সহজ করে তোলে, কারণ বাইরের লুপটি প্রতিটি নেভিটি আইটেম এবং ভিতরের লুপটি প্রতিটি নেভিটেমের ব্যক্তিগত কীফ্রেম। বাইরের লুপ উপাদানটি ভিতরের লুপের মতো একই কিনা তা আমি পরীক্ষা করি এবং কখন এটি নির্বাচন করা হয় তা জানতে এটি ব্যবহার করুন।
এইটা লিখে অনেক মজা পেলাম। এত
এমনকি আরও জাভাস্ক্রিপ্ট বর্ধন
এটি একটি অনুস্মারক মূল্য যে আমি আপনাকে এখানে যা দেখাচ্ছি তার মূলটি জাভাস্ক্রিপ্ট ছাড়াই কাজ করে। যে বলেছে, আসুন দেখি কিভাবে আমরা এটিকে উন্নত করতে পারি যখন জেএস পাওয়া যায়।
গভীর লিঙ্ক
ডিপ লিঙ্ক একটি মোবাইল শব্দ, কিন্তু আমি মনে করি ডিপ লিঙ্কের উদ্দেশ্য এখানে ট্যাবগুলির সাথে পূরণ করা হয়েছে যাতে আপনি সরাসরি একটি ট্যাবের বিষয়বস্তুতে একটি URL শেয়ার করতে পারেন৷ ব্রাউজারটি ইন-পেজ আইডিতে নেভিগেট করবে যা URL হ্যাশের সাথে মেলে। আমি খুঁজে পেয়েছি যে এই onload
হ্যান্ডলারটি প্ল্যাটফর্ম জুড়ে প্রভাব তৈরি করেছে।
window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}
স্ক্রোল শেষ সিঙ্ক্রোনাইজেশন
আমাদের ব্যবহারকারীরা সবসময় কীবোর্ডে ক্লিক বা ব্যবহার করে না, কখনও কখনও তারা কেবল বিনামূল্যে স্ক্রলিং করে, যেমন তাদের সক্ষম হওয়া উচিত। যখন সেকশন স্ক্রলারটি স্ক্রোল করা বন্ধ করে, এটি যেখানেই ল্যান্ড করে সেখানে উপরের নেভিগেশন বারে মিলিত হওয়া প্রয়োজন।
স্ক্রোল শেষের জন্য আমি কীভাবে অপেক্ষা করি তা এখানে: js tabsection.addEventListener('scroll', () => { clearTimeout(tabsection.scrollEndTimer); tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100); });
যখনই বিভাগগুলি স্ক্রোল করা হচ্ছে, সেখানে থাকলে বিভাগের সময়সীমাটি সাফ করুন এবং একটি নতুন শুরু করুন। যখন বিভাগগুলি স্ক্রোল করা বন্ধ করে, টাইমআউট সাফ করবেন না, এবং বিশ্রামের পরে 100ms ফায়ার করুন। যখন এটি ফায়ার হয়, কল ফাংশন যা ব্যবহারকারী কোথায় থামল তা খুঁজে বের করতে চায়।
const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];
matchingNavItem && setActiveTab(matchingNavItem);
};
স্ক্রলটি স্ন্যাপ করা হয়েছে বলে ধরে নিয়ে, স্ক্রোল এলাকার প্রস্থ থেকে বর্তমান স্ক্রোল অবস্থানকে ভাগ করলে একটি পূর্ণসংখ্যা হওয়া উচিত এবং দশমিক নয়। আমি তারপর এই গণনাকৃত সূচকের মাধ্যমে আমাদের ক্যাশে থেকে একটি নেভিটেম নেওয়ার চেষ্টা করি এবং যদি এটি কিছু খুঁজে পায়, আমি ম্যাচটিকে সক্রিয় করতে পাঠাব।
const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');
tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};
সক্রিয় ট্যাব সেট করা যে কোনো বর্তমানে সক্রিয় ট্যাব সাফ করে শুরু হয়, তারপর আগত নেভি আইটেমটিকে সক্রিয় অবস্থা বৈশিষ্ট্য প্রদান করে। scrollIntoView()
এর কলে CSS-এর সাথে একটি মজার মিথস্ক্রিয়া রয়েছে যা লক্ষ্য করার মতো।
.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
অনুভূমিক স্ক্রোল স্ন্যাপ ইউটিলিটি CSS-এ, আমরা একটি মিডিয়া ক্যোয়ারী নেস্ট করেছি যা ব্যবহারকারীর গতি সহনশীল হলে smooth
স্ক্রলিং প্রযোজ্য। জাভাস্ক্রিপ্ট অবাধে কল করতে পারে উপাদান স্ক্রোল করতে, এবং CSS ঘোষণামূলকভাবে UX পরিচালনা করতে পারে। বেশ আনন্দদায়ক সামান্য ম্যাচ তারা কখনও কখনও করা.
উপসংহার
এখন আপনি জানেন যে আমি কীভাবে এটি করেছি, আপনি কীভাবে করবেন?! এটি কিছু মজার উপাদান আর্কিটেকচারের জন্য তৈরি করে! কে তাদের প্রিয় ফ্রেমওয়ার্কে স্লট সহ 1ম সংস্করণ তৈরি করতে যাচ্ছে? 🙂
আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। একটি ত্রুটি তৈরি করুন, আমাকে আপনার সংস্করণ টুইট করুন , এবং আমি এটিকে নীচের সম্প্রদায়ের রিমিক্স বিভাগে যোগ করব৷
কমিউনিটি রিমিক্স
- @devnook , @rob_dodson , এবং @DasSurma ওয়েব কম্পোনেন্ট সহ: নিবন্ধ ।
- @jhvanderschee বোতাম সহ: কোডপেন ।
আইওএস এবং অ্যান্ড্রয়েড অ্যাপে পাওয়া ট্যাবগুলির অনুরূপ একটি ট্যাব উপাদান কীভাবে তৈরি করা যায় তার একটি মৌলিক ওভারভিউ।
এই পোস্টে আমি ওয়েবের জন্য একটি ট্যাব উপাদান তৈরি করার চিন্তাভাবনা শেয়ার করতে চাই যা প্রতিক্রিয়াশীল, একাধিক ডিভাইস ইনপুট সমর্থন করে এবং ব্রাউজার জুড়ে কাজ করে। ডেমো চেষ্টা করুন.
আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:
ওভারভিউ
ট্যাবগুলি ডিজাইন সিস্টেমের একটি সাধারণ উপাদান কিন্তু অনেক আকার এবং ফর্ম নিতে পারে। প্রথমে <frame>
উপাদানে তৈরি ডেস্কটপ ট্যাব ছিল, এবং এখন আমাদের কাছে বাটারি মোবাইল উপাদান রয়েছে যা পদার্থবিজ্ঞানের বৈশিষ্ট্যের উপর ভিত্তি করে বিষয়বস্তুকে অ্যানিমেট করে। তারা সবাই একই জিনিস করার চেষ্টা করছে: স্থান বাঁচান।
আজ, একটি ট্যাব ব্যবহারকারীর অভিজ্ঞতার অপরিহার্য বিষয় হল একটি বোতাম নেভিগেশন এলাকা যা একটি ডিসপ্লে ফ্রেমে বিষয়বস্তুর দৃশ্যমানতা টগল করে। অনেক ভিন্ন বিষয়বস্তু এলাকা একই স্থান ভাগ করে, কিন্তু শর্তসাপেক্ষে নেভিগেশন নির্বাচিত বোতাম উপর ভিত্তি করে উপস্থাপন করা হয়.
ওয়েব কৌশল
সব মিলিয়ে আমি এই উপাদানটিকে তৈরি করার জন্য বেশ সহজবোধ্য পেয়েছি, কয়েকটি সমালোচনামূলক ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্যগুলির জন্য ধন্যবাদ:
- উপযুক্ত স্ক্রোল স্টপ অবস্থানের সাথে মার্জিত সোয়াইপ এবং কীবোর্ড ইন্টারঅ্যাকশনের জন্য
scroll-snap-points
- ব্রাউজারের জন্য ইউআরএল হ্যাশের মাধ্যমে গভীর লিঙ্কগুলি ইন-পেজ স্ক্রোল অ্যাঙ্করিং এবং শেয়ারিং সমর্থন পরিচালনা করে
-
<a>
এবংid="#hash"
উপাদান মার্কআপের সাথে স্ক্রিন রিডার সমর্থন - ক্রসফেড ট্রানজিশন এবং ইনস্ট্যান্ট ইন-পেজ স্ক্রোলিং সক্ষম করার জন্য
prefers-reduced-motion
- ইন-ড্রাফ্ট
@scroll-timeline
ওয়েব বৈশিষ্ট্যটি নির্বাচিত ট্যাবটিকে গতিশীলভাবে আন্ডারলাইন এবং রঙ পরিবর্তন করার জন্য
এইচটিএমএল
মৌলিকভাবে, এখানে UX হল: একটি লিঙ্কে ক্লিক করুন, ইউআরএলটি নেস্টেড পৃষ্ঠার অবস্থার প্রতিনিধিত্ব করুন এবং তারপরে ব্রাউজার ম্যাচিং এলিমেন্টে স্ক্রোল করার সাথে সাথে বিষয়বস্তু এলাকা আপডেট দেখুন।
সেখানে কিছু স্ট্রাকচারাল কন্টেন্ট মেম্বার আছে: লিঙ্ক এবং :target
এস। আমাদের লিঙ্কগুলির একটি তালিকা প্রয়োজন, যেগুলির জন্য একটি <nav>
দুর্দান্ত, এবং <article>
উপাদানগুলির একটি তালিকা, যার জন্য একটি <section>
দুর্দান্ত। প্রতিটি লিঙ্ক হ্যাশ একটি বিভাগের সাথে মিলবে, ব্রাউজারকে অ্যাঙ্করিংয়ের মাধ্যমে জিনিসগুলি স্ক্রোল করতে দেয়।
উদাহরণস্বরূপ, একটি লিঙ্কে ক্লিক করলে তা স্বয়ংক্রিয়ভাবে ক্রোম 89-এ :target
নিবন্ধে ফোকাস করে, কোন JS প্রয়োজন হয় না। ব্যবহারকারী তারপর বরাবরের মতো তাদের ইনপুট ডিভাইস দিয়ে নিবন্ধের বিষয়বস্তু স্ক্রোল করতে পারেন। এটি প্রশংসাসূচক বিষয়বস্তু, যা মার্কআপে নির্দেশিত।
আমি ট্যাবগুলি সংগঠিত করতে নিম্নলিখিত মার্কআপ ব্যবহার করেছি:
<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>
আমি এই মত href
এবং id
বৈশিষ্ট্য সহ <a>
এবং <article>
উপাদানগুলির মধ্যে সংযোগ স্থাপন করতে পারি:
<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>
আমি পরবর্তীতে নিবন্ধগুলিকে মিশ্র পরিমাণে লরেমের সাথে এবং লিঙ্কগুলিকে একটি মিশ্র দৈর্ঘ্য এবং শিরোনামগুলির সেট দিয়ে পূরণ করেছি। বিষয়বস্তুর সাথে কাজ করার জন্য, আমরা লেআউট শুরু করতে পারি।
স্ক্রলিং লেআউট
এই উপাদানটিতে 3টি বিভিন্ন ধরণের স্ক্রোল এলাকা রয়েছে:
- নেভিগেশন (গোলাপী) অনুভূমিকভাবে স্ক্রোলযোগ্য
- বিষয়বস্তু এলাকা (নীল) অনুভূমিকভাবে স্ক্রোলযোগ্য
- প্রতিটি নিবন্ধ আইটেম (সবুজ) উল্লম্বভাবে স্ক্রোলযোগ্য।
স্ক্রোলিং এর সাথে জড়িত 2টি বিভিন্ন ধরণের উপাদান রয়েছে:
- একটি জানালা
সংজ্ঞায়িত মাত্রা সহ একটি বাক্স যাতেoverflow
সম্পত্তি শৈলী রয়েছে। - একটি oversized পৃষ্ঠ
এই লেআউটে, এটি তালিকার ধারক: নেভি লিঙ্ক, বিভাগ নিবন্ধ এবং নিবন্ধের বিষয়বস্তু।
<snap-tabs>
লেআউট
আমি যে শীর্ষ স্তরের বিন্যাসটি বেছে নিয়েছি তা হল ফ্লেক্স (ফ্লেক্সবক্স)। আমি column
দিকনির্দেশ সেট করেছি, তাই শিরোনাম এবং বিভাগ উল্লম্বভাবে অর্ডার করা হয়েছে। এটি আমাদের প্রথম স্ক্রোল উইন্ডো, এবং এটি ওভারফ্লো লুকিয়ে সবকিছু লুকিয়ে রাখে। শিরোনাম এবং বিভাগ শীঘ্রই ওভারস্ক্রোল নিয়োগ করবে, পৃথক অঞ্চল হিসাবে।
<snap-tabs> <header></header> <section></section> </snap-tabs>
snap-tabs { display: flex; flex-direction: column; /* establish primary containing box */ overflow: hidden; position: relative; & > section { /* be pushy about consuming all space */ block-size: 100%; } & > header { /* defend againstneeding 100% */ flex-shrink: 0; /* fixes cross browser quarks */ min-block-size: fit-content; } }
রঙিন 3-স্ক্রোল ডায়াগ্রামে ফিরে ইঙ্গিত করা:
-
<header>
এখন (গোলাপী) স্ক্রোল কন্টেইনার হতে প্রস্তুত। -
<section>
(নীল) স্ক্রোল কন্টেইনার হতে প্রস্তুত।
VisBug-এর সাহায্যে আমি নীচে যে ফ্রেমগুলি হাইলাইট করেছি সেগুলি আমাদের স্ক্রোল কন্টেনারগুলি তৈরি করা উইন্ডোগুলি দেখতে সাহায্য করে৷
ট্যাব <header>
লেআউট
পরবর্তী লেআউট প্রায় একই: আমি উল্লম্ব ক্রম তৈরি করতে ফ্লেক্স ব্যবহার করি।
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
লিঙ্কগুলির গ্রুপের সাথে অনুভূমিকভাবে ভ্রমণ করা উচিত এবং এই হেডার লেআউটটি সেই পর্যায়টি সেট করতে সহায়তা করে। এখানে কোন পরম অবস্থান উপাদান!
পরবর্তী, স্ক্রোল শৈলী. দেখা যাচ্ছে যে আমরা আমাদের 2টি অনুভূমিক স্ক্রোল এলাকার (শিরোনাম এবং বিভাগ) মধ্যে স্ক্রোল শৈলী ভাগ করতে পারি, তাই আমি একটি ইউটিলিটি ক্লাস তৈরি করেছি, .scroll-snap-x
।
.scroll-snap-x {
/* browser decide if x is ok to scroll and show bars on, y hidden */
overflow: auto hidden;
/* prevent scroll chaining on x scroll */
overscroll-behavior-x: contain;
/* scrolling should snap children on x */
scroll-snap-type: x mandatory;
@media (hover: none) {
scrollbar-width: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
প্রতিটির প্রয়োজন x অক্ষে ওভারফ্লো, ওভারস্ক্রোলকে আটকাতে স্ক্রোল কন্টেনমেন্ট, টাচ ডিভাইসের জন্য লুকানো স্ক্রলবার এবং সবশেষে বিষয়বস্তু উপস্থাপনা এলাকা লক করার জন্য স্ক্রোল-স্ন্যাপ। আমাদের কীবোর্ড ট্যাব অর্ডার অ্যাক্সেসযোগ্য এবং যেকোনো ইন্টারঅ্যাকশন গাইড স্বাভাবিকভাবেই ফোকাস করে। স্ক্রোল স্ন্যাপ কন্টেইনারগুলি তাদের কীবোর্ড থেকে একটি সুন্দর ক্যারোজেল শৈলী মিথস্ক্রিয়াও পায়।
ট্যাব হেডার <nav>
লেআউট
নেভি লিঙ্কগুলিকে একটি লাইনে বিছিয়ে দিতে হবে, কোন লাইন বিরতি ছাড়াই, উল্লম্বভাবে কেন্দ্রীভূত, এবং প্রতিটি লিঙ্ক আইটেম স্ক্রোল-স্ন্যাপ কন্টেইনারে স্ন্যাপ করা উচিত। 2021 CSS-এর জন্য দ্রুত কাজ!
<nav> <a></a> <a></a> <a></a> <a></a> </nav>
nav { display: flex; & a { scroll-snap-align: start; display: inline-flex; align-items: center; white-space: nowrap; } }
প্রতিটি লিঙ্ক শৈলী এবং মাপ নিজেই, তাই নেভি লেআউট শুধুমাত্র দিক এবং প্রবাহ নির্দিষ্ট করতে হবে। এনএভি আইটেমগুলিতে অনন্য প্রস্থগুলি ট্যাবগুলির মধ্যে পরিবর্তনকে মজাদার করে তোলে কারণ সূচকটি তার প্রস্থকে নতুন লক্ষ্যের সাথে সামঞ্জস্য করে। এখানে কতগুলি উপাদান রয়েছে তার উপর নির্ভর করে, ব্রাউজার একটি স্ক্রলবার রেন্ডার করবে কি না।
ট্যাব <section>
লেআউট
এই বিভাগটি একটি ফ্লেক্স আইটেম এবং স্থানের প্রভাবশালী ভোক্তা হতে হবে। এটিতে নিবন্ধগুলি স্থাপন করার জন্য কলাম তৈরি করতে হবে। আবার, CSS 2021 এর জন্য দ্রুত কাজ! block-size: 100%
এই উপাদানটিকে যতটা সম্ভব প্যারেন্ট পূরণ করতে প্রসারিত করে, তারপর তার নিজস্ব লেআউটের জন্য, এটি অভিভাবকের প্রস্থের 100%
কলামের একটি সিরিজ তৈরি করে। শতাংশ এখানে দুর্দান্ত কাজ করে কারণ আমরা অভিভাবকদের উপর শক্তিশালী সীমাবদ্ধতা লিখেছি।
<section> <article></article> <article></article> <article></article> <article></article> </section>
section { block-size: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 100%; }
এটা যেন আমরা বলছি "যতটা সম্ভব উল্লম্বভাবে প্রসারিত করুন, একটি চাপের উপায়ে" (হেডারটি মনে রাখবেন যেটি আমরা flex-shrink: 0
: এটি এই সম্প্রসারণ পুশের বিরুদ্ধে একটি প্রতিরক্ষা), যা একটি সারির উচ্চতা নির্ধারণ করে সম্পূর্ণ উচ্চতার কলামের সেট। auto-flow
শৈলী গ্রিডকে সবসময় একটি অনুভূমিক রেখায় বাচ্চাদের বাইরে রাখতে বলে, কোন মোড়ক নেই, ঠিক আমরা যা চাই; অভিভাবক জানালা উপচে পড়া.
আমার মাঝে মাঝে মাথা গুটিয়ে রাখা কঠিন লাগে! এই বিভাগের উপাদানটি একটি বাক্সে ফিট করা হয়েছে, তবে বাক্সের একটি সেটও তৈরি করেছে৷ আমি আশা করি ভিজ্যুয়াল এবং ব্যাখ্যা সাহায্য করছে.
ট্যাব <article>
লেআউট
ব্যবহারকারীর নিবন্ধের বিষয়বস্তু স্ক্রোল করতে সক্ষম হওয়া উচিত, এবং স্ক্রলবারগুলি কেবলমাত্র ওভারফ্লো হলেই দেখানো উচিত। এই নিবন্ধ উপাদান একটি ঝরঝরে অবস্থানে আছে. তারা একই সাথে একটি স্ক্রোল পিতামাতা এবং একটি স্ক্রোল শিশু। ব্রাউজার সত্যিই এখানে আমাদের জন্য কিছু জটিল স্পর্শ, মাউস এবং কীবোর্ড মিথস্ক্রিয়া পরিচালনা করছে।
<article> <h2></h2> <p></p> <p></p> <h2></h2> <p></p> <p></p> ... </article>
article { scroll-snap-align: start; overflow-y: auto; overscroll-behavior-y: contain; }
আমি নিবন্ধগুলি তাদের পিতামাতার স্ক্রলারের মধ্যে স্ন্যাপ করা বেছে নিয়েছি। আমি সত্যিই পছন্দ করি যে কীভাবে নেভিগেশন লিঙ্ক আইটেম এবং নিবন্ধ উপাদানগুলি তাদের নিজ নিজ স্ক্রোল কন্টেইনারগুলির ইনলাইন-শুরুতে স্ন্যাপ করে। এটি একটি সুরেলা সম্পর্কের মতো দেখায় এবং অনুভব করে।
নিবন্ধটি একটি গ্রিড চাইল্ড, এবং এটির আকার আমরা স্ক্রোল UX প্রদান করতে চাই এমন ভিউপোর্ট এলাকা হিসাবে পূর্বনির্ধারিত। এর মানে আমার এখানে কোন উচ্চতা বা প্রস্থের শৈলীর প্রয়োজন নেই, আমাকে শুধু সংজ্ঞায়িত করতে হবে কিভাবে এটি ওভারফ্লো হয়। আমি অটোতে ওভারফ্লো-ওয়াই সেট করেছি, এবং তারপরে সহজ ওভারস্ক্রোল-আচরণ বৈশিষ্ট্যের সাথে স্ক্রোল ইন্টারঅ্যাকশনগুলিও আটকেছি।
3টি স্ক্রোল এলাকা সংকলন
নীচে আমি আমার সিস্টেম সেটিংসে "সর্বদা স্ক্রলবার দেখাতে" বেছে নিয়েছি। আমি মনে করি লেআউটের জন্য এই সেটিংটি চালু করার সাথে কাজ করা দ্বিগুণ গুরুত্বপূর্ণ, কারণ লেআউট এবং স্ক্রোল অর্কেস্ট্রেশন পর্যালোচনা করা আমার জন্য।
আমি মনে করি এই কম্পোনেন্টে স্ক্রলবার নর্দমা দেখা স্পষ্টভাবে দেখাতে সাহায্য করে যে স্ক্রোল এলাকাগুলি কোথায়, তারা যে দিকটি সমর্থন করে এবং তারা কীভাবে একে অপরের সাথে যোগাযোগ করে। বিবেচনা করুন কিভাবে এই স্ক্রোল উইন্ডো ফ্রেমগুলির প্রতিটি একটি লেআউটে ফ্লেক্স বা গ্রিড পিতামাতা হয়।
DevTools আমাদের এটি কল্পনা করতে সাহায্য করতে পারে:
স্ক্রোল লেআউট সম্পূর্ণ: স্ন্যাপিং, গভীর লিঙ্কযোগ্য, এবং কীবোর্ড অ্যাক্সেসযোগ্য। UX বর্ধন, শৈলী এবং আনন্দের জন্য শক্তিশালী ভিত্তি।
বৈশিষ্ট্য হাইলাইট
স্ক্রোল করা শিশুরা আকার পরিবর্তনের সময় তাদের লক করা অবস্থান বজায় রাখে। এর মানে ডিভাইস রোটেট বা ব্রাউজার রিসাইজ করার সময় JavaScript-এর কিছু দেখার দরকার নেই। রেসপন্সিভ ব্যতীত অন্য যেকোনো মোড নির্বাচন করে এবং তারপর ডিভাইস ফ্রেমের আকার পরিবর্তন করে Chromium DevTools ডিভাইস মোডে এটি ব্যবহার করে দেখুন। লক্ষ্য করুন উপাদানটি দৃশ্যে থাকে এবং এর বিষয়বস্তু সহ লক করা থাকে। Chromium স্পেকের সাথে মেলে তাদের বাস্তবায়ন আপডেট করার পর থেকে এটি উপলব্ধ। এখানে এটি সম্পর্কে একটি ব্লগ পোস্ট .
অ্যানিমেশন
এখানে অ্যানিমেশন কাজের লক্ষ্য হল স্পষ্টভাবে UI প্রতিক্রিয়ার সাথে মিথস্ক্রিয়া লিঙ্ক করা। এটি ব্যবহারকারীকে তাদের (আশা করি) সমস্ত বিষয়বস্তুর নিরবচ্ছিন্ন আবিষ্কারের মাধ্যমে গাইড বা সহায়তা করে। আমি উদ্দেশ্য এবং শর্তসাপেক্ষে গতি যোগ করা হবে. ব্যবহারকারীরা এখন তাদের অপারেটিং সিস্টেমে তাদের গতি পছন্দগুলি নির্দিষ্ট করতে পারে, এবং আমি আমার ইন্টারফেসে তাদের পছন্দগুলির প্রতিক্রিয়া জানাতে পুরোপুরি উপভোগ করি।
আমি নিবন্ধ স্ক্রোল অবস্থানের সাথে একটি ট্যাব আন্ডারলাইন লিঙ্ক করা হবে. স্ন্যাপিং শুধুমাত্র সুন্দর সারিবদ্ধতা নয়, এটি একটি অ্যানিমেশনের শুরু এবং শেষকেও নোঙ্গর করে। এটি <nav>
কে রাখে, যা একটি মিনি-ম্যাপের মত কাজ করে, বিষয়বস্তুর সাথে সংযুক্ত থাকে। আমরা CSS এবং JS উভয় থেকে ব্যবহারকারীর গতি পছন্দ পরীক্ষা করব। বিবেচনা করা কয়েক মহান জায়গা আছে!
স্ক্রোল আচরণ
:target
এবং element.scrollIntoView()
উভয়ের গতি আচরণ উন্নত করার সুযোগ রয়েছে। ডিফল্টরূপে, এটা তাত্ক্ষণিক. ব্রাউজার শুধু স্ক্রোল অবস্থান সেট করে। আচ্ছা, যদি আমরা সেই স্ক্রোল পজিশনে ট্রানজিশন করতে চাই, সেখানে পলক ফেলার পরিবর্তে?
@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}
যেহেতু আমরা এখানে মোশন প্রবর্তন করছি, এবং গতি যা ব্যবহারকারী নিয়ন্ত্রণ করে না (যেমন স্ক্রোলিং), আমরা শুধুমাত্র এই স্টাইলটি প্রয়োগ করি যদি ব্যবহারকারীর অপারেটিং সিস্টেমে হ্রাসকৃত গতির আশেপাশে কোন পছন্দ না থাকে। এইভাবে, আমরা শুধুমাত্র যারা এটির সাথে ঠিক আছে তাদের জন্য স্ক্রোল মোশন চালু করি।
ট্যাব সূচক
এই অ্যানিমেশনের উদ্দেশ্য হল বিষয়বস্তুর অবস্থার সাথে সূচককে যুক্ত করতে সাহায্য করা। আমি সিদ্ধান্ত নিয়েছি যে ব্যবহারকারীরা কম গতি পছন্দ করেন তাদের জন্য ক্রসফেড border-bottom
শৈলী এবং একটি স্ক্রোল লিঙ্কযুক্ত স্লাইডিং + কালার ফেইড অ্যানিমেশন ব্যবহারকারীদের জন্য যারা গতির সাথে ঠিক আছে।
Chromium Devtools-এ, আমি পছন্দ টগল করতে পারি এবং 2টি ভিন্ন রূপান্তর শৈলী প্রদর্শন করতে পারি। আমি এটি নির্মাণ মজা একটি টন ছিল.
@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;
&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}
snap-tabs .snap-indicator {
visibility: hidden;
}
}
আমি .snap-indicator
লুকিয়ে রাখি যখন ব্যবহারকারী কম গতি পছন্দ করে যেহেতু আমার আর এটির প্রয়োজন নেই। তারপর আমি এটিকে border-block-end
শৈলী এবং একটি transition
দিয়ে প্রতিস্থাপন করি। এছাড়াও ট্যাব মিথস্ক্রিয়ায় লক্ষ্য করুন যে সক্রিয় নেভি আইটেমটিতে শুধুমাত্র একটি ব্র্যান্ড আন্ডারলাইন হাইলাইট নেই, তবে এটির পাঠ্যের রঙও গাঢ়। সক্রিয় উপাদানটিতে উচ্চতর পাঠ্য রঙের বৈসাদৃশ্য এবং একটি উজ্জ্বল আন্ডারলাইট অ্যাকসেন্ট রয়েছে।
CSS-এর মাত্র কয়েকটি অতিরিক্ত লাইন কাউকে দেখা অনুভব করবে (এই অর্থে যে আমরা চিন্তাভাবনা করে তাদের গতি পছন্দকে সম্মান করছি)। আমি এটা ভালোবাসি.
@scroll-timeline
উপরের বিভাগে আমি আপনাকে দেখিয়েছি কিভাবে আমি হ্রাসকৃত গতির ক্রসফেড শৈলীগুলি পরিচালনা করি এবং এই বিভাগে আমি আপনাকে দেখাব কিভাবে আমি সূচক এবং একটি স্ক্রোল এলাকা একসাথে সংযুক্ত করেছি। এটি পরবর্তী কিছু মজার পরীক্ষামূলক জিনিস। আমি আশা করি আপনি আমার মতোই উত্তেজিত।
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);
আমি প্রথমে জাভাস্ক্রিপ্ট থেকে ব্যবহারকারীর গতি পছন্দ চেক করি। যদি এর ফলাফল false
হয়, যার অর্থ ব্যবহারকারী হ্রাস গতি পছন্দ করে, তাহলে আমরা স্ক্রোল লিঙ্কিং মোশন প্রভাবগুলির কোনোটি চালাব না।
if (motionOK) {
// motion based animation code
}
এটি লেখার সময়, @scroll-timeline
এর জন্য ব্রাউজার সমর্থন কোনটিই নয়। এটি শুধুমাত্র পরীক্ষামূলক বাস্তবায়ন সহ একটি খসড়া বৈশিষ্ট্য । যদিও এটিতে একটি পলিফিল রয়েছে, যা আমি এই ডেমোতে ব্যবহার করি।
ScrollTimeline
যদিও CSS এবং JavaScript উভয়ই স্ক্রোল টাইমলাইন তৈরি করতে পারে, আমি জাভাস্ক্রিপ্টে নির্বাচন করেছি যাতে আমি অ্যানিমেশনে লাইভ উপাদান পরিমাপ ব্যবহার করতে পারি।
const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // scroll in the direction letters flow
fill: 'both', // bi-directional linking
});
আমি চাই 1টি জিনিস অন্যের স্ক্রোল পজিশন অনুসরণ করুক, এবং একটি ScrollTimeline
তৈরি করে আমি স্ক্রোল লিঙ্কের ড্রাইভারকে সংজ্ঞায়িত করি, scrollSource
। সাধারণত ওয়েবে একটি অ্যানিমেশন একটি গ্লোবাল টাইম ফ্রেম টিক এর বিপরীতে চলে, কিন্তু মেমরিতে একটি কাস্টম sectionScrollTimeline
সহ, আমি সেগুলি পরিবর্তন করতে পারি।
tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
অ্যানিমেশনের কীফ্রেমে প্রবেশ করার আগে, আমি মনে করি স্ক্রোলিং-এর অনুসরণকারীকে নির্দেশ করা গুরুত্বপূর্ণ, tabindicator
, একটি কাস্টম টাইমলাইনের উপর ভিত্তি করে অ্যানিমেটেড হবে, আমাদের বিভাগের স্ক্রোল৷ এটি সংযোগটি সম্পূর্ণ করে, কিন্তু চূড়ান্ত উপাদানটি অনুপস্থিত, মধ্যে অ্যানিমেট করার জন্য স্টেটফুল পয়েন্ট, যা কীফ্রেম নামেও পরিচিত।
ডায়নামিক কীফ্রেম
@scroll-timeline
সাথে অ্যানিমেট করার জন্য সত্যিই একটি শক্তিশালী বিশুদ্ধ ঘোষণামূলক CSS উপায় আছে, কিন্তু আমি যে অ্যানিমেশনটি বেছে নিয়েছি তা খুব গতিশীল ছিল। auto
প্রস্থের মধ্যে স্থানান্তর করার কোন উপায় নেই, এবং শিশুদের দৈর্ঘ্যের উপর ভিত্তি করে গতিশীলভাবে বেশ কয়েকটি কীফ্রেম তৈরি করার কোন উপায় নেই।
জাভাস্ক্রিপ্ট জানে কিভাবে সেই তথ্যটি পেতে হয়, তাই আমরা নিজেরাই শিশুদের উপর পুনরাবৃত্তি করব এবং রানটাইমে গণনা করা মানগুলি ধরব:
tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
প্রতিটি tabnavitem
জন্য, offsetLeft
অবস্থানটি ধ্বংস করে এবং এমন একটি স্ট্রিং ফিরিয়ে দেয় যা এটি translateX
মান হিসাবে ব্যবহার করে। এটি অ্যানিমেশনের জন্য 4 ট্রান্সফর্ম কীফ্রেম তৈরি করে। প্রস্থের জন্যও একই কাজ করা হয়, প্রত্যেককে তার গতিশীল প্রস্থ কী তা জিজ্ঞাসা করা হয় এবং তারপরে এটি কীফ্রেম মান হিসাবে ব্যবহৃত হয়।
আমার ফন্ট এবং ব্রাউজারের পছন্দগুলির উপর ভিত্তি করে এখানে উদাহরণ আউটপুট:
অনুবাদ কীফ্রেমস:
[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)
// results in 4 array items, which represent 4 keyframe states
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]
প্রস্থ কীফ্রেমস:
[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
// results in 4 array items, which represent 4 keyframe states
// ["121px", "117px", "226px", "67px"]
কৌশলটির সংক্ষিপ্তসার হিসাবে, ট্যাব সূচকটি এখন বিভাগের স্ক্রোলারের স্ক্রোল স্ন্যাপ অবস্থানের উপর নির্ভর করে 4 কীফ্রেমগুলি জুড়ে অ্যানিমেট করবে। স্ন্যাপ পয়েন্টগুলি আমাদের কীফ্রেমগুলির মধ্যে স্পষ্ট বর্ণনাকে তৈরি করে এবং অ্যানিমেশনের সিঙ্ক্রোনাইজড অনুভূতিতে সত্যই যুক্ত করে।
ব্যবহারকারী তাদের ইন্টারঅ্যাকশন দিয়ে অ্যানিমেশনটি চালিত করে, সূচকটির প্রস্থ এবং অবস্থানটি এক বিভাগ থেকে পরের অংশে পরিবর্তিত করে, স্ক্রোল দিয়ে পুরোপুরি ট্র্যাক করে।
আপনি খেয়াল নাও করতে পারেন, তবে হাইলাইট করা নেভিগেশন আইটেমটি নির্বাচিত হওয়ার সাথে সাথে আমি রঙের সংক্রমণের জন্য খুব গর্বিত।
হাইলাইট করা আইটেমটির আরও বৈপরীত্য থাকলে অনির্ধারিত হালকা ধূসর আরও পিছনে উপস্থিত হয়। এটি হোভার এবং যখন নির্বাচিত হওয়ার মতো পাঠ্যের জন্য রঙিন রঙের রূপান্তর করা সাধারণ, তবে এটি স্ক্রোলে সেই রঙটি রূপান্তর করা পরবর্তী স্তরের, আন্ডারলাইন সূচকটির সাথে সিঙ্ক্রোনাইজ করা।
আমি এটি কিভাবে করেছি তা এখানে:
tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});
প্রতিটি ট্যাব এনএভি লিঙ্কের জন্য এই নতুন রঙের অ্যানিমেশন প্রয়োজন, আন্ডারলাইন সূচক হিসাবে একই স্ক্রোল টাইমলাইন ট্র্যাক করে। আমি আগের মতো একই টাইমলাইনটি ব্যবহার করি: যেহেতু এটির ভূমিকাটি স্ক্রোলে একটি টিক নির্গত করা হয়, তাই আমরা যে কোনও ধরণের অ্যানিমেশনটিতে আমরা সেই টিকটি ব্যবহার করতে পারি। আমি আগে যেমন করেছি, আমি লুপে 4 টি কীফ্রেম তৈরি করি এবং রঙগুলি ফিরিয়ে দিই।
[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
// results in 4 array items, which represent 4 keyframe states
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]
রঙের var(--text-active-color)
সহ কীফ্রেমটি লিঙ্কটি হাইলাইট করে এবং এটি অন্যথায় একটি স্ট্যান্ডার্ড পাঠ্য রঙ। সেখানে নেস্টেড লুপটি তুলনামূলকভাবে সোজা করে তোলে, কারণ বাইরের লুপটি প্রতিটি এনএভি আইটেম এবং অভ্যন্তরীণ লুপটি প্রতিটি নাভিটেমের ব্যক্তিগত কীফ্রেম। আমি পরীক্ষা করে দেখি বাইরের লুপ উপাদানটি অভ্যন্তরীণ লুপের মতো একই কিনা এবং এটি কখন নির্বাচিত হবে তা জানতে এটি ব্যবহার করুন।
এইটা লিখে অনেক মজা পেলাম। এত
আরও জাভাস্ক্রিপ্ট বর্ধন
এটি একটি অনুস্মারক মূল্যবান যে আমি আপনাকে এখানে যা দেখিয়েছি তার মূলটি জাভাস্ক্রিপ্ট ছাড়াই কাজ করে। এই বলে যে, আসুন দেখুন যখন জেএস উপলব্ধ থাকে তখন আমরা কীভাবে এটি বাড়িয়ে তুলতে পারি।
গভীর লিঙ্ক
গভীর লিঙ্কগুলি একটি মোবাইল শব্দের বেশি, তবে আমি মনে করি গভীর লিঙ্কটির অভিপ্রায়টি এখানে ট্যাবগুলির সাথে দেখা হয়েছে যাতে আপনি সরাসরি একটি ট্যাবের সামগ্রীতে একটি ইউআরএল ভাগ করতে পারেন। ব্রাউজারটি ইউআরএল হ্যাশের সাথে মিলে যাওয়া আইডিতে নেভিগেট করতে পারে। আমি খুঁজে পেয়েছি এই onload
হ্যান্ডলারটি প্ল্যাটফর্মগুলি জুড়ে প্রভাব ফেলেছে।
window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}
স্ক্রোল শেষ সিঙ্ক্রোনাইজেশন
আমাদের ব্যবহারকারীরা সর্বদা কীবোর্ড ক্লিক বা ব্যবহার করে না, কখনও কখনও তারা কেবল বিনামূল্যে স্ক্রোলিং করে, কারণ তারা সক্ষম হওয়া উচিত। যখন বিভাগটি স্ক্রোলার স্ক্রোলিং বন্ধ করে দেয়, যেখানে শীর্ষ নেভিগেশন বারে এটি অবতরণ করা দরকার।
আমি কীভাবে স্ক্রোল শেষের জন্য অপেক্ষা করি তা এখানে: js tabsection.addEventListener('scroll', () => { clearTimeout(tabsection.scrollEndTimer); tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100); });
যখনই বিভাগগুলি স্ক্রোল করা হচ্ছে, সেখানে থাকলে বিভাগের সময়সীমাটি সাফ করুন এবং একটি নতুন শুরু করুন। বিভাগগুলি স্ক্রোল করা বন্ধ হয়ে গেলে, সময়সীমাটি সাফ করবেন না এবং বিশ্রামের পরে 100 মিমি ফায়ার করুন। যখন এটি আগুন লাগে, কল ফাংশন যা ব্যবহারকারী কোথায় থামল তা নির্ধারণ করতে চায়।
const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];
matchingNavItem && setActiveTab(matchingNavItem);
};
স্ক্রোলটি ছড়িয়ে পড়ে ধরে ধরে, স্ক্রোল অঞ্চলের প্রস্থ থেকে বর্তমান স্ক্রোল অবস্থানকে ভাগ করে নেওয়ার ফলে একটি পূর্ণসংখ্যা হতে হবে এবং দশমিক নয়। আমি তখন এই গণনা করা সূচকটির মাধ্যমে আমাদের ক্যাশে থেকে একটি নাভিটেম ধরার চেষ্টা করি এবং যদি এটি কিছু খুঁজে পায় তবে আমি ম্যাচটি সক্রিয় হওয়ার জন্য প্রেরণ করি।
const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');
tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};
সক্রিয় ট্যাব সেট করা কোনও বর্তমানে সক্রিয় ট্যাব সাফ করে শুরু হয়, তারপরে আগত এনএভি আইটেমটিকে সক্রিয় রাষ্ট্রের বৈশিষ্ট্য দেয়। scrollIntoView()
এর কলটিতে সিএসএসের সাথে একটি মজাদার ইন্টারঅ্যাকশন রয়েছে যা লক্ষণীয়।
.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
অনুভূমিক স্ক্রোল স্ন্যাপ ইউটিলিটি সিএসএসে, আমরা একটি মিডিয়া ক্যোয়ারিতে বাসা বেঁধেছি যা ব্যবহারকারী যদি গতি সহনশীল হয় তবে smooth
স্ক্রোলিং প্রয়োগ করে। জাভাস্ক্রিপ্ট নিখরচায় উপাদানগুলিকে দেখার জন্য কল করতে পারে এবং সিএসএস ইউএক্সকে ঘোষণামূলকভাবে পরিচালনা করতে পারে। তারা কখনও কখনও তৈরি করে বেশ আনন্দদায়ক ছোট্ট ম্যাচ।
উপসংহার
এখন আপনি জানেন যে আমি কীভাবে এটি করেছি, আপনি কীভাবে করবেন?! এটি কিছু মজাদার উপাদান আর্কিটেকচার তৈরি করে! কে তাদের প্রিয় কাঠামোর স্লট সহ 1 ম সংস্করণ তৈরি করতে চলেছে? 🙂
আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। একটি গ্লিচ তৈরি করুন, আমাকে আপনার সংস্করণটি টুইট করুন এবং আমি এটি নীচে সম্প্রদায় রিমিক্স বিভাগে যুক্ত করব।
কমিউনিটি রিমিক্স
- @ডিভনুক , @রোব_ডোডসন এবং ওয়েব উপাদানগুলির সাথে @ডাসুরমা : নিবন্ধ ।
- বোতামগুলির সাথে @জাভ্যান্ডারশি : কোডপেন ।
আইওএস এবং অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিতে পাওয়া অনুরূপ একটি ট্যাব উপাদান কীভাবে তৈরি করবেন তার একটি ভিত্তি ওভারভিউ।
এই পোস্টে আমি প্রতিক্রিয়াশীল ওয়েবের জন্য একটি ট্যাব উপাদান তৈরির বিষয়ে চিন্তাভাবনা ভাগ করে নিতে চাই, একাধিক ডিভাইস ইনপুট সমর্থন করে এবং ব্রাউজার জুড়ে কাজ করে। ডেমো চেষ্টা করুন.
আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:
ওভারভিউ
ট্যাবগুলি ডিজাইন সিস্টেমগুলির একটি সাধারণ উপাদান তবে অনেকগুলি আকার এবং ফর্ম নিতে পারে। প্রথমে <frame>
উপাদানটিতে নির্মিত ডেস্কটপ ট্যাবগুলি ছিল এবং এখন আমাদের কাছে বাটারি মোবাইল উপাদান রয়েছে যা পদার্থবিজ্ঞানের বৈশিষ্ট্যের ভিত্তিতে সামগ্রীকে অ্যানিমেট করে। তারা সকলেই একই কাজ করার চেষ্টা করছে: স্থান সংরক্ষণ করুন।
আজ, একটি ট্যাব ব্যবহারকারীর অভিজ্ঞতার প্রয়োজনীয়তা হ'ল একটি বোতাম নেভিগেশন অঞ্চল যা একটি ডিসপ্লে ফ্রেমে সামগ্রীর দৃশ্যমানতা টগল করে। অনেকগুলি বিভিন্ন সামগ্রী অঞ্চল একই স্থান ভাগ করে, তবে নেভিগেশনে নির্বাচিত বোতামের ভিত্তিতে শর্তাধীন উপস্থাপিত হয়।
Web Tactics
All in all I found this component pretty straightforward to build, thanks to a few critical web platform features:
-
scroll-snap-points
for elegant swipe and keyboard interactions with appropriate scroll stop positions - Deep links via URL hashes for browser handled in-page scroll anchoring and sharing support
- Screen reader support with
<a>
andid="#hash"
element markup -
prefers-reduced-motion
for enabling crossfade transitions and instant in-page scrolling - The in-draft
@scroll-timeline
web feature for dynamically underlining and color changing the selected tab
এইচটিএমএল
মৌলিকভাবে, এখানে ইউএক্সটি হ'ল: একটি লিঙ্ক ক্লিক করুন, ইউআরএলটি নেস্টেড পৃষ্ঠা রাষ্ট্রের প্রতিনিধিত্ব করুন এবং তারপরে কন্টেন্ট এরিয়া আপডেটটি ব্রাউজারটি ম্যাচিং উপাদানটিতে স্ক্রোল হিসাবে দেখুন।
There are some structural content members in there: links and :target
s. আমাদের লিঙ্কগুলির একটি তালিকা দরকার, যা একটি <nav>
এর জন্য দুর্দান্ত এবং <article>
উপাদানগুলির একটি তালিকা, যা একটি <section>
এর জন্য দুর্দান্ত। প্রতিটি লিঙ্ক হ্যাশ একটি বিভাগের সাথে মেলে, ব্রাউজারকে অ্যাঙ্করিংয়ের মাধ্যমে স্ক্রোল জিনিসগুলি দেয়।
উদাহরণস্বরূপ, একটি লিঙ্ক ক্লিক করা স্বয়ংক্রিয়ভাবে ফোকাস করে :target
নিবন্ধ, কোনও জেএসের প্রয়োজন নেই। এরপরে ব্যবহারকারীরা তাদের ইনপুট ডিভাইসের সাথে সর্বদা নিবন্ধের সামগ্রীটি স্ক্রোল করতে পারেন। এটি প্রশংসামূলক সামগ্রী, যেমন মার্কআপে নির্দেশিত।
আমি ট্যাবগুলি সংগঠিত করতে নিম্নলিখিত মার্কআপটি ব্যবহার করেছি:
<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>
আমি href
এবং id
বৈশিষ্ট্যগুলির সাথে <a>
এবং <article>
উপাদানগুলির মধ্যে সংযোগ স্থাপন করতে পারি:
<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>
এরপরে আমি নিবন্ধগুলি মিশ্রিত পরিমাণে লোরেম এবং একটি মিশ্র দৈর্ঘ্য এবং শিরোনামের চিত্র সেট সহ লিঙ্কগুলি পূরণ করেছি। সামগ্রীর সাথে কাজ করার সাথে সাথে আমরা বিন্যাস শুরু করতে পারি।
স্ক্রোলিং লেআউট
এই উপাদানটিতে 3 টি বিভিন্ন ধরণের স্ক্রোল অঞ্চল রয়েছে:
- নেভিগেশন (গোলাপী) অনুভূমিকভাবে স্ক্রোলযোগ্য
- সামগ্রী অঞ্চল (নীল) অনুভূমিকভাবে স্ক্রোলযোগ্য
- Each article item (green) is vertically scrollable.
স্ক্রোলিংয়ের সাথে জড়িত 2 টি বিভিন্ন ধরণের উপাদান রয়েছে:
- একটি জানালা
সংজ্ঞায়িত মাত্রা সহ একটি বাক্স যাoverflow
সম্পত্তি শৈলী রয়েছে। - একটি বড় আকারের পৃষ্ঠ
এই বিন্যাসে, এটি তালিকার পাত্রে: এনএভি লিঙ্কগুলি, বিভাগ নিবন্ধ এবং নিবন্ধ সামগ্রী।
<snap-tabs>
লেআউট
আমি যে শীর্ষ স্তরের বিন্যাসটি বেছে নিয়েছি তা হ'ল ফ্লেক্স (ফ্লেক্সবক্স)। আমি column
দিকটি সেট করেছি, সুতরাং শিরোনাম এবং বিভাগটি উল্লম্বভাবে অর্ডার করা হয়েছে। এটি আমাদের প্রথম স্ক্রোল উইন্ডো, এবং এটি ওভারফ্লো লুকানো সমস্ত কিছু লুকিয়ে রাখে। শিরোনাম এবং বিভাগটি শীঘ্রই পৃথক অঞ্চল হিসাবে ওভারক্রোল নিয়োগ করবে।
<snap-tabs> <header></header> <section></section> </snap-tabs>
snap-tabs { display: flex; flex-direction: column; /* establish primary containing box */ overflow: hidden; position: relative; & > section { /* be pushy about consuming all space */ block-size: 100%; } & > header { /* defend againstneeding 100% */ flex-shrink: 0; /* fixes cross browser quarks */ min-block-size: fit-content; } }
রঙিন 3-স্ক্রোল ডায়াগ্রামের দিকে ফিরে ইশারা করা:
-
<header>
এখন (গোলাপী) স্ক্রোল ধারক হিসাবে প্রস্তুত। -
<section>
(নীল) স্ক্রোল ধারক হতে প্রস্তুত।
ভিসবাগের সাথে নীচে আমি যে ফ্রেমগুলি হাইলাইট করেছি তা আমাদের স্ক্রোল পাত্রে তৈরি উইন্ডোগুলি দেখতে সহায়তা করে।
ট্যাব <header>
বিন্যাস
পরবর্তী লেআউটটি প্রায় একই রকম: আমি উল্লম্ব ক্রম তৈরি করতে ফ্লেক্স ব্যবহার করি।
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
এখানে কোনও পরম অবস্থানযুক্ত উপাদান নেই!
এরপরে, স্ক্রোল শৈলী। দেখা যাচ্ছে যে আমরা আমাদের 2 টি অনুভূমিক স্ক্রোল অঞ্চল (শিরোনাম এবং বিভাগ) এর মধ্যে স্ক্রোল স্টাইলগুলি ভাগ করতে পারি, তাই আমি একটি ইউটিলিটি ক্লাস তৈরি করেছি, .scroll-snap-x
।
.scroll-snap-x {
/* browser decide if x is ok to scroll and show bars on, y hidden */
overflow: auto hidden;
/* prevent scroll chaining on x scroll */
overscroll-behavior-x: contain;
/* scrolling should snap children on x */
scroll-snap-type: x mandatory;
@media (hover: none) {
scrollbar-width: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
প্রতিটি এক্স অক্ষের উপর ওভারফ্লো প্রয়োজন, ওভারক্রোল ফাঁদে ফেলার জন্য স্ক্রোল কনটেন্টমেন্ট, টাচ ডিভাইসের জন্য লুকানো স্ক্রোলবার এবং শেষ পর্যন্ত সামগ্রী উপস্থাপনার ক্ষেত্রগুলি লক করার জন্য স্ক্রোল-এসএনএপি। আমাদের কীবোর্ড ট্যাব অর্ডার অ্যাক্সেসযোগ্য এবং যে কোনও ইন্টারঅ্যাকশন গাইড প্রাকৃতিকভাবে ফোকাস করে। স্ক্রোল স্ন্যাপ পাত্রে তাদের কীবোর্ড থেকে একটি দুর্দান্ত ক্যারোসেল স্টাইলের ইন্টারঅ্যাকশনও পান।
ট্যাব শিরোনাম <nav>
লেআউট
NAV লিঙ্কগুলি একটি লাইনে রাখা দরকার, কোনও লাইন বিরতি ছাড়াই, উল্লম্বভাবে কেন্দ্রিক এবং প্রতিটি লিঙ্ক আইটেমটি স্ক্রোল-এসএনএপি ধারকটিতে স্ন্যাপ করা উচিত। 2021 সিএসএসের জন্য সুইফট কাজ!
<nav> <a></a> <a></a> <a></a> <a></a> </nav>
nav { display: flex; & a { scroll-snap-align: start; display: inline-flex; align-items: center; white-space: nowrap; } }
প্রতিটি লিঙ্ক শৈলী এবং আকার নিজেই, তাই এনএভি লেআউটটির কেবল দিকনির্দেশ এবং প্রবাহ নির্দিষ্ট করতে হবে। এনএভি আইটেমগুলিতে অনন্য প্রস্থগুলি ট্যাবগুলির মধ্যে রূপান্তরকে মজাদার করে তোলে কারণ সূচকটি তার প্রস্থকে নতুন লক্ষ্যে সামঞ্জস্য করে। এখানে কতগুলি উপাদান রয়েছে তার উপর নির্ভর করে ব্রাউজারটি একটি স্ক্রোলবার রেন্ডার করবে বা না করে।
ট্যাব <section>
লেআউট
এই বিভাগটি একটি ফ্লেক্স আইটেম এবং স্থানের প্রভাবশালী গ্রাহক হওয়া দরকার। নিবন্ধগুলিতে স্থাপনের জন্য এটি কলাম তৈরি করতে হবে। আবার, সিএসএস 2021 এর জন্য সুইফট কাজ! block-size: 100%
এই উপাদানটিকে যতটা সম্ভব পিতামাতাকে পূরণ করতে প্রসারিত করে, তারপরে তার নিজস্ব বিন্যাসের জন্য, এটি কলামগুলির একটি সিরিজ তৈরি করে যা পিতামাতার 100%
প্রস্থ। শতাংশ এখানে দুর্দান্ত কাজ করে কারণ আমরা পিতামাতার উপর দৃ strong ় বাধা লিখেছি।
<section> <article></article> <article></article> <article></article> <article></article> </section>
section { block-size: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 100%; }
দেখে মনে হচ্ছে আমরা "যতটা সম্ভব উল্লম্বভাবে প্রসারিত করুন, একটি ধোঁয়াটে উপায়ে" (আমরা flex-shrink: 0
: এটি এই সম্প্রসারণ ধাক্কাটির বিরুদ্ধে একটি প্রতিরক্ষা), যা এ এর জন্য সারি উচ্চতা নির্ধারণ করে পূর্ণ উচ্চতার কলামগুলির সেট। auto-flow
স্টাইলটি গ্রিডকে সর্বদা একটি অনুভূমিক লাইনে বাচ্চাদের রাখার জন্য বলে, কোনও মোড়ানো নেই, আমরা ঠিক কী চাই; পিতামাতার উইন্ডোটি উপচে পড়তে।
আমি মাঝে মাঝে আমার মাথা গুটিয়ে রাখা কঠিন মনে করি! এই বিভাগের উপাদানটি একটি বাক্সে উপযুক্ত, তবে বাক্সগুলির একটি সেটও তৈরি করেছে। আমি আশা করি ভিজ্যুয়াল এবং ব্যাখ্যাগুলি সহায়তা করছে।
ট্যাব <article>
বিন্যাস
ব্যবহারকারীর নিবন্ধ সামগ্রীটি স্ক্রোল করতে সক্ষম হওয়া উচিত এবং স্ক্রোলবারগুলি কেবল তখনই প্রদর্শিত হবে যদি ওভারফ্লো থাকে। এই নিবন্ধ উপাদানগুলি একটি ঝরঝরে অবস্থানে রয়েছে। তারা একই সাথে একটি স্ক্রোল পিতামাতা এবং একটি স্ক্রোল শিশু। ব্রাউজারটি এখানে আমাদের জন্য কিছু জটিল স্পর্শ, মাউস এবং কীবোর্ড ইন্টারঅ্যাকশনগুলি পরিচালনা করছে।
<article> <h2></h2> <p></p> <p></p> <h2></h2> <p></p> <p></p> ... </article>
article { scroll-snap-align: start; overflow-y: auto; overscroll-behavior-y: contain; }
আমি তাদের পিতামাতার স্ক্রোলারের মধ্যে নিবন্ধগুলি স্ন্যাপ করা বেছে নিয়েছি। আমি সত্যিই পছন্দ করি কীভাবে নেভিগেশন লিঙ্ক আইটেমগুলি এবং নিবন্ধের উপাদানগুলি তাদের নিজ নিজ স্ক্রোল পাত্রে ইনলাইন-স্টার্টে স্ন্যাপ করে। এটি সুরেলা সম্পর্কের মতো দেখায় এবং অনুভব করে।
নিবন্ধটি একটি গ্রিড শিশু, এবং এর আকারটি ভিউপোর্ট অঞ্চল হিসাবে আমরা স্ক্রোল ইউএক্স সরবরাহ করতে চাই তা পূর্বনির্ধারিত। এর অর্থ এখানে আমার কোনও উচ্চতা বা প্রস্থের শৈলীর দরকার নেই, এটি কীভাবে উপচে পড়েছে তা আমার কেবল সংজ্ঞায়িত করতে হবে। আমি অটোতে ওভারফ্লো-ওয়াই সেট করেছি এবং তারপরে হ্যান্ডি ওভারক্রোল-আচরণগত সম্পত্তি দিয়ে স্ক্রোল ইন্টারঅ্যাকশনগুলিও ফাঁদে ফেলেছি।
3 স্ক্রোল অঞ্চল পুনরুদ্ধার
নীচে আমি আমার সিস্টেম সেটিংসে "সর্বদা স্ক্রোলবারগুলি দেখান" এ বেছে নিয়েছি। আমি মনে করি লেআউটটির পক্ষে এই সেটিংটি চালু করার সাথে কাজ করা দ্বিগুণ গুরুত্বপূর্ণ, কারণ আমার লেআউট এবং স্ক্রোল অর্কেস্টেশন পর্যালোচনা করা আমার পক্ষে।
আমি মনে করি এই উপাদানটিতে স্ক্রোলবার গটারটি দেখতে স্ক্রোল অঞ্চলগুলি কোথায় রয়েছে, তারা যে দিকটি সমর্থন করে এবং কীভাবে তারা একে অপরের সাথে যোগাযোগ করে তা স্পষ্টভাবে দেখাতে সহায়তা করে। এই স্ক্রোল উইন্ডো ফ্রেমগুলির প্রতিটি কীভাবে কোনও লেআউটে ফ্লেক্স বা গ্রিড পিতামাতাকে কীভাবে বিবেচনা করুন।
ডেভটুলগুলি আমাদের এটি কল্পনা করতে সহায়তা করতে পারে:
স্ক্রোল লেআউটগুলি সম্পূর্ণ: স্ন্যাপিং, গভীর লিঙ্কেবল এবং কীবোর্ড অ্যাক্সেসযোগ্য। ইউএক্স বর্ধন, শৈলী এবং আনন্দের জন্য শক্তিশালী ভিত্তি।
বৈশিষ্ট্য হাইলাইট
স্ক্রোল স্ন্যাপড শিশুরা পুনরায় আকার দেওয়ার সময় তাদের লক অবস্থান বজায় রাখে। এর অর্থ জাভাস্ক্রিপ্টে ডিভাইস ঘোরানো বা ব্রাউজারের আকার পরিবর্তন করার জন্য কোনও কিছু দেখার প্রয়োজন হবে না। প্রতিক্রিয়াশীল ব্যতীত অন্য কোনও মোড নির্বাচন করে এবং তারপরে ডিভাইস ফ্রেমকে পুনরায় আকার দেওয়ার মাধ্যমে ক্রোমিয়াম ডিভটুলস ডিভাইস মোডে এটি ব্যবহার করে দেখুন। লক্ষ্য করুন উপাদানটি দেখার মধ্যে থাকে এবং এর সামগ্রী সহ লক করা আছে। ক্রোমিয়াম স্পেকের সাথে মেলে তাদের বাস্তবায়ন আপডেট করার পর থেকে এটি উপলব্ধ। এটি সম্পর্কে একটি ব্লগ পোস্ট এখানে।
অ্যানিমেশন
এখানে অ্যানিমেশন কাজের লক্ষ্যটি হ'ল ইউআই প্রতিক্রিয়ার সাথে স্পষ্টভাবে ইন্টারঅ্যাকশনগুলিকে লিঙ্ক করা। এটি ব্যবহারকারীকে তাদের (আশাবাদী) সমস্ত সামগ্রীর বিরামবিহীন আবিষ্কারের মাধ্যমে গাইড বা সহায়তা করতে সহায়তা করে। আমি উদ্দেশ্য এবং শর্তসাপেক্ষে গতি যোগ করব। ব্যবহারকারীরা এখন তাদের অপারেটিং সিস্টেমে তাদের গতির পছন্দগুলি নির্দিষ্ট করতে পারেন এবং আমি আমার ইন্টারফেসগুলিতে তাদের পছন্দগুলির প্রতিক্রিয়া জানাতে পুরোপুরি উপভোগ করি।
আমি নিবন্ধ স্ক্রোল অবস্থানের সাথে একটি ট্যাব আন্ডারলাইন লিঙ্ক করব। স্নেপিং কেবল সুন্দর প্রান্তিককরণ নয়, এটি একটি অ্যানিমেশনের শুরু এবং শেষকেও নোঙ্গর করে। এটি <nav>
রাখে, যা একটি মিনি-মানচিত্রের মতো কাজ করে, সামগ্রীর সাথে সংযুক্ত। আমরা সিএসএস এবং জেএস উভয় থেকে ব্যবহারকারীর গতি পছন্দটি পরীক্ষা করব। বিবেচ্য হওয়ার জন্য কয়েকটি দুর্দান্ত জায়গা আছে!
স্ক্রোল আচরণ
উভয়ের গতি আচরণ বাড়ানোর একটি সুযোগ রয়েছে :target
এবং element.scrollIntoView()
। ডিফল্টরূপে, এটি তাত্ক্ষণিক। ব্রাউজারটি কেবল স্ক্রোল অবস্থান সেট করে। ঠিক আছে, আমরা যদি সেখানে ব্লিঙ্কের পরিবর্তে সেই স্ক্রোল অবস্থানে স্থানান্তর করতে চাই তবে কী হবে?
@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}
যেহেতু আমরা এখানে গতি প্রবর্তন করছি, এবং গতি যা ব্যবহারকারী নিয়ন্ত্রণ করে না (যেমন স্ক্রোলিংয়ের মতো), আমরা কেবলমাত্র এই স্টাইলটি প্রয়োগ করি যদি ব্যবহারকারীর হ্রাস গতির চারপাশে তাদের অপারেটিং সিস্টেমে কোনও পছন্দ না থাকে। এইভাবে, আমরা কেবল এটির সাথে ঠিক থাকা লোকদের জন্য স্ক্রোল গতি প্রবর্তন করি।
ট্যাব সূচক
এই অ্যানিমেশনের উদ্দেশ্য হ'ল সূচকটিকে সামগ্রীর অবস্থার সাথে যুক্ত করতে সহায়তা করা। আমি হ্রাস গতি পছন্দকারী ব্যবহারকারীদের জন্য ক্রসফেড border-bottom
শৈলীর রঙ করার সিদ্ধান্ত নিয়েছি এবং গতির সাথে ঠিক আছেন এমন ব্যবহারকারীদের জন্য একটি স্ক্রোল লিঙ্কযুক্ত স্লাইডিং + রঙিন বিবর্ণ অ্যানিমেশন।
ক্রোমিয়াম ডিভটুলগুলিতে, আমি পছন্দটি টগল করতে পারি এবং 2 টি পৃথক রূপান্তর শৈলী প্রদর্শন করতে পারি। আমি এটি তৈরি করতে একটি টন মজা ছিল।
@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;
&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}
snap-tabs .snap-indicator {
visibility: hidden;
}
}
আমার আর প্রয়োজন নেই বলে ব্যবহারকারী যখন হ্রাস গতি পছন্দ করেন তখন আমি .snap-indicator
টি লুকিয়ে রাখি। তারপরে আমি এটিকে border-block-end
শৈলী এবং একটি transition
দিয়ে প্রতিস্থাপন করি। এছাড়াও ট্যাবগুলির মিথস্ক্রিয়ায় লক্ষ্য করুন যে সক্রিয় এনএভি আইটেমটিতে কেবল একটি ব্র্যান্ড আন্ডারলাইন হাইলাইট নেই, তবে এটির পাঠ্যের রঙটিও আরও গা er ়। সক্রিয় উপাদানটির উচ্চতর পাঠ্য রঙের বিপরীতে এবং একটি উজ্জ্বল আন্ডারলাইট অ্যাকসেন্ট রয়েছে।
সিএসএসের মাত্র কয়েকটি অতিরিক্ত লাইন কাউকে দেখে মনে করবে (এই অর্থে যে আমরা চিন্তাভাবনা করে তাদের গতির পছন্দগুলিকে সম্মান করছি)। আমি এটা ভালোবাসি.
@scroll-timeline
উপরের বিভাগে আমি আপনাকে দেখিয়েছি যে আমি কীভাবে হ্রাস মোশন ক্রসফ্যাড স্টাইলগুলি পরিচালনা করব এবং এই বিভাগে আমি আপনাকে দেখাব যে আমি কীভাবে সূচক এবং একটি স্ক্রোল অঞ্চলকে একসাথে সংযুক্ত করেছি। এটি পরবর্তী কিছু মজাদার পরীক্ষামূলক জিনিস। আমি আশা করি আপনি আমার মতো উত্তেজিত।
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);
আমি প্রথমে জাভাস্ক্রিপ্ট থেকে ব্যবহারকারীর গতি পছন্দটি পরীক্ষা করি। যদি এর ফলাফলটি false
হয়, যার অর্থ ব্যবহারকারী হ্রাস গতি পছন্দ করে, তবে আমরা মোশন এফেক্টগুলির সংযোগকারী কোনও স্ক্রোল চালাব না।
if (motionOK) {
// motion based animation code
}
এটি লেখার সময়, @scroll-timeline
জন্য ব্রাউজার সমর্থন কোনওটি নয়। এটি কেবল পরীক্ষামূলক বাস্তবায়ন সহ একটি খসড়া স্পেক । যদিও এটি একটি পলিফিল রয়েছে, যা আমি এই ডেমোতে ব্যবহার করি।
ScrollTimeline
যদিও সিএসএস এবং জাভাস্ক্রিপ্ট উভয়ই স্ক্রোল টাইমলাইন তৈরি করতে পারে, আমি জাভাস্ক্রিপ্টে বেছে নিয়েছি যাতে আমি অ্যানিমেশনটিতে লাইভ উপাদান পরিমাপ ব্যবহার করতে পারি।
const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // scroll in the direction letters flow
fill: 'both', // bi-directional linking
});
আমি 1 টি জিনিস অন্যের স্ক্রোল অবস্থান অনুসরণ করতে চাই এবং একটি ScrollTimeline
তৈরি করে আমি স্ক্রোল লিঙ্ক, scrollSource
ড্রাইভারকে সংজ্ঞায়িত করি। সাধারণত ওয়েবে একটি অ্যানিমেশন বিশ্বব্যাপী সময় ফ্রেমের টিকের বিপরীতে চলে তবে মেমরিতে একটি কাস্টম sectionScrollTimeline
দিয়ে আমি সেগুলি পরিবর্তন করতে পারি।
tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
আমি অ্যানিমেশনের কীফ্রেমগুলিতে প্রবেশের আগে, আমি মনে করি যে স্ক্রোলিং, tabindicator
অনুসারীকে আমাদের বিভাগের স্ক্রোলের উপর ভিত্তি করে অ্যানিমেটেড করা হবে। এটি সংযোগটি সম্পূর্ণ করে, তবে চূড়ান্ত উপাদানটি অনুপস্থিত, এর মধ্যে অ্যানিমেট করার জন্য রাষ্ট্রীয় পয়েন্টগুলি অনুপস্থিত, যা কীফ্রেমস নামেও পরিচিত।
গতিশীল কীফ্রেম
@scroll-timeline
দিয়ে অ্যানিমেট করার জন্য একটি সত্যই শক্তিশালী খাঁটি ঘোষণামূলক সিএসএস উপায় রয়েছে, তবে আমি যে অ্যানিমেশনটি বেছে নিয়েছি তা খুব গতিশীল ছিল। auto
প্রস্থের মধ্যে পরিবর্তনের কোনও উপায় নেই এবং বাচ্চাদের দৈর্ঘ্যের উপর ভিত্তি করে গতিশীলভাবে বেশ কয়েকটি কীফ্রেম তৈরি করার কোনও উপায় নেই।
জাভাস্ক্রিপ্ট যদিও সেই তথ্যটি কীভাবে পেতে পারে তা জানে, তাই আমরা নিজেরাই বাচ্চাদের উপর পুনরাবৃত্তি করব এবং রানটাইমে গণিত মানগুলি ধরব:
tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
প্রতিটি tabnavitem
জন্য, offsetLeft
অবস্থানটি ধ্বংস করে এবং এমন একটি স্ট্রিং ফিরিয়ে দেয় যা এটি translateX
মান হিসাবে ব্যবহার করে। এটি অ্যানিমেশনের জন্য 4 ট্রান্সফর্ম কীফ্রেম তৈরি করে। প্রস্থের জন্যও একই কাজ করা হয়, প্রত্যেককে তার গতিশীল প্রস্থ কী তা জিজ্ঞাসা করা হয় এবং তারপরে এটি কীফ্রেম মান হিসাবে ব্যবহৃত হয়।
আমার ফন্ট এবং ব্রাউজারের পছন্দগুলির উপর ভিত্তি করে এখানে উদাহরণ আউটপুট:
অনুবাদ কীফ্রেমস:
[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)
// results in 4 array items, which represent 4 keyframe states
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]
প্রস্থ কীফ্রেমস:
[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
// results in 4 array items, which represent 4 keyframe states
// ["121px", "117px", "226px", "67px"]
কৌশলটির সংক্ষিপ্তসার হিসাবে, ট্যাব সূচকটি এখন বিভাগের স্ক্রোলারের স্ক্রোল স্ন্যাপ অবস্থানের উপর নির্ভর করে 4 কীফ্রেমগুলি জুড়ে অ্যানিমেট করবে। স্ন্যাপ পয়েন্টগুলি আমাদের কীফ্রেমগুলির মধ্যে স্পষ্ট বর্ণনাকে তৈরি করে এবং অ্যানিমেশনের সিঙ্ক্রোনাইজড অনুভূতিতে সত্যই যুক্ত করে।
ব্যবহারকারী তাদের ইন্টারঅ্যাকশন দিয়ে অ্যানিমেশনটি চালিত করে, সূচকটির প্রস্থ এবং অবস্থানটি এক বিভাগ থেকে পরের অংশে পরিবর্তিত করে, স্ক্রোল দিয়ে পুরোপুরি ট্র্যাক করে।
আপনি খেয়াল নাও করতে পারেন, তবে হাইলাইট করা নেভিগেশন আইটেমটি নির্বাচিত হওয়ার সাথে সাথে আমি রঙের সংক্রমণের জন্য খুব গর্বিত।
হাইলাইট করা আইটেমটির আরও বৈপরীত্য থাকলে অনির্ধারিত হালকা ধূসর আরও পিছনে উপস্থিত হয়। এটি হোভার এবং যখন নির্বাচিত হওয়ার মতো পাঠ্যের জন্য রঙিন রঙের রূপান্তর করা সাধারণ, তবে এটি স্ক্রোলে সেই রঙটি রূপান্তর করা পরবর্তী স্তরের, আন্ডারলাইন সূচকটির সাথে সিঙ্ক্রোনাইজ করা।
আমি এটি কিভাবে করেছি তা এখানে:
tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});
প্রতিটি ট্যাব এনএভি লিঙ্কের জন্য এই নতুন রঙের অ্যানিমেশন প্রয়োজন, আন্ডারলাইন সূচক হিসাবে একই স্ক্রোল টাইমলাইন ট্র্যাক করে। আমি আগের মতো একই টাইমলাইনটি ব্যবহার করি: যেহেতু এটির ভূমিকাটি স্ক্রোলে একটি টিক নির্গত করা হয়, তাই আমরা যে কোনও ধরণের অ্যানিমেশনটিতে আমরা সেই টিকটি ব্যবহার করতে পারি। আমি আগে যেমন করেছি, আমি লুপে 4 টি কীফ্রেম তৈরি করি এবং রঙগুলি ফিরিয়ে দিই।
[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
// results in 4 array items, which represent 4 keyframe states
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]
রঙের var(--text-active-color)
সহ কীফ্রেমটি লিঙ্কটি হাইলাইট করে এবং এটি অন্যথায় একটি স্ট্যান্ডার্ড পাঠ্য রঙ। সেখানে নেস্টেড লুপটি তুলনামূলকভাবে সোজা করে তোলে, কারণ বাইরের লুপটি প্রতিটি এনএভি আইটেম এবং অভ্যন্তরীণ লুপটি প্রতিটি নাভিটেমের ব্যক্তিগত কীফ্রেম। আমি পরীক্ষা করে দেখি বাইরের লুপ উপাদানটি অভ্যন্তরীণ লুপের মতো একই কিনা এবং এটি কখন নির্বাচিত হবে তা জানতে এটি ব্যবহার করুন।
এইটা লিখে অনেক মজা পেলাম। এত
আরও জাভাস্ক্রিপ্ট বর্ধন
এটি একটি অনুস্মারক মূল্যবান যে আমি আপনাকে এখানে যা দেখিয়েছি তার মূলটি জাভাস্ক্রিপ্ট ছাড়াই কাজ করে। এই বলে যে, আসুন দেখুন যখন জেএস উপলব্ধ থাকে তখন আমরা কীভাবে এটি বাড়িয়ে তুলতে পারি।
গভীর লিঙ্ক
গভীর লিঙ্কগুলি একটি মোবাইল শব্দের বেশি, তবে আমি মনে করি গভীর লিঙ্কটির অভিপ্রায়টি এখানে ট্যাবগুলির সাথে দেখা হয়েছে যাতে আপনি সরাসরি একটি ট্যাবের সামগ্রীতে একটি ইউআরএল ভাগ করতে পারেন। ব্রাউজারটি ইউআরএল হ্যাশের সাথে মিলে যাওয়া আইডিতে নেভিগেট করতে পারে। আমি খুঁজে পেয়েছি এই onload
হ্যান্ডলারটি প্ল্যাটফর্মগুলি জুড়ে প্রভাব ফেলেছে।
window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}
স্ক্রোল শেষ সিঙ্ক্রোনাইজেশন
আমাদের ব্যবহারকারীরা সর্বদা কীবোর্ড ক্লিক বা ব্যবহার করে না, কখনও কখনও তারা কেবল বিনামূল্যে স্ক্রোলিং করে, কারণ তারা সক্ষম হওয়া উচিত। যখন বিভাগটি স্ক্রোলার স্ক্রোলিং বন্ধ করে দেয়, যেখানে শীর্ষ নেভিগেশন বারে এটি অবতরণ করা দরকার।
আমি কীভাবে স্ক্রোল শেষের জন্য অপেক্ষা করি তা এখানে: js tabsection.addEventListener('scroll', () => { clearTimeout(tabsection.scrollEndTimer); tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100); });
যখনই বিভাগগুলি স্ক্রোল করা হচ্ছে, সেখানে থাকলে বিভাগের সময়সীমাটি সাফ করুন এবং একটি নতুন শুরু করুন। বিভাগগুলি স্ক্রোল করা বন্ধ হয়ে গেলে, সময়সীমাটি সাফ করবেন না এবং বিশ্রামের পরে 100 মিমি ফায়ার করুন। যখন এটি আগুন লাগে, কল ফাংশন যা ব্যবহারকারী কোথায় থামল তা নির্ধারণ করতে চায়।
const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];
matchingNavItem && setActiveTab(matchingNavItem);
};
স্ক্রোলটি ছড়িয়ে পড়ে ধরে ধরে, স্ক্রোল অঞ্চলের প্রস্থ থেকে বর্তমান স্ক্রোল অবস্থানকে ভাগ করে নেওয়ার ফলে একটি পূর্ণসংখ্যা হতে হবে এবং দশমিক নয়। আমি তখন এই গণনা করা সূচকটির মাধ্যমে আমাদের ক্যাশে থেকে একটি নাভিটেম ধরার চেষ্টা করি এবং যদি এটি কিছু খুঁজে পায় তবে আমি ম্যাচটি সক্রিয় হওয়ার জন্য প্রেরণ করি।
const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');
tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};
সক্রিয় ট্যাব সেট করা কোনও বর্তমানে সক্রিয় ট্যাব সাফ করে শুরু হয়, তারপরে আগত এনএভি আইটেমটিকে সক্রিয় রাষ্ট্রের বৈশিষ্ট্য দেয়। scrollIntoView()
এর কলটিতে সিএসএসের সাথে একটি মজাদার ইন্টারঅ্যাকশন রয়েছে যা লক্ষণীয়।
.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
অনুভূমিক স্ক্রোল স্ন্যাপ ইউটিলিটি সিএসএসে, আমরা একটি মিডিয়া ক্যোয়ারিতে বাসা বেঁধেছি যা ব্যবহারকারী যদি গতি সহনশীল হয় তবে smooth
স্ক্রোলিং প্রয়োগ করে। জাভাস্ক্রিপ্ট নিখরচায় উপাদানগুলিকে দেখার জন্য কল করতে পারে এবং সিএসএস ইউএক্সকে ঘোষণামূলকভাবে পরিচালনা করতে পারে। তারা কখনও কখনও তৈরি করে বেশ আনন্দদায়ক ছোট্ট ম্যাচ।
উপসংহার
এখন আপনি জানেন যে আমি কীভাবে এটি করেছি, আপনি কীভাবে করবেন?! এটি কিছু মজাদার উপাদান আর্কিটেকচার তৈরি করে! কে তাদের প্রিয় কাঠামোর স্লট সহ 1 ম সংস্করণ তৈরি করতে চলেছে? 🙂
আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। একটি গ্লিচ তৈরি করুন, আমাকে আপনার সংস্করণটি টুইট করুন এবং আমি এটি নীচে সম্প্রদায় রিমিক্স বিভাগে যুক্ত করব।
কমিউনিটি রিমিক্স
- @ডিভনুক , @রোব_ডোডসন এবং ওয়েব উপাদানগুলির সাথে @ডাসুরমা : নিবন্ধ ।
- বোতামগুলির সাথে @জাভ্যান্ডারশি : কোডপেন ।
আইওএস এবং অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিতে পাওয়া অনুরূপ একটি ট্যাব উপাদান কীভাবে তৈরি করবেন তার একটি ভিত্তি ওভারভিউ।
এই পোস্টে আমি প্রতিক্রিয়াশীল ওয়েবের জন্য একটি ট্যাব উপাদান তৈরির বিষয়ে চিন্তাভাবনা ভাগ করে নিতে চাই, একাধিক ডিভাইস ইনপুট সমর্থন করে এবং ব্রাউজার জুড়ে কাজ করে। ডেমো চেষ্টা করুন.
আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:
ওভারভিউ
ট্যাবগুলি ডিজাইন সিস্টেমগুলির একটি সাধারণ উপাদান তবে অনেকগুলি আকার এবং ফর্ম নিতে পারে। প্রথমে <frame>
উপাদানটিতে নির্মিত ডেস্কটপ ট্যাবগুলি ছিল এবং এখন আমাদের কাছে বাটারি মোবাইল উপাদান রয়েছে যা পদার্থবিজ্ঞানের বৈশিষ্ট্যের ভিত্তিতে সামগ্রীকে অ্যানিমেট করে। তারা সকলেই একই কাজ করার চেষ্টা করছে: স্থান সংরক্ষণ করুন।
আজ, একটি ট্যাব ব্যবহারকারীর অভিজ্ঞতার প্রয়োজনীয়তা হ'ল একটি বোতাম নেভিগেশন অঞ্চল যা একটি ডিসপ্লে ফ্রেমে সামগ্রীর দৃশ্যমানতা টগল করে। অনেকগুলি বিভিন্ন সামগ্রী অঞ্চল একই স্থান ভাগ করে, তবে নেভিগেশনে নির্বাচিত বোতামের ভিত্তিতে শর্তাধীন উপস্থাপিত হয়।
ওয়েব কৌশল
সব মিলিয়ে আমি এই উপাদানটি তৈরি করতে বেশ সোজা পেয়েছি, কয়েকটি সমালোচনামূলক ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্যগুলির জন্য ধন্যবাদ:
- উপযুক্ত স্ক্রোল স্টপ পজিশনের সাথে মার্জিত সোয়াইপ এবং কীবোর্ড ইন্টারঅ্যাকশনগুলির জন্য
scroll-snap-points
- ব্রাউজারের জন্য ইউআরএল হ্যাশের মাধ্যমে গভীর লিঙ্কগুলি ইন-পৃষ্ঠা স্ক্রোল অ্যাঙ্করিং এবং ভাগ করে নেওয়ার সহায়তা
-
<a>
এবংid="#hash"
এলিমেন্ট মার্কআপ সহ স্ক্রিন রিডার সমর্থন - ক্রসফেড ট্রানজিশন এবং তাত্ক্ষণিক ইন-পৃষ্ঠা স্ক্রোলিং সক্ষম করার জন্য
prefers-reduced-motion
- নির্বাচিত ট্যাবটি গতিশীলভাবে আন্ডারলাইনিং এবং রঙ পরিবর্তন করার জন্য ইন-ড্রাফ্ট
@scroll-timeline
ওয়েব বৈশিষ্ট্য
এইচটিএমএল
মৌলিকভাবে, এখানে ইউএক্সটি হ'ল: একটি লিঙ্ক ক্লিক করুন, ইউআরএলটি নেস্টেড পৃষ্ঠা রাষ্ট্রের প্রতিনিধিত্ব করুন এবং তারপরে কন্টেন্ট এরিয়া আপডেটটি ব্রাউজারটি ম্যাচিং উপাদানটিতে স্ক্রোল হিসাবে দেখুন।
সেখানে কিছু কাঠামোগত সামগ্রী সদস্য রয়েছে: লিঙ্কগুলি এবং :target
এস। আমাদের লিঙ্কগুলির একটি তালিকা দরকার, যা একটি <nav>
এর জন্য দুর্দান্ত এবং <article>
উপাদানগুলির একটি তালিকা, যা একটি <section>
এর জন্য দুর্দান্ত। Each link hash will match a section, letting the browser scroll things via anchoring.
উদাহরণস্বরূপ, একটি লিঙ্ক ক্লিক করা স্বয়ংক্রিয়ভাবে ফোকাস করে :target
নিবন্ধ, কোনও জেএসের প্রয়োজন নেই। এরপরে ব্যবহারকারীরা তাদের ইনপুট ডিভাইসের সাথে সর্বদা নিবন্ধের সামগ্রীটি স্ক্রোল করতে পারেন। এটি প্রশংসামূলক সামগ্রী, যেমন মার্কআপে নির্দেশিত।
আমি ট্যাবগুলি সংগঠিত করতে নিম্নলিখিত মার্কআপটি ব্যবহার করেছি:
<snap-tabs>
<header>
<nav>
<a></a>
<a></a>
<a></a>
<a></a>
</nav>
</header>
<section>
<article></article>
<article></article>
<article></article>
<article></article>
</section>
</snap-tabs>
আমি href
এবং id
বৈশিষ্ট্যগুলির সাথে <a>
এবং <article>
উপাদানগুলির মধ্যে সংযোগ স্থাপন করতে পারি:
<snap-tabs>
<header>
<nav>
<a href="#responsive"></a>
<a href="#accessible"></a>
<a href="#overscroll"></a>
<a href="#more"></a>
</nav>
</header>
<section>
<article id="responsive"></article>
<article id="accessible"></article>
<article id="overscroll"></article>
<article id="more"></article>
</section>
</snap-tabs>
এরপরে আমি নিবন্ধগুলি মিশ্রিত পরিমাণে লোরেম এবং একটি মিশ্র দৈর্ঘ্য এবং শিরোনামের চিত্র সেট সহ লিঙ্কগুলি পূরণ করেছি। সামগ্রীর সাথে কাজ করার সাথে সাথে আমরা বিন্যাস শুরু করতে পারি।
স্ক্রোলিং লেআউট
এই উপাদানটিতে 3 টি বিভিন্ন ধরণের স্ক্রোল অঞ্চল রয়েছে:
- নেভিগেশন (গোলাপী) অনুভূমিকভাবে স্ক্রোলযোগ্য
- সামগ্রী অঞ্চল (নীল) অনুভূমিকভাবে স্ক্রোলযোগ্য
- প্রতিটি নিবন্ধ আইটেম (সবুজ) উল্লম্বভাবে স্ক্রোলযোগ্য।
স্ক্রোলিংয়ের সাথে জড়িত 2 টি বিভিন্ন ধরণের উপাদান রয়েছে:
- একটি জানালা
সংজ্ঞায়িত মাত্রা সহ একটি বাক্স যাoverflow
সম্পত্তি শৈলী রয়েছে। - একটি বড় আকারের পৃষ্ঠ
এই বিন্যাসে, এটি তালিকার পাত্রে: এনএভি লিঙ্কগুলি, বিভাগ নিবন্ধ এবং নিবন্ধ সামগ্রী।
<snap-tabs>
লেআউট
আমি যে শীর্ষ স্তরের বিন্যাসটি বেছে নিয়েছি তা হ'ল ফ্লেক্স (ফ্লেক্সবক্স)। আমি column
দিকটি সেট করেছি, সুতরাং শিরোনাম এবং বিভাগটি উল্লম্বভাবে অর্ডার করা হয়েছে। এটি আমাদের প্রথম স্ক্রোল উইন্ডো, এবং এটি ওভারফ্লো লুকানো সমস্ত কিছু লুকিয়ে রাখে। শিরোনাম এবং বিভাগটি শীঘ্রই পৃথক অঞ্চল হিসাবে ওভারক্রোল নিয়োগ করবে।
<snap-tabs> <header></header> <section></section> </snap-tabs>
snap-tabs { display: flex; flex-direction: column; /* establish primary containing box */ overflow: hidden; position: relative; & > section { /* be pushy about consuming all space */ block-size: 100%; } & > header { /* defend againstneeding 100% */ flex-shrink: 0; /* fixes cross browser quarks */ min-block-size: fit-content; } }
রঙিন 3-স্ক্রোল ডায়াগ্রামের দিকে ফিরে ইশারা করা:
-
<header>
এখন (গোলাপী) স্ক্রোল ধারক হিসাবে প্রস্তুত। -
<section>
(নীল) স্ক্রোল ধারক হতে প্রস্তুত।
ভিসবাগের সাথে নীচে আমি যে ফ্রেমগুলি হাইলাইট করেছি তা আমাদের স্ক্রোল পাত্রে তৈরি উইন্ডোগুলি দেখতে সহায়তা করে।
ট্যাব <header>
বিন্যাস
পরবর্তী লেআউটটি প্রায় একই রকম: আমি উল্লম্ব ক্রম তৈরি করতে ফ্লেক্স ব্যবহার করি।
<snap-tabs> <header> <nav></nav> <span class="snap-indicator"></span> </header> <section></section> </snap-tabs>
header { display: flex; flex-direction: column; }
.snap-indicator
এখানে কোনও পরম অবস্থানযুক্ত উপাদান নেই!
এরপরে, স্ক্রোল শৈলী। দেখা যাচ্ছে যে আমরা আমাদের 2 টি অনুভূমিক স্ক্রোল অঞ্চল (শিরোনাম এবং বিভাগ) এর মধ্যে স্ক্রোল স্টাইলগুলি ভাগ করতে পারি, তাই আমি একটি ইউটিলিটি ক্লাস তৈরি করেছি, .scroll-snap-x
।
.scroll-snap-x {
/* browser decide if x is ok to scroll and show bars on, y hidden */
overflow: auto hidden;
/* prevent scroll chaining on x scroll */
overscroll-behavior-x: contain;
/* scrolling should snap children on x */
scroll-snap-type: x mandatory;
@media (hover: none) {
scrollbar-width: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
}
প্রতিটি এক্স অক্ষের উপর ওভারফ্লো প্রয়োজন, ওভারক্রোল ফাঁদে ফেলার জন্য স্ক্রোল কনটেন্টমেন্ট, টাচ ডিভাইসের জন্য লুকানো স্ক্রোলবার এবং শেষ পর্যন্ত সামগ্রী উপস্থাপনার ক্ষেত্রগুলি লক করার জন্য স্ক্রোল-এসএনএপি। আমাদের কীবোর্ড ট্যাব অর্ডার অ্যাক্সেসযোগ্য এবং যে কোনও ইন্টারঅ্যাকশন গাইড প্রাকৃতিকভাবে ফোকাস করে। স্ক্রোল স্ন্যাপ পাত্রে তাদের কীবোর্ড থেকে একটি দুর্দান্ত ক্যারোসেল স্টাইলের ইন্টারঅ্যাকশনও পান।
ট্যাব শিরোনাম <nav>
লেআউট
NAV লিঙ্কগুলি একটি লাইনে রাখা দরকার, কোনও লাইন বিরতি ছাড়াই, উল্লম্বভাবে কেন্দ্রিক এবং প্রতিটি লিঙ্ক আইটেমটি স্ক্রোল-এসএনএপি ধারকটিতে স্ন্যাপ করা উচিত। 2021 সিএসএসের জন্য সুইফট কাজ!
<nav> <a></a> <a></a> <a></a> <a></a> </nav>
nav { display: flex; & a { scroll-snap-align: start; display: inline-flex; align-items: center; white-space: nowrap; } }
প্রতিটি লিঙ্ক শৈলী এবং আকার নিজেই, তাই এনএভি লেআউটটির কেবল দিকনির্দেশ এবং প্রবাহ নির্দিষ্ট করতে হবে। এনএভি আইটেমগুলিতে অনন্য প্রস্থগুলি ট্যাবগুলির মধ্যে রূপান্তরকে মজাদার করে তোলে কারণ সূচকটি তার প্রস্থকে নতুন লক্ষ্যে সামঞ্জস্য করে। এখানে কতগুলি উপাদান রয়েছে তার উপর নির্ভর করে ব্রাউজারটি একটি স্ক্রোলবার রেন্ডার করবে বা না করে।
ট্যাব <section>
লেআউট
এই বিভাগটি একটি ফ্লেক্স আইটেম এবং স্থানের প্রভাবশালী গ্রাহক হওয়া দরকার। নিবন্ধগুলিতে স্থাপনের জন্য এটি কলাম তৈরি করতে হবে। আবার, সিএসএস 2021 এর জন্য সুইফট কাজ! block-size: 100%
এই উপাদানটিকে যতটা সম্ভব পিতামাতাকে পূরণ করতে প্রসারিত করে, তারপরে তার নিজস্ব বিন্যাসের জন্য, এটি কলামগুলির একটি সিরিজ তৈরি করে যা পিতামাতার 100%
প্রস্থ। শতাংশ এখানে দুর্দান্ত কাজ করে কারণ আমরা পিতামাতার উপর দৃ strong ় বাধা লিখেছি।
<section> <article></article> <article></article> <article></article> <article></article> </section>
section { block-size: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: 100%; }
দেখে মনে হচ্ছে আমরা "যতটা সম্ভব উল্লম্বভাবে প্রসারিত করুন, একটি ধোঁয়াটে উপায়ে" (আমরা flex-shrink: 0
: এটি এই সম্প্রসারণ ধাক্কাটির বিরুদ্ধে একটি প্রতিরক্ষা), যা এ এর জন্য সারি উচ্চতা নির্ধারণ করে পূর্ণ উচ্চতার কলামগুলির সেট। auto-flow
স্টাইলটি গ্রিডকে সর্বদা একটি অনুভূমিক লাইনে বাচ্চাদের রাখার জন্য বলে, কোনও মোড়ানো নেই, আমরা ঠিক কী চাই; পিতামাতার উইন্ডোটি উপচে পড়তে।
আমি মাঝে মাঝে আমার মাথা গুটিয়ে রাখা কঠিন মনে করি! এই বিভাগের উপাদানটি একটি বাক্সে উপযুক্ত, তবে বাক্সগুলির একটি সেটও তৈরি করেছে। আমি আশা করি ভিজ্যুয়াল এবং ব্যাখ্যাগুলি সহায়তা করছে।
ট্যাব <article>
বিন্যাস
ব্যবহারকারীর নিবন্ধ সামগ্রীটি স্ক্রোল করতে সক্ষম হওয়া উচিত এবং স্ক্রোলবারগুলি কেবল তখনই প্রদর্শিত হবে যদি ওভারফ্লো থাকে। এই নিবন্ধ উপাদানগুলি একটি ঝরঝরে অবস্থানে রয়েছে। তারা একই সাথে একটি স্ক্রোল পিতামাতা এবং একটি স্ক্রোল শিশু। ব্রাউজারটি এখানে আমাদের জন্য কিছু জটিল স্পর্শ, মাউস এবং কীবোর্ড ইন্টারঅ্যাকশনগুলি পরিচালনা করছে।
<article> <h2></h2> <p></p> <p></p> <h2></h2> <p></p> <p></p> ... </article>
article { scroll-snap-align: start; overflow-y: auto; overscroll-behavior-y: contain; }
আমি তাদের পিতামাতার স্ক্রোলারের মধ্যে নিবন্ধগুলি স্ন্যাপ করা বেছে নিয়েছি। আমি সত্যিই পছন্দ করি কীভাবে নেভিগেশন লিঙ্ক আইটেমগুলি এবং নিবন্ধের উপাদানগুলি তাদের নিজ নিজ স্ক্রোল পাত্রে ইনলাইন-স্টার্টে স্ন্যাপ করে। এটি সুরেলা সম্পর্কের মতো দেখায় এবং অনুভব করে।
নিবন্ধটি একটি গ্রিড শিশু, এবং এর আকারটি ভিউপোর্ট অঞ্চল হিসাবে আমরা স্ক্রোল ইউএক্স সরবরাহ করতে চাই তা পূর্বনির্ধারিত। এর অর্থ এখানে আমার কোনও উচ্চতা বা প্রস্থের শৈলীর দরকার নেই, এটি কীভাবে উপচে পড়েছে তা আমার কেবল সংজ্ঞায়িত করতে হবে। আমি অটোতে ওভারফ্লো-ওয়াই সেট করেছি এবং তারপরে হ্যান্ডি ওভারক্রোল-আচরণগত সম্পত্তি দিয়ে স্ক্রোল ইন্টারঅ্যাকশনগুলিও ফাঁদে ফেলেছি।
3 স্ক্রোল অঞ্চল পুনরুদ্ধার
নীচে আমি আমার সিস্টেম সেটিংসে "সর্বদা স্ক্রোলবারগুলি দেখান" এ বেছে নিয়েছি। আমি মনে করি লেআউটটির পক্ষে এই সেটিংটি চালু করার সাথে কাজ করা দ্বিগুণ গুরুত্বপূর্ণ, কারণ আমার লেআউট এবং স্ক্রোল অর্কেস্টেশন পর্যালোচনা করা আমার পক্ষে।
আমি মনে করি এই উপাদানটিতে স্ক্রোলবার গটারটি দেখতে স্ক্রোল অঞ্চলগুলি কোথায় রয়েছে, তারা যে দিকটি সমর্থন করে এবং কীভাবে তারা একে অপরের সাথে যোগাযোগ করে তা স্পষ্টভাবে দেখাতে সহায়তা করে। এই স্ক্রোল উইন্ডো ফ্রেমগুলির প্রতিটি কীভাবে কোনও লেআউটে ফ্লেক্স বা গ্রিড পিতামাতাকে কীভাবে বিবেচনা করুন।
ডেভটুলগুলি আমাদের এটি কল্পনা করতে সহায়তা করতে পারে:
স্ক্রোল লেআউটগুলি সম্পূর্ণ: স্ন্যাপিং, গভীর লিঙ্কেবল এবং কীবোর্ড অ্যাক্সেসযোগ্য। ইউএক্স বর্ধন, শৈলী এবং আনন্দের জন্য শক্তিশালী ভিত্তি।
বৈশিষ্ট্য হাইলাইট
স্ক্রোল স্ন্যাপড শিশুরা পুনরায় আকার দেওয়ার সময় তাদের লক অবস্থান বজায় রাখে। এর অর্থ জাভাস্ক্রিপ্টে ডিভাইস ঘোরানো বা ব্রাউজারের আকার পরিবর্তন করার জন্য কোনও কিছু দেখার প্রয়োজন হবে না। Try it out in Chromium DevTools Device Mode by selecting any mode other than Responsive , and then resizing the device frame. Notice the element stays in view and locked with its content. This has been available since Chromium updated their implementation to match the spec. Here's a blog post about it.
অ্যানিমেশন
The goal of the animation work here is to clearly link interactions with UI feedback. This helps guide or assist the user through to their (hopefully) seamless discovery of all the content. I'll be adding motion with purpose and conditionally. Users can now specify their motion preferences in their operating system, and I thoroughly enjoy responding to their preferences in my interfaces.
I'll be linking a tab underline with the article scroll position. Snapping isn't only pretty alignment, it's also anchoring the start and end of an animation. This keeps the <nav>
, which acts like a mini-map , connected to the content. We'll be checking the user's motion preference from both CSS and JS. There's a few great places to be considerate!
স্ক্রোল আচরণ
There's an opportunity to enhance the motion behavior of both :target
and element.scrollIntoView()
. By default, it's instant. The browser just sets the scroll position. Well, what if we want to transition to that scroll position, instead of blink there?
@media (prefers-reduced-motion: no-preference) {
.scroll-snap-x {
scroll-behavior: smooth;
}
}
Since we're introducing motion here, and motion that the user doesn't control (like scrolling), we only apply this style if the user has no preference in their operating system around reduced motion. This way, we only introduce scroll motion for folks who are OK with it.
Tabs indicator
The purpose of this animation is to help associate the indicator with the state of the content. I decided to color crossfade border-bottom
styles for users who prefer reduced motion, and a scroll linked sliding + color fade animation for users who are OK with motion.
In Chromium Devtools, I can toggle the preference and demonstrate the 2 different transition styles. I had a ton of fun building this.
@media (prefers-reduced-motion: reduce) {
snap-tabs > header a {
border-block-end: var(--indicator-size) solid hsl(var(--accent) / 0%);
transition: color .7s ease, border-color .5s ease;
&:is(:target,:active,[active]) {
color: var(--text-active-color);
border-block-end-color: hsl(var(--accent));
}
}
snap-tabs .snap-indicator {
visibility: hidden;
}
}
I hide the .snap-indicator
when the user prefers reduced motion since I don't need it anymore. Then I replace it with border-block-end
styles and a transition
. Also notice in the tabs interaction that the active nav item not only has a brand underline highlight, but it's text color also is darker. The active element has higher text color contrast and a bright underlight accent.
Just a few extra lines of CSS will make someone feel seen (in the sense that we're thoughtfully respecting their motion preferences). আমি এটা ভালোবাসি.
@scroll-timeline
In the above section I showed you how I handle the reduced motion crossfade styles, and in this section I'll show you how I linked the indicator and a scroll area together. This is some fun experimental stuff up next. I hope you're as excited as me.
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
);
I first check the user's motion preference from JavaScript. If the result of this is false
, meaning the user prefers reduced motion, then we'll not run any of the scroll linking motion effects.
if (motionOK) {
// motion based animation code
}
At the time of writing this, the browser support for @scroll-timeline
is none. It's a draft spec with only experimental implementations. It has a polyfill though, which I use in this demo.
ScrollTimeline
While CSS and JavaScript can both create scroll timelines, I opted into JavaScript so I could use live element measurements in the animation.
const sectionScrollTimeline = new ScrollTimeline({
scrollSource: tabsection, // snap-tabs > section
orientation: 'inline', // scroll in the direction letters flow
fill: 'both', // bi-directional linking
});
I want 1 thing to follow another's scroll position, and by creating a ScrollTimeline
I define the driver of the scroll link, the scrollSource
. Normally an animation on the web runs against a global time frame tick, but with a custom sectionScrollTimeline
in memory, I can change all that.
tabindicator.animate({
transform: ...,
width: ...,
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
Before I get into the keyframes of the animation, I think it's important to point out the follower of the scrolling, tabindicator
, will be animated based on a custom timeline, our section's scroll. This completes the linkage, but is missing the final ingredient, stateful points to animate between, also known as keyframes.
Dynamic keyframes
There's a really powerful pure declarative CSS way to animate with @scroll-timeline
, but the animation I chose to do was too dynamic. There's no way to transition between auto
width, and there's no way to dynamically create a number of keyframes based on children length.
JavaScript knows how to get that information though, so we'll iterate over the children ourselves and grab the computed values at runtime:
tabindicator.animate({
transform: [...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`),
width: [...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
For each tabnavitem
, destructure the offsetLeft
position and return a string that uses it as a translateX
value. This creates 4 transform keyframes for the animation. The same is done for width, each is asked what its dynamic width is and then it's used as a keyframe value.
Here's example output, based on my fonts and browser preferences:
TranslateX Keyframes:
[...tabnavitems].map(({offsetLeft}) =>
`translateX(${offsetLeft}px)`)
// results in 4 array items, which represent 4 keyframe states
// ["translateX(0px)", "translateX(121px)", "translateX(238px)", "translateX(464px)"]
Width Keyframes:
[...tabnavitems].map(({offsetWidth}) =>
`${offsetWidth}px`)
// results in 4 array items, which represent 4 keyframe states
// ["121px", "117px", "226px", "67px"]
To summarize the strategy, the tab indicator will now animate across 4 keyframes depending on the scroll snap position of the section scroller. The snap points create clear delineation between our keyframes and really add to the synchronized feel of the animation.
The user drives the animation with their interaction, seeing the width and position of the indicator change from one section to the next, tracking perfectly with scroll.
You may not have noticed, but I'm very proud of the transition of color as the highlighted navigation item becomes selected.
The unselected lighter grey appears even more pushed back when the highlighted item has more contrast. It's common to transition color for text, like on hover and when selected, but it's next-level to transition that color on scroll, synchronized with the underline indicator.
আমি এটি কিভাবে করেছি তা এখানে:
tabnavitems.forEach(navitem => {
navitem.animate({
color: [...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
}, {
duration: 1000,
fill: 'both',
timeline: sectionScrollTimeline,
}
);
});
Each tab nav link needs this new color animation, tracking the same scroll timeline as the underline indicator. I use the same timeline as before: since it's role is to emit a tick on scroll, we can use that tick in any type of animation we want. As I did before, I create 4 keyframes in the loop, and return colors.
[...tabnavitems].map(item =>
item === navitem
? `var(--text-active-color)`
: `var(--text-color)`)
// results in 4 array items, which represent 4 keyframe states
// [
"var(--text-active-color)",
"var(--text-color)",
"var(--text-color)",
"var(--text-color)",
]
The keyframe with the color var(--text-active-color)
highlights the link, and it's otherwise a standard text color. The nested loop there makes it relatively straightforward, as the outer loop is each nav item, and the inner loop is each navitem's personal keyframes. I check if the outer loop element is the same as the inner loop one, and use that to know when it's selected.
এইটা লিখে অনেক মজা পেলাম। এত
Even more JavaScript enhancements
It's worth a reminder that the core of what I'm showing you here works without JavaScript. With that said, let's see how we can enhance it when JS is available.
গভীর লিঙ্ক
Deep links are more of a mobile term, but I think the intent of the deep link is met here with tabs in that you can share a URL directly to a tab's contents. The browser will in-page navigate to the ID that is matched in the URL hash. I found this onload
handler made the effect across platforms.
window.onload = () => {
if (location.hash) {
tabsection.scrollLeft = document
.querySelector(location.hash)
.offsetLeft;
}
}
Scroll end synchronization
Our users aren't always clicking or using a keyboard, sometimes they're just free scrolling, as they should be able to. When the section scroller stops scrolling, wherever it lands needs to be matched in the top navigation bar.
Here's how I wait for scroll end: js tabsection.addEventListener('scroll', () => { clearTimeout(tabsection.scrollEndTimer); tabsection.scrollEndTimer = setTimeout(determineActiveTabSection, 100); });
Whenever the sections are being scrolled, clear the section timeout if there, and start a new one. When sections stop being scrolled, don't clear the timeout, and fire 100ms after resting. When it fires, call function that seeks to figure out where the user stopped.
const determineActiveTabSection = () => {
const i = tabsection.scrollLeft / tabsection.clientWidth;
const matchingNavItem = tabnavitems[i];
matchingNavItem && setActiveTab(matchingNavItem);
};
Assuming the scroll snapped, dividing the current scroll position from the width of the scroll area should result in an integer and not a decimal. I then try to grab a navitem from our cache via this calculated index, and if it finds something, I send the match to be set active.
const setActiveTab = tabbtn => {
tabnav
.querySelector(':scope a[active]')
.removeAttribute('active');
tabbtn.setAttribute('active', '');
tabbtn.scrollIntoView();
};
Setting the active tab starts by clearing any currently active tab, then giving the incoming nav item the active state attribute. The call to scrollIntoView()
has a fun interaction with CSS that is worth noting.
.scroll-snap-x {
overflow: auto hidden;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
In the horizontal scroll snap utility CSS, we've nested a media query which applies smooth
scrolling if the user is motion tolerant. JavaScript can freely make calls to scroll elements into view, and CSS can manage the UX declaratively. Quite the delightful little match they make sometimes.
উপসংহার
Now that you know how I did it, how would you?! This makes for some fun component architecture! Who's going to make the 1st version with slots in their favorite framework? 🙂
আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। Create a Glitch , tweet me your version, and I'll add it to the Community remixes section below.
কমিউনিটি রিমিক্স
- @devnook , @rob_dodson , and @DasSurma with Web Components: article .
- @jhvanderschee with buttons: Codepen .