মসৃণ এন্ট্রি এবং প্রস্থান অ্যানিমেশনের জন্য চারটি নতুন CSS বৈশিষ্ট্য

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

এই ফাঁকগুলি পূরণ করতে, Chrome 116 এবং 117-এ চারটি নতুন ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্য রয়েছে, যা বিচ্ছিন্ন বৈশিষ্ট্যগুলির জন্য মসৃণ অ্যানিমেশন এবং ট্রানজিশন সক্ষম করে৷

এই চারটি নতুন বৈশিষ্ট্য অন্তর্ভুক্ত:

  • একটি কীফ্রেম টাইমলাইনে display এবং content-visibility অ্যানিমেট করার ক্ষমতা (Chrome 116 থেকে)।
  • display মত পৃথক বৈশিষ্ট্যের রূপান্তর সক্ষম করতে allow-discrete কীওয়ার্ড সহ transition-behavior বৈশিষ্ট্য (Chrome 117 থেকে)।
  • ডিসপ্লে থেকে এন্ট্রি ইফেক্ট অ্যানিমেট করার জন্য @starting-style নিয়ম display: none এবং টপ-লেয়ারে (ক্রোম 117 থেকে)।
  • একটি অ্যানিমেশনের সময় শীর্ষ-স্তরের আচরণ নিয়ন্ত্রণ করার জন্য overlay বৈশিষ্ট্য (Chrome 117 থেকে)।

কীফ্রেমে অ্যানিমেশন প্রদর্শন করুন

Chrome 116 থেকে, আপনি কীফ্রেম নিয়মে display এবং content-visibility ব্যবহার করতে পারেন। কীফ্রেমটি ঘটলে এইগুলি তখন অদলবদল হবে। এটি সমর্থন করার জন্য কোন অতিরিক্ত নতুন মান প্রয়োজন নেই:

.card {
  animation: fade-out 0.5s forwards;
}

@keyframes fade-out {
  100% {
    opacity: 0;
    display: none;
  }
}

পূর্ববর্তী উদাহরণটি 0.5 সেকেন্ড সময়কাল ধরে অস্বচ্ছতাকে 0 এ অ্যানিমেট করে এবং তারপরে প্রদর্শন সেট করে না। উপরন্তু, forwards কীওয়ার্ড নিশ্চিত করে যে অ্যানিমেশনটি তার শেষ অবস্থায় থাকে, যাতে এটি প্রয়োগ করা উপাদানটি display: none এবং opacity: 0

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

.card {
  animation: spin-and-delete 1s ease-in forwards;
}

@keyframes spin-and-delete {
  0% {
    transform: rotateY(0);
    filter: hue-rotate(0);
  }
  80% {
    transform: rotateY(360deg);
    filter: hue-rotate(180deg);
    opacity: 1;
  }
  100% {
    opacity: 0;
    display: none;
  }
}

spin-and-delete অ্যানিমেশন হল একটি প্রস্থান অ্যানিমেশন। প্রথমে, কার্ডটি y-অক্ষে ঘুরবে, একটি হিউ-ঘূর্ণনের মাধ্যমে চলবে, এবং তারপর টাইমলাইনের মাধ্যমে 80% এ, এর অস্বচ্ছতা 1 থেকে 0 এ রূপান্তরিত করবে। অবশেষে, কার্ডটি display: block display: none

এই প্রস্থান অ্যানিমেশনগুলির জন্য, এগুলি সরাসরি একটি উপাদানে প্রয়োগ করার পরিবর্তে, আপনি অ্যানিমেশনগুলির জন্য একটি ট্রিগার সেট আপ করতে পারেন৷ উদাহরণস্বরূপ, একটি ইভেন্ট শ্রোতাকে একটি বোতামের সাথে সংযুক্ত করে যা অ্যানিমেশন প্রয়োগ করতে একটি ক্লাস ট্রিগার করে, যেমন:

.spin-out {
   animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
 document.querySelector('.card').classList.add('spin-out');
})

উপরের উদাহরণে এখন display:none । এমন অনেক ক্ষেত্রে রয়েছে যেখানে আপনি এটিকে আরও এগিয়ে নিতে চান এবং অ্যানিমেশনটি প্রথমে শেষ করার অনুমতি দেওয়ার জন্য একটি টাইমআউট সহ DOM নোডটি সরাতে চান।

বিযুক্ত বৈশিষ্ট্য স্থানান্তর

বিচ্ছিন্নভাবে অ্যানিমেট করা বৈশিষ্ট্যগুলি ডিফল্টরূপে ট্রানজিশন ইভেন্টগুলিকে ট্রিগার করে না। এটি সক্ষম করার জন্য, ট্রানজিশন আচরণ মোডটিকে allow-discrete তে সেট করুন।

transition-behavior সম্পত্তি

transition-behavior বৈশিষ্ট্য নির্দিষ্ট করে যে বিচ্ছিন্ন বৈশিষ্ট্যগুলির জন্য রূপান্তরগুলি শুরু করা হবে কি না। এটি দুটি মান গ্রহণ করে: normal এবং allow-discrete , প্রাথমিক মানটি normal

  • normal : বিচ্ছিন্ন বৈশিষ্ট্যের জন্য ট্রানজিশন শুরু করা হবে না, শুধুমাত্র ইন্টারপোলেবল বৈশিষ্ট্যের জন্য।
  • allow-discrete : বিচ্ছিন্ন বৈশিষ্ট্যের পাশাপাশি ইন্টারপোলেবল বৈশিষ্ট্যগুলির জন্য ট্রানজিশন শুরু করা হবে।

একটি নির্দিষ্ট সম্পত্তির জন্য allow-discrete মোড সক্ষম করতে, এটিকে transition শর্টহ্যান্ডে অন্তর্ভুক্ত করুন:

.card {
  transition: opacity 0.25s, display 0.25s allow-discrete; /* Enable allow-discrete for the display property */
}

.card.fade-out {
  opacity: 0;
  display: none;
}
দ্রষ্টব্য: এই ট্রানজিশন ডেমোটি প্রথম অ্যানিমেশন ডেমো থেকে একটি ভিন্ন কৌশল দেখায় কিন্তু দৃশ্যত একই রকম দেখায়।

একাধিক বিচ্ছিন্ন বৈশিষ্ট্য পরিবর্তন করার সময়, আপনাকে অবশ্যই প্রতিটি স্থানান্তরকারী সম্পত্তির জন্য allow-discrete সেট করতে হবে। যেমন:

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}

বিকল্পভাবে, সমস্ত রূপান্তরের বৈশিষ্ট্যের জন্য আচরণ সেট করতে, রূপান্তর-আচরণ ঘোষণা করুন: transition ঘোষণার পরে transition-behavior: allow-discrete । এটি প্রায়শই সবচেয়ে সহজ পদ্ধতি।

.card {
  transition: opacity 0.5s, display 0.5s, overlay 0.5s;
  transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}

এন্ট্রি অ্যানিমেশনের জন্য @starting-style নিয়ম

এখন পর্যন্ত, এই নিবন্ধটি প্রস্থান অ্যানিমেশনগুলিকে কভার করেছে, এন্ট্রি অ্যানিমেশন তৈরি করতে আপনাকে @starting-style নিয়মটি ব্যবহার করতে হবে।

পৃষ্ঠায় উপাদান খোলার আগে ব্রাউজার দেখতে পারে এমন একটি স্টাইল প্রয়োগ করতে @starting-style ব্যবহার করুন। এটি "আগে-খোলা" অবস্থা (যেখান থেকে আপনি অ্যানিমেট করছেন)।

/*  0. IS-OPEN STATE   */
/*  The state at which the element is open + transition logic */
.item {
  height: 3rem;
  display: grid;
  overflow: hidden;
  transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}

/*  1. BEFORE-OPEN STATE   */
/*  Starting point for the transition */
@starting-style {
  .item {
    opacity: 0;
    height: 0;
  }
}

/*  2. EXITING STATE   */
/*  While it is deleting, before DOM removal in JS, apply this
    transformation for height, opacity, and a transform which
    skews the element and moves it to the left before setting
    it to display: none */
.is-deleting {
  opacity: 0;
  height: 0;
  display: none;
  transform: skewX(50deg) translateX(-25vw);
}

এখন আপনার কাছে এই TODO তালিকা আইটেমগুলির জন্য প্রবেশ এবং প্রস্থান উভয় অবস্থাই রয়েছে:

উপরের স্তরে এবং থেকে উপাদানগুলিকে অ্যানিমেটিং করা৷

উপরের স্তরে এবং থেকে উপাদানগুলিকে অ্যানিমেট করতে, ব্রাউজারকে কোথা থেকে অ্যানিমেট করতে হবে তা জানাতে "ওপেন" স্টেটে @starting-style নির্দিষ্ট করুন৷ একটি ডায়ালগের জন্য, ওপেন স্টেটকে [open] অ্যাট্রিবিউট দিয়ে সংজ্ঞায়িত করা হয়। একটি পপওভারের জন্য, :popover-open pseudo class ব্যবহার করুন।

একটি ডায়ালগের একটি সাধারণ উদাহরণ এইরকম দেখতে পারে:

/*   0. IS-OPEN STATE   */
dialog[open] {
  translate: 0 0;
}

/*   1. BEFORE-OPEN STATE   */
@starting-style {
  dialog[open] {
    translate: 0 100vh;
  }
}

/*   2. EXIT STATE   */
dialog {
  transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
  translate: 0 100vh;
}

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

একটি পপওভার অ্যানিমেট করার সময়, পূর্বে ব্যবহৃত open অ্যাট্রিবিউটের পরিবর্তে :popover-open pseudo class ব্যবহার করুন।

.settings-popover {
  &:popover-open {
    /*  0. IS-OPEN STATE  */
    /*  state when popover is open, BOTH:
        what we're transitioning *in* to 
        and transitioning *out* from */
    transform: translateY(0);
    opacity: 1;

    /*  1. BEFORE-OPEN STATE  */
    /*  Initial state for what we're animating *in* from, 
        in this case: goes from lower (y + 20px) to center  */
    @starting-style {
      transform: translateY(20px);
      opacity: 0;
    }
  }
  
  /*  2. EXIT STATE  */
  /*  Initial state for what we're animating *out* to , 
      in this case: goes from center to (y - 50px) higher */
  transform: translateY(-50px);
  opacity: 0;
  
  /*  Enumerate transitioning properties, 
      including display and allow-discrete mode */
  transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}

overlay সম্পত্তি

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

[open] {
  transition: opacity 1s, display 1s allow-discrete;
}

পরিবর্তে, বাকি বৈশিষ্ট্যগুলির সাথে overlay অ্যানিমেট করার জন্য ট্রানজিশন বা অ্যানিমেশনে overlay অন্তর্ভুক্ত করুন এবং অ্যানিমেটিং করার সময় এটি উপরের স্তরে থাকে তা নিশ্চিত করুন। এটি দেখতে অনেক মসৃণ হবে।

[open] {
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

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

ভিউ ট্রানজিশনের উপর একটি নোট

আপনি যদি DOM পরিবর্তন করেন, যেমন DOM থেকে উপাদান যোগ করা এবং অপসারণ করা, মসৃণ অ্যানিমেশনের জন্য আরেকটি দুর্দান্ত সমাধান হল ভিউ ট্রানজিশন । এখানে ভিউ ট্রানজিশন ব্যবহার করে নির্মিত উপরের দুটি উদাহরণ রয়েছে।

এই প্রথম ডেমোতে, @starting-style এবং অন্যান্য সিএসএস রূপান্তর সেট আপ করার পরিবর্তে, ভিউ ট্রানজিশন ট্রানজিশন পরিচালনা করবে। ভিউ ট্রানজিশনটি এভাবে সেট আপ করা হয়েছে:

প্রথমে, CSS-এ, প্রতিটি কার্ডকে একটি পৃথক view-transition-name দিন।

.card-1 {
  view-transition-name: card-1;
}

.card-2 {
  view-transition-name: card-2;
}

/* etc. */

তারপর, জাভাস্ক্রিপ্টে, একটি ভিউ ট্রানজিশনে DOM মিউটেশন (এই ক্ষেত্রে, কার্ড অপসারণ) মোড়ানো।

deleteBtn.addEventListener('click', () => {
  // Check for browser support
  if (document.startViewTransition) {
    document.startViewTransition(() => {
      // DOM mutation
      card.remove();
    });
  } 
  // Alternative if no browser support
  else {
    card.remove();
  }
})

এখন, ব্রাউজার প্রতিটি কার্ডের ফেইড আউট এবং রূপকে তার নতুন অবস্থানে পরিচালনা করতে পারে।

যেখানে এটি সহজ হতে পারে তার আরেকটি উদাহরণ হল তালিকা আইটেমগুলির ডেমো যোগ/সরানো। এই ক্ষেত্রে, আপনাকে প্রতিটি কার্ডের জন্য একটি অনন্য view-transition-name যোগ করার কথা মনে রাখতে হবে।

উপসংহার

এই নতুন প্ল্যাটফর্ম বৈশিষ্ট্যগুলি আমাদের ওয়েব প্ল্যাটফর্মে মসৃণ প্রবেশ এবং প্রস্থান অ্যানিমেশনের এক ধাপ কাছাকাছি নিয়ে আসে। আরও জানতে, এই লিঙ্কগুলি দেখুন: