مقاله تخصصی باورژن

تایپوگرافی سیال مدرن با استفاده از تابع clamp در CSS

با تایپوگرافی سیال در CSS آشنا شوید، نحوه استفاده از clamp()، محاسبه اندازه فونت واکنش‌گرا، تنظیم نقاط شروع و پایان و نکات دسترس‌پذیری.

آموزش تایپوگرافی سیال در CSS با استفاده از تابع clamp و تغییر اندازه فونت متناسب با عرض صفحه‌نمایش
این مقاله را با تمرکز بر مفاهیم و مثال‌های فنی بخوانید. زمان مطالعه تقریبی: 20 دقیقه

خلاصه سریع: در این مقاله، آدریان بسه (Adrian Bece) اصول تایپوگرافی سیال (Fluid Typography)، موارد استفاده از آن، بهترین روش‌های پیاده‌سازی، نحوه استفاده از فانکشن clamp در CSS و چگونگی محاسبه پارامترهای مناسب را بررسی می‌کند. او همچنین به برخی ملاحظات مربوط به دسترس‌پذیری می‌پردازد و یک مشکل مهم را توضیح می‌دهد که در حال حاضر راه‌حل قابل‌اعتمادی برای آن نداریم، اما باید از وجودش آگاه باشیم.

مفهوم تایپوگرافی سیال سال‌هاست که در توسعه وب مطرح است. در گذشته، توسعه‌دهندگان برای پیاده‌سازی آن در مرورگرها مجبور بودند از راهکارهای جایگزین مختلفی استفاده کنند. اما با معرفی فانکشن جدید clamp در CSS، پیاده‌سازی تایپوگرافی سیال از همیشه ساده‌تر شده است.

معمولا وقتی تایپوگرافی واکنش‌گرا (Responsive Typography) را پیاده‌سازی می‌کنیم، اندازه‌ها در نقاط شکست (Breakpoints) مشخصی تغییر می‌کنند. این مقادیر از قبل تعریف شده‌اند. به همین دلیل، طراحان معمولا مقادیر تایپوگرافی، مانند اندازه فونت، ارتفاع خط و فاصله بین حروف را برای دو، سه یا حتی تعداد بیشتری از اندازه‌های صفحه نمایش مشخص می‌کنند. توسعه‌دهندگان نیز این نیازمندی‌ها را با افزودن مدیا کوئری‌ها (Media Queries) برای هدف قرار دادن نقاط شکست مشخص پیاده‌سازی می‌کنند.

نمودار وابستگی بین عرض نمای و مقادیر مختلف تایپوگرافی با نقاط شکست پرس و جو رسانه را نشان می دهد.
نمودار، رابطه بین عرض ناحیه قابل‌مشاهده مرورگر (Viewport) و مقادیر مختلف تایپوگرافی را با استفاده از نقاط شکست مدیا کوئری نشان می‌دهد.

اگرچه ممکن است عناصر تایپوگرافی در اندازه‌های صفحه‌ای که طراح مشخص کرده است ظاهر مناسبی داشته باشند، لزوما در عرض‌های نزدیک به نقاط شکست نیز به همان خوبی دیده نمی‌شوند. همان‌طور که می‌دانیم، کاربران از دستگاه‌ها و اندازه‌های صفحه‌نمایش بسیار متنوعی استفاده می‌کنند که ممکن است در طراحی اولیه در نظر گرفته نشده باشند.

اضافه کردن نقاط شکست بیشتر در فاصله بین این اندازه‌ها و بازنویسی استایل‌ها می‌تواند مشکل را برطرف کند، اما در عوض، خطر افزایش پیچیدگی کد، ایجاد حالت‌های خاص بیشتر و دشوارتر شدن خوانایی و نگه‌داری کد را به همراه دارد.

نمونه ای از تایپوگرافی در سه دستگاه مختلف با اندازه های مختلف صفحه نمایش، یعنی: تلفن، تبلت و لپ تاپ.
نمونه‌ای از تایپوگرافی در سه دستگاه با اندازه‌های مختلف صفحه‌نمایش: تلفن همراه، تبلت و لپ‌تاپ.

در این مثال، تایپوگرافی در عرض‌های کوچک و بزرگ صفحه‌نمایش ظاهر مناسبی دارد، اما اندازه عنوان در نزدیکی نقطه شکست (تصویر وسط) نامتناسب به نظر می‌رسد. دلیل این مسئله، استفاده از مقادیر ثابت برای تایپوگرافی و فضای خالی کمتر در آن ناحیه است.

تایپوگرافی سیال (Fluid typography) اندازه متن را متناسب با عرض صفحه‌نمایش، به‌صورت پیوسته و نرم تغییر می‌دهد. این روش معمولا با یک مقدار حداقل شروع می‌شود و تا رسیدن به عرض مشخصی از صفحه، همان اندازه را حفظ می‌کند. پس از آن، اندازه متن به‌تدریج افزایش می‌یابد. وقتی اندازه به حداکثر مقدار خود در عرض دیگری از صفحه برسد، از آن نقطه به بعد ثابت می‌ماند.

در ادامه این مقاله خواهیم دید که رفتار سیال می‌تواند در جهت معکوس نیز عمل کند، یعنی اندازه متن از مقدار حداکثر شروع شود و در نهایت به مقدار حداقل برسد.

نمودار وابستگی بین عرض درگاه دید و مقادیر مختلف تایپوگرافی با حداقل مقدار نقطه پایان و حداکثر مقدار نقطه شروع را نشان می دهد.

نمودار، رابطه بین عرض صفحه‌نمایش و مقادیر مختلف تایپوگرافی را نشان می‌دهد، به‌طوری‌که در یک سمت، مقدار حداکثر و در سمت دیگر، مقدار حداقل قرار دارد.

این رویکرد نیاز به تنظیمات ظریف برای نقاط شکست خاص و مدیریت حالت‌های استثنایی را کاهش می‌دهد یا حتی از بین می‌برد. اگرچه این روش بیشتر در تایپوگرافی استفاده می‌شود، می‌توان از همین رویکرد برای تغییر سیال مقادیر دیگری مانند margin، padding و gap نیز استفاده کرد.

در مثال بعدی، توجه کنید که اندازه عنوان چگونه به‌نرمی با عرض صفحه‌نمایش تغییر می‌کند و در عرض‌های مختلف ظاهر مناسبی دارد. همچنین، در نظر داشته باشید که محتوای دیگر همچنان از تایپوگرافی واکنش‌گرا استفاده می‌کند و اندازه آن فقط در نقاط شکست تغییر می‌کند.

عنوان‌ها با تغییر عرض صفحه‌نمایش به‌نرمی تغییر اندازه می‌دهند و برخلاف مثال قبلی، در نزدیکی نقاط شکست با ناهماهنگی در اندازه‌ها مواجه نمی‌شویم.
عنوان‌ها با تغییر عرض صفحه‌نمایش به‌نرمی تغییر اندازه می‌دهند و برخلاف مثال قبلی، در نزدیکی نقاط شکست با ناهماهنگی در اندازه‌ها مواجه نمی‌شویم.

با وجود اینکه تایپوگرافی سیال مشکلات مطرح‌شده را برطرف می‌کند، برای تمام موقعیت‌ها ایده‌آل نیست و نباید آن را جایگزینی کامل برای تایپوگرافی واکنش‌گرا در نظر گرفت. هرکدام از این روش‌ها کاربردها و بهترین شیوه‌های استفاده مخصوص به خود را دارند که در ادامه مقاله بررسی خواهیم کرد.

در این مقاله، تایپوگرافی سیال را به‌صورت عمیق بررسی می‌کنیم و با روش‌های مختلفی آشنا می‌شویم که توسعه‌دهندگان در گذشته برای پیاده‌سازی آن به کار می‌بردند. همچنین، فانکشن clamp در CSS و تاثیر آن بر ساده‌تر شدن پیاده‌سازی تایپوگرافی سیال را بررسی خواهیم کرد. یاد می‌گیریم چگونه پارامترهای این فانکشن را دقیق تنظیم کنیم تا نقاط شروع و پایان رفتار سیال تحت کنترل باشند.

در نهایت، ملاحظات مربوط به دسترس‌پذیری را بررسی می‌کنیم، بیشتر مشکلاتی که امروزه قابل‌حل هستند و یک مشکل مهم که هنوز راه‌حل مناسبی برای آن نداریم.

اولین تلاش‌ها برای پیاده‌سازی تایپوگرافی سیال

ما توسعه‌دهندگان اغلب از جاوااسکریپت برای جبران قابلیت‌های CSS استفاده می‌کنیم که هنوز پیاده‌سازی نشده‌اند یا مرورگرهای اصلی از آن‌ها پشتیبانی نمی‌کنند. در سال‌های ابتدایی طراحی واکنش‌گرای وب، کتابخانه‌های جاوااسکریپتی مانند FlowType.JS برای دستیابی به تایپوگرافی سیال استفاده می‌شدند.

اولین پیاده‌سازی واقعی تایپوگرافی سیال با CSS، پس از معرفی قابلیت‌های calc() و واحدهای اندازه‌گیری مبتنی بر Viewport، یعنی vw و vh، امکان‌پذیر شد.

کد زیر را در نظر بگیرید:

/* مقدار حداقل ثابت در عرض‌های کمتر از نقطه شکست */
.fluid {
  font-size: 32px;
}

/* مقدار سیال در عرض صفحه‌نمایش بین 568 و 768 پیکسل */
@media screen and (min-width: 568px) {
  .fluid {
    font-size: calc(
      32px + 16 * ((100vw - 568px) / (768 - 568))
    );
  }
}

/* مقدار حداکثر ثابت در عرض‌های بیشتر از نقطه شکست */
@media screen and (min-width: 768px) {
  .fluid {
    font-size: 48px;
  }
}

این قطعه کد کمی پیچیده به نظر می‌رسد و اعداد زیادی در محاسبات آن وجود دارند. بنابراین، بیایید آن را به بخش‌های کوچک‌تر تقسیم کنیم و در سطح کلی ببینیم چه اتفاقی می‌افتد. ابتدا روی سلکتورها و مدیا کوئری‌ها تمرکز می‌کنیم تا مشخص شود هرکدام چه شرایطی را پوشش می‌دهند.

.fluid {
  /* مقدار حداقل */
}

@media screen and (min-width: [breakpoint-min]) {
  .fluid {
    /* مقدار ترجیحی بین حداقل و حداکثر */
  }
}

@media screen and (min-width: [breakpoint-max]) {
  /* مقدار حداکثر */
}

در رویکرد موبایل‌محور (Mobile-First)، سلکتور اول مقدار را روی حداقل تعیین می‌کند. مدیا کوئری اول رفتار سیال را در فاصله بین دو نقطه شکست مدیریت می‌کند. در نهایت، نقطه شکست آخر مقدار را روی حداکثر تنظیم می‌کند.

حالا که می‌دانیم هر سلکتور و مدیا کوئری چه کاری انجام می‌دهد، بیایید بررسی کنیم که مقادیر حداقل و حداکثر چگونه اعمال می‌شوند و مقدار سیال چگونه محاسبه می‌شود.

.fluid {
  font-size: [value-min];
}

@media (min-width: [breakpoint-min]) {
  .fluid {
    font-size: calc(
      [value-min] +
      ([value-max] - [value-min]) *
      ((100vw - [breakpoint-min]) /
      ([breakpoint-max] - [breakpoint-min]))
    );
  }
}

@media (min-width: [breakpoint-max]) {
  .fluid {
    font-size: [value-max];
  }
}

برای انجام کاری به این سادگی، یعنی محدود کردن یک مقدار به بازه‌ای بین حداقل و حداکثر و ایجاد رفتاری سیال بین دو نقطه شکست، به کدهای تکراری (بویلرپلیت کد) نسبتا زیادی نیاز داریم.

با وجود این حجم از کدهای اضافی، این روش برای مدیریت اندازه‌های سیال به‌قدری محبوب شد که نیاز به راهکاری ساده‌تر و یکپارچه‌تر کاملا احساس می‌شد. اینجاست که فانکشن clamp در CSS وارد میدان می‌شود.

اصطلاحات فنی

بویلرپلیت (boilerplate) کدهای تکراری هستند که بارها در جاهای مختلف برنامه استفاده می‌شوند و حجم برنامه را افزایش می‌دهند.

فانکشن clamp در CSS

فانکشن clamp در CSS سه مقدار دریافت می‌کند: حداقل، مقدار ترجیحی و حداکثر. سپس مقدار نهایی را در محدوده بین حداقل و حداکثر نگه می‌دارد.

مقدار ترجیحی تعیین می‌کند که مقدار نهایی در محدوده تعیین‌شده چگونه تغییر کند. این مقدار معمولا شامل واحدهای اندازه‌گیری Viewport، درصدها یا واحدهای نسبی دیگری است که امکان ایجاد رفتار سیال را فراهم می‌کنند.

فانکشن clamp بسیار انعطاف‌پذیر است. علاوه بر مقادیر ثابت، می‌تواند توابع و عبارت‌های ریاضی و حتی مقادیری را که از فانکشن attr به دست می‌آیند، بپذیرد.

clamp([value-min], [value-preferred], [value-max]);

این فانکشن را می‌توان برای هر ویژگی CSS که نوع مقدار معتبری مانند طول، فرکانس، زمان، زاویه، درصد یا عدد می‌پذیرد، به کار برد. بنابراین، کاربرد آن به تایپوگرافی و تنظیم اندازه‌ها محدود نمی‌شود.

در زمان نگارش مقاله، پشتیبانی مرورگرها از فانکشن clamp بیش از ۹۰ درصد بود، بنابراین، این فانکشن از پشتیبانی گسترده‌ای برخوردار است.

برای مرورگرهای دسکتاپی که از آن پشتیبانی نمی‌کنند، مانند Internet Explorer، کافی است یک مقدار جایگزین (Fallback) تعریف کنیم. مرورگرهایی که نمی‌توانند فانکشن clamp را تجزیه کنند، کل عبارت font-size حاوی این فانکشن را نادیده می‌گیرند و از مقدار جایگزین استفاده می‌کنند.

font-size: [value-fallback]; /* مقدار جایگزین */
font-size: clamp([value-min], [value-preferred], [value-max]);

پیاده‌سازی تایپوگرافی سیال با CSS clamp

بیایید از فانکشن clamp استفاده کنیم و مقادیر زیر را برای آن در نظر بگیریم:

  • مقدار حداقل: برابر با کوچک‌ترین اندازه فونت موردنظر است.
  • مقدار حداکثر: برابر با بزرگ‌ترین اندازه فونت موردنظر است.
  • مقدار ترجیحی: مشخص می‌کند تایپوگرافی سیال چگونه تغییر اندازه دهد، از جمله نقاط شروع و پایان رفتار سیال و سرعت تغییر اندازه. این مقدار به اندازه Viewport وابسته است، بنابراین، از واحد vw استفاده می‌کنیم.

مثال زیر را در نظر بگیرید. می‌خواهیم اندازه فونت بین ۳۲ و ۴۸ پیکسل تغییر کند. در این حالت، اندازه فونت حداقل ۳۲ پیکسل و حداکثر ۴۸ پیکسل خواهد بود. مقدار فعلی بر اساس عرض Viewport تعیین می‌شود، به‌طور دقیق‌تر، برابر با ۴ درصد عرض فعلی Viewport است، مشروط بر اینکه این مقدار بین حداقل و حداکثر قرار بگیرد.

font-size: clamp(32px, 4vw, 48px);

بیایید بررسی کنیم که با توجه به عرض Viewport، در این مثال کدام مقدار اعمال می‌شود تا نحوه عملکرد فانکشن clamp را بهتر درک کنیم.

عرض Viewport (پیکسل) مقدار ترجیحی (پیکسل) مقدار اعمال‌شده (پیکسل)
۵۰۰ ۲۰ ۳۲، محدودشده به حداقل
۹۰۰ ۳۶ ۳۶، مقدار ترجیحی در محدوده مجاز
۱۴۰۰ ۵۶ ۴۸، محدودشده به حداکثر

در این مقداردهی فانکشن clamp، سه مشکل قابل‌توجه وجود دارد.

۱. مقادیر حداقل و حداکثر بر حسب پیکسل دسترس‌پذیر نیستند.

از آنجا که حداقل و حداکثر با واحد پیکسل تعریف شده‌اند، اگر کاربر اندازه فونت ترجیحی مرورگر را تغییر دهد، این مقادیر متناسب با آن تغییر نخواهند کرد.

۲. مقدار ترجیحی مبتنی بر Viewport نیز از ترجیحات کاربر پیروی نمی‌کند.

این مقدار، مانند حالت قبل، به‌طور انحصاری به عرض Viewport وابسته است و ترجیحات کاربر را در نظر نمی‌گیرد.

۳. مقدار ترجیحی چندان گویا نیست.

در این مثال از 4vw استفاده کرده‌ایم که ممکن است در نگاه اول یک عدد جادویی (Magic Number) به نظر برسد. برای هماهنگ نگه داشتن تغییر اندازه چندین متن سیال، باید بدانیم رفتار سیال دقیقا از چه عرضی شروع می‌شود و در چه عرضی به پایان می‌رسد.

می‌توانیم مشکل اول را به‌سادگی با تبدیل مقادیر پیکسلی حداقل و حداکثر به واحد rem برطرف کنیم. برای این کار، مقادیر پیکسلی را بر ۱۶ تقسیم می‌کنیم، یعنی اندازه پیش‌فرض فونت مرورگر.

با این کار، اندازه‌های حداقل و حداکثر با ترجیحات اندازه فونت کاربر در مرورگر سازگار می‌شوند.

font-size: clamp(2rem, 4vw, 3rem);
مقادیر پیکسل با تنظیمات برگزیده اندازه فونت مرورگر سازگار نیستند، اما مقادیر rem و em سازگار هستند.
مقادیر پیکسلی با تغییر ترجیحات اندازه فونت مرورگر سازگار نمی‌شوند، اما مقادیر rem و em می‌توانند با این ترجیحات تطبیق پیدا کنند.

برای مقدار ترجیحی باید از رویکرد متفاوتی استفاده کنیم، زیرا این مقدار باید به اندازه Viewport واکنش نشان دهد. با این حال، می‌توانیم مقدار نسبی rem را نیز به آن اضافه کنیم و یک عبارت ریاضی بسازیم.

font-size: clamp(2rem, 4vw + 1rem, 3rem);

توجه داشته باشید که این راهکار به‌تنهایی تمام مشکلات دسترس‌پذیری را برطرف نمی‌کند. همچنان باید آزمایش کنیم که آیا اندازه متن به‌اندازه کافی قابل بزرگ‌نمایی است و آیا رفتار آن با ترجیحات دسترس‌پذیری کاربران سازگاری دارد یا خیر. در ادامه مقاله به این مسائل خواهیم پرداخت.

با این حال، هنوز نمی‌دانیم چگونه مقدار ترجیحی مثال بالا، یعنی 4vw + 1rem، به دست آمده است تا رفتار سیال موردنظر را ایجاد کند. پس بیایید بررسی کنیم که چگونه می‌توان مقدار ترجیحی را دقیق تنظیم کرد و ریاضیات پشت آن را به‌طور کامل درک کرد.

فانکشن محاسبه اندازه سیال

مقدار ترجیحی تعیین می‌کند فانکشن تایپوگرافی سیال چگونه رفتار کند. به‌طور دقیق‌تر، با تغییر این مقدار می‌توانیم مشخص کنیم که حداقل اندازه فونت در چه عرضی از Viewport شروع به تغییر کند و در چه عرضی به حداکثر مقدار خود برسد.

برای مثال، ممکن است بخواهیم رفتار سیال در عرض ۱۲۰۰ پیکسل شروع شود و در عرض ۸۰۰ پیکسل به پایان برسد.

توجه داشته باشید که برای حفظ هماهنگی میان اندازه‌های مختلف تایپوگرافی سیال، وقتی مقادیر حداقل و حداکثر متفاوت باشند، باید مقادیر ترجیحی متفاوتی نیز محاسبه کنیم. این مقادیر شامل ضریب Viewport و اندازه نسبی هستند.

برای مثال، معمولا نمی‌خواهیم رفتار سیال یک عنصر بین عرض‌های ۱۲۰۰ و ۸۰۰ پیکسل اتفاق بیفتد، اما عنصر دیگری بین عرض‌های ۱۰۰۰ و ۷۵۰ پیکسل تغییر اندازه دهد. چنین وضعیتی می‌تواند باعث ناهماهنگی در اندازه‌ها شود، همان‌طور که در مثال زیر مشاهده می‌کنیم.

در این مثال، ما چهار مقدار تایپوگرافی سیال را با کران های مختلف و اندازه ترجیحی یکسان 4vw تنظیم می کنیم. اگرچه نتیجه سمت چپ ثابت به نظر می‌رسد، اندازه سیال (در سمت راست) در برخی از عرض‌های دید ناسازگار است، زیرا این تغییر در عرض‌های درگاه دید متفاوت رخ می‌دهد.
در این مثال، چهار مقدار مختلف برای تایپوگرافی سیال تعریف شده‌اند که حدود متفاوتی دارند، اما همگی از مقدار ترجیحی یکسان 4vw استفاده می‌کنند. اگرچه نتیجه در سمت چپ هماهنگ به نظر می‌رسد، در سمت راست تغییر اندازه در بعضی عرض‌های صفحه‌نمایش ناهماهنگ است، زیرا تغییر اندازه عناصر در عرض‌های متفاوتی آغاز می‌شود.

برای جلوگیری از این مشکل، باید نحوه محاسبه مقدار ترجیحی را مشخص کنیم و مقادیر مناسب Viewport و اندازه نسبی را در فانکشن clamp قرار دهیم.

بیایید فانکشنی را که برای این محاسبه استفاده می‌شود، بررسی کنیم:

font-size: clamp([min]rem, [v]vw + [r]rem, [max]rem);
معادله

در این فانکشن:

  • x: عرض فعلی Viewport بر حسب پیکسل است.
  • y: اندازه فونت سیال حاصل برای عرض فعلی Viewport، بر حسب پیکسل است.
  • v: ضریب مبتنی بر عرض Viewport است که نرخ تغییر مقدار سیال را کنترل می‌کند و در واحد vw بیان می‌شود.
  • r: اندازه نسبی مبتنی بر اندازه فونت مرورگر است. مقدار پیش‌فرض آن ۱۶ پیکسل است.

با استفاده از این فانکشن می‌توانیم نقاط شروع و پایان رفتار سیال را به‌سادگی محاسبه کنیم.

در مثال ما، مقدار حداقل برابر با 2rem یا ۳۲ پیکسل است و تا زمانی که عرض Viewport به ۴۰۰ پیکسل برسد، ثابت می‌ماند.

معادله

همین فانکشن را می‌توانیم برای مقدار حداکثر نیز به کار ببریم. با این محاسبه متوجه می‌شویم که اندازه فونت در عرض ۸۰۰ پیکسل به مقدار حداکثر خود، یعنی 3rem یا ۴۸ پیکسل، می‌رسد.

هدف این مثال صرفا نشان دادن تاثیر مقدار ترجیحی بر رفتار تایپوگرافی سیال بود. حالا بیایید از همین فانکشن در سناریویی واقع‌گرایانه‌تر استفاده کنیم و یک مسئله کاربردی را حل کنیم. می‌خواهیم تایپوگرافی سیالی طراحی کنیم که دسترس‌پذیر باشد و بر اساس اندازه‌های فونت موردنیاز و نقاط مشخص شروع و پایان رفتار سیال تنظیم شود.

محاسبه پارامترهای مقدار ترجیحی بر اساس نقاط شروع و پایان مشخص

بیایید یک مثال کاربردی را بررسی کنیم که در پروژه‌های واقعی زیاد با آن مواجه می‌شویم. طراحان اندازه‌های فونت و نقاط شکست موردنیاز را در اختیار ما قرار داده‌اند و وظیفه ما به‌عنوان توسعه‌دهنده، پیاده‌سازی تایپوگرافی سیال با پارامترهای زیر است:

  • حداقل اندازه فونت برابر با ۳۶ پیکسل است (y1).
  • حداکثر اندازه فونت برابر با ۵۲ پیکسل است (y2).
  • مقدار حداقل باید در عرض ۶۰۰ پیکسل Viewport به پایان برسد (x1).
  • مقدار حداکثر باید از عرض ۱۴۰۰ پیکسل Viewport شروع شود (x2).
نمایش تصویری نیازمندی‌های تایپوگرافی سیال در این مثال.
نمایش تصویری نیازمندی‌های تایپوگرافی سیال در این مثال.

حالا این مقادیر را در فانکشن محاسبه اندازه سیال که پیش‌تر بررسی کردیم، قرار می‌دهیم.

معادله

با این کار به دو معادله می‌رسیم که در آن‌ها باید دو پارامتر را محاسبه کنیم: ضریب عرض Viewport، یعنی v، و اندازه نسبی، یعنی r.

معادله

می‌توانیم معادله اول را به عبارت زیر تبدیل کنیم و از آن برای محاسبات استفاده کنیم.

معادله

سپس مقدار r را در معادله دوم با این عبارت جایگزین می‌کنیم تا معادله‌ای برای محاسبه v به دست آوریم.

معادله

نتیجه محاسبات، مقدار 2vw برای ضریب عرض Viewport است. به همین روش می‌توانیم r را نیز از معادله جدا کنیم و با استفاده از پارامترهای موجود محاسبه کنیم.

معادله

توجه: مقدار به‌دست‌آمده برای r بر حسب پیکسل است، اما باید آن را با واحد rem بیان کنیم. بنابراین، مقدار پیکسلی را بر ۱۶ تقسیم می‌کنیم و به 1.5rem می‌رسیم.

همچنین باید حداقل ۳۶ پیکسل و حداکثر ۵۲ پیکسل را به واحد rem تبدیل کنیم و تمام مقادیر را در فانکشن clamp قرار دهیم.

font-size: clamp(2.25rem, 2vw + 1.5rem, 3.25rem);

برای اطمینان از صحت محاسبات، می‌توانیم نمودار این فانکشن را رسم کنیم.

نمودار رفتار تایپوگرافی سیال با پارامترهای محاسبه‌شده.
نمودار رفتار تایپوگرافی سیال با پارامترهای محاسبه‌شده.

برای جمع‌بندی، می‌توانیم از دو رابطه ریاضی زیر برای محاسبه پارامترهای مقدار ترجیحی استفاده کنیم: v که با واحد vw و r که با واحد rem بیان می‌شود. این محاسبات بر اساس اندازه‌های فونت و عرض‌های مشخص Viewport انجام می‌شوند.

معادله

اکنون که نحوه عملکرد فانکشن clamp و روش محاسبه مقدار ترجیحی را به‌طور کامل درک کرده‌ایم، می‌توانیم تایپوگرافی سیال هماهنگ و دسترس‌پذیری را در پروژه‌های خود پیاده‌سازی کنیم و از مشکلاتی که پیش‌تر به آن‌ها اشاره شد، جلوگیری کنیم.

استفاده از مقدار منفی Viewport برای تغییر اندازه سیال

می‌توانیم با استفاده از ضریب منفی برای مقدار Viewport، کاری کنیم که اندازه متن با کوچک‌تر شدن صفحه‌نمایش افزایش پیدا کند. مقدار منفی Viewport رفتار سیال پیش‌فرض را معکوس می‌کند.

برای اینکه رفتار سیال در نقاط مشخصی آغاز و پایان یابد، باید اندازه نسبی را نیز متناسب با آن تنظیم کنیم. برای این کار، دو معادله‌ای را که در مثال قبلی بررسی کردیم، حل می‌کنیم.

font-size: clamp(3rem, -4vw + 6rem, 4.5rem);

من شخصا از این پیکربندی معکوس در پروژه‌هایم استفاده نکرده‌ام، اما اگر در پروژه یا طراحی خود با چنین نیازی مواجه شدید، ممکن است این روش برایتان جالب باشد.

تغییر اندازه سیال با استفاده از مقدار منفی برای اندازه Viewport. توجه کنید که با افزایش عرض صفحه‌نمایش، اندازه متن کاهش می‌یابد.
تغییر اندازه سیال با استفاده از مقدار منفی برای اندازه Viewport. توجه کنید که با افزایش عرض صفحه‌نمایش، اندازه متن کاهش می‌یابد.
در این حالت، رفتار سیال با مقدار حداکثر آغاز می‌شود. وقتی به نقطه مشخصی برسیم، اندازه متن شروع به کاهش می‌کند و این روند تا رسیدن به مقدار حداقل ادامه پیدا می‌کند.
در این حالت، رفتار سیال با مقدار حداکثر آغاز می‌شود. وقتی به نقطه مشخصی برسیم، اندازه متن شروع به کاهش می‌کند و این روند تا رسیدن به مقدار حداقل ادامه پیدا می‌کند.

ابزار بصری‌سازی تایپوگرافی سیال

هنگام کار روی یکی از پروژه‌هایم، مجبور شدم چندین پیکربندی مختلف برای تایپوگرافی سیال ایجاد کنم. در حال آزمایش این پیکربندی‌ها در مرورگر بودم که به فکرم رسید ابزاری بسازم تا توسعه‌دهندگان بتوانند رفتار تایپوگرافی سیال را مشاهده و تنظیم کنند.

ایده این ابزار از یکی از نمونه‌های نمایشی دوره «CSS for JS Developers» متعلق به جاش دبلیو. کامو (Josh W. Comeau) الهام گرفته شد. نتیجه کار، ابزاری به نام Modern Fluid Typography Tool بود.

نمای نموداری این ابزار، دید کلی مناسبی از رفتار سیال در اختیار توسعه‌دهندگان قرار می‌دهد.
نمای نموداری این ابزار، دید کلی مناسبی از رفتار سیال در اختیار توسعه‌دهندگان قرار می‌دهد.

توسعه‌دهندگان می‌توانند با استفاده از این ابزار، قطعه‌کدهای تایپوگرافی سیال را ایجاد و دقیق تنظیم کنند و رفتار آن‌ها را به‌صورت بصری مشاهده کنند تا چندین نمونه از تایپوگرافی سیال در کنار یکدیگر هماهنگ باقی بمانند.

این ابزار همچنین امکان تولید پیوندی به تنظیمات را فراهم می‌کند. به این ترتیب، توسعه‌دهندگان می‌توانند این پیوند را در توضیحات کد یا مستندات پروژه قرار دهند تا دیگران نیز بتوانند به‌راحتی رفتار تغییر اندازه سیال را بررسی کنند.

نمای جدولی ابزار نیز به توسعه‌دهندگان کمک می‌کند اندازه‌های سیال را در فهرستی قابل‌تنظیم از نقاط شکست دنبال کنند.
نمای جدولی ابزار نیز به توسعه‌دهندگان کمک می‌کند اندازه‌های سیال را در فهرستی قابل‌تنظیم از نقاط شکست دنبال کنند.

این پروژه رایگان و متن‌باز است، بنابراین، می‌توانید اشکالات آن را گزارش کنید یا در توسعه‌اش مشارکت داشته باشید. از شنیدن نظرات و پیشنهادهای شما برای افزودن قابلیت‌های جدید خوشحال می‌شوم.

ملاحظات مربوط به دسترس‌پذیری

مهم است دوباره تاکید کنیم که استفاده از مقادیر rem به‌صورت خودکار تایپوگرافی سیال را برای همه کاربران دسترس‌پذیر نمی‌کند. این واحد صرفا اجازه می‌دهد اندازه فونت‌ها به ترجیحات کاربر درباره اندازه متن واکنش نشان دهند.

استفاده از فانکشن clamp در CSS همراه با واحدهای Viewport برای ایجاد اندازه‌های سیال، محدودیت‌های دیگری نیز به همراه دارد که باید در نظر گرفته شوند.

آدریان روزلی (Adrian Roselli) این مشکلات را به‌طور گسترده در مقاله خود آزمایش و مستند کرده است.

«وقتی از واحدهای vw استفاده می‌کنید یا با clamp() حداکثر اندازه متن را محدود می‌کنید، این احتمال وجود دارد که کاربر نتواند متن را تا ۲۰۰ درصد اندازه اولیه آن بزرگ کند. اگر چنین اتفاقی بیفتد، معیار ۱.۴.۴ از استاندارد WCAG با عنوان تغییر اندازه متن (سطح AA) نقض می‌شود، بنابراین، حتما نتیجه را با قابلیت بزرگ‌نمایی آزمایش کنید.»

— آدریان روزلی

می‌خواستم از همان ابتدا این مشکل را برطرف کنم. ایده‌ام این بود که با استفاده از جاوااسکریپت، فعال شدن بزرگ‌نمایی را تشخیص دهم و کلاسی را اعمال کنم که اندازه‌گذاری سیال را با یک مقدار معمولی rem جایگزین کند.

/* تایپوگرافی سیال در سطح بزرگ‌نمایی پیش‌فرض */
.title {
  font-size: clamp(2rem, 4vw + 1rem, 3rem);
}

/* در صورت فعال بودن بزرگ‌نمایی، به تایپوگرافی واکنش‌گرا برگرد */
body.zoom-active .title {
  font-size: 2rem;
}

@media screen and (min-width: 768px) {
  body.zoom-active .title {
    font-size: 3rem;
  }
}

شاید همان‌طور که من تعجب کردم، شما هم از این موضوع تعجب کنید که نمی‌توانیم رویداد بزرگ‌نمایی را به‌طور قابل‌اعتماد با جاوااسکریپت تشخیص دهیم، در حالی که رویدادهای معمولی Viewport، مانند تغییر اندازه صفحه (resize)، به‌سادگی قابل‌شناسایی هستند.

مشخصات Visual Viewport API وجود دارد که در زمان نگارش این مقاله، حدود ۹۲ درصد مرورگرها از آن پشتیبانی می‌کردند. با این حال، مقدار scale که باید سطح بزرگ‌نمایی را مشخص کند، عملا درست کار نمی‌کند و صرف‌نظر از میزان بزرگ‌نمایی، مقدار یکسانی برمی‌گرداند.

علاوه بر این، مستندات، مثال‌های عملی یا موارد استفاده قابل‌اتکایی برای این قابلیت وجود ندارد. این مسئله کمی عجیب است، به‌خصوص با توجه به اینکه این API از پشتیبانی گسترده‌ای در مرورگرها برخوردار است.

برخی راهکارهای جایگزین وجود دارند، اما آن‌ها نیز کاملا قابل‌اعتماد نیستند. همچنین، این روش‌ها نمی‌توانند تشخیص دهند که آیا صفحه از همان لحظه بارگذاری بزرگ‌نمایی شده است یا خیر، بلکه فقط پس از وقوع یک رویداد قادر به شناسایی وضعیت هستند.

اگر Visual Viewport API مطابق انتظار کار می‌کرد، می‌توانستیم هنگام وقوع رویداد بزرگ‌نمایی، به‌سادگی یک کلاس CSS را فعال یا غیرفعال کنیم.

/*
 * این کد کار نمی‌کند؛ زیرا visualViewport.scale مشکل دارد
 * و همیشه مقدار یکسانی برمی‌گرداند.
 * ممکن است این مشکل در آینده برطرف شود.
 */

function checkZoomLevel() {
  if (window.visualViewport.scale === 1) {
    document.body.classList.remove("zoom-active");
  } else {
    document.body.classList.add("zoom-active");
  }
}

window.addEventListener("resize", checkZoomLevel);

متاسفانه، با پیاده‌سازی اندازه‌گذاری سیال ممکن است محتوای وب را برای برخی از کاربرانی که هنگام مرور وب از قابلیت بزرگ‌نمایی استفاده می‌کنند، غیرقابل‌دسترس کنیم.

تا زمانی که نتوانیم یک راهکار جایگزین قابل‌اعتمادتر و دسترس‌پذیرتر برای تایپوگرافی سیال ایجاد کنیم، بهتر است از این روش با احتیاط استفاده کنیم و بررسی کنیم که بزرگ‌نمایی متن مطابق با دستورالعمل‌های دسترس‌پذیری محتوای وب (WCAG) عمل می‌کند.

موارد استفاده پیشنهادی

تایپوگرافی سیال برای عناصر متنی بزرگ و برجسته، به‌ویژه زمانی که اختلاف قابل‌توجهی بین حداقل و حداکثر اندازه آن‌ها وجود دارد، بهترین عملکرد را دارد.

اگر اندازه عنوان‌های بزرگ متناسب با صفحه‌نمایش تغییر نکند، ممکن است در صفحات کوچک‌تر بیش از حد بزرگ و نامتناسب به نظر برسند. در چنین شرایطی، تغییر سیال اندازه متن می‌تواند ظاهر مناسب‌تری ایجاد کند.

استفاده از اندازه‌گذاری سیال زمانی نیز توصیه می‌شود که بخواهیم هماهنگی اندازه‌ها را در بخش‌های مختلف رابط کاربری حفظ کنیم.

برای مثال، ممکن است اندازه عنوان و فاصله بین ستون‌های یک شبکه (Grid Gap) در صفحه‌نمایش‌های دسکتاپ کوچک‌تر و تبلت‌های بزرگ‌تر، متناسب با ابعاد کارت‌ها تغییر نکند. می‌توانیم با استفاده از اندازه‌گذاری سیال این مشکل را برطرف کنیم.

اندازه عنوان و فاصله شبکه در اندازه‌های مختلف صفحه‌نمایش به‌درستی با ابعاد کارت‌ها هماهنگ نیستند. اندازه‌گذاری سیال می‌تواند این مشکل را حل کند.
اندازه عنوان و فاصله شبکه در اندازه‌های مختلف صفحه‌نمایش به‌درستی با ابعاد کارت‌ها هماهنگ نیستند. اندازه‌گذاری سیال می‌تواند این مشکل را حل کند.
به کمک اندازه‌گذاری سیال می‌توان هم تغییر اندازه تایپوگرافی و هم فاصله بین عناصر شبکه را به‌صورت هماهنگ حفظ کرد.
به کمک اندازه‌گذاری سیال می‌توان هم تغییر اندازه تایپوگرافی و هم فاصله بین عناصر شبکه را به‌صورت هماهنگ حفظ کرد.

الیز هاین (Elise Hein) نیز در مقاله خود درباره بهترین روش‌های تایپوگرافی سیال، به نتیجه مشابهی رسیده است:

«تلاش کردم حوزه‌های مشخص زیادی پیدا کنم که در آن‌ها تایپوگرافی مبتنی بر اندازه Viewport از نظر خوانایی واقعا بهتر از اندازه‌گذاری مبتنی بر نقاط شکست عمل کند، اما موفق نشدم. با این حال، دو مورد وجود دارند: تنظیم متن‌های نمایشی بزرگ و حفظ طول خط در محدوده‌ای مناسب برای خواندن.»

— الیز هاین

تایپوگرافی سیال زمانی که اختلاف بین حداقل و حداکثر اندازه فونت فقط چند پیکسل باشد، به‌اندازه کافی مؤثر یا کاربردی نیست. این وضعیت معمولا در متن بدنه (Body Text) دیده می‌شود.

متن بدنه‌ای که اختلاف اندکی بین حداقل و حداکثر اندازه فونت آن وجود دارد، برخلاف عنوان‌های بزرگ، معمولا در عرض‌های مختلف صفحه‌نمایش نامتناسب به نظر نمی‌رسد. برای چنین مواردی، بهتر است از تایپوگرافی واکنش‌گرای معمولی و نقاط شکست استفاده کنیم.

جمع‌بندی

تایپوگرافی سیال نباید جایگزین تایپوگرافی واکنش‌گرا شود، بلکه باید به‌عنوان روشی تکمیلی برای کاربردهای مشخص در نظر گرفته شود.

بهتر است از تایپوگرافی سیال برای تغییر نرم اندازه متن‌هایی استفاده کنیم که اختلاف قابل‌توجهی بین حداقل و حداکثر اندازه آن‌ها وجود دارد، یا در موقعیت‌هایی که حفظ هماهنگی اندازه‌ها اهمیت دارد.

هنگام استفاده از چندین عنصر تایپوگرافی سیال با فانکشن clamp در CSS، باید مطمئن شویم که تغییر اندازه آن‌ها با یکدیگر هماهنگ است. برای این کار می‌توانیم ضرایب مربوط به عرض Viewport و اندازه نسبی را محاسبه کنیم و از آن‌ها به‌عنوان مقادیر ترجیحی در فانکشن clamp استفاده کنیم.

همچنین باید به استفاده از واحدهای نسبی مانند rem توجه داشته باشیم تا اندازه متن با ترجیحات کاربران درباره اندازه فونت سازگار شود.

در این مقاله دیدیم که اندازه‌گذاری سیال می‌تواند قابلیت بزرگ‌نمایی متن را برای کاربران محدود کند و در نتیجه، مشکلاتی در دسترس‌پذیری به وجود بیاورد. بنابراین، ضروری است تایپوگرافی سیال را با قابلیت بزرگ‌نمایی آزمایش کنیم و اگر مشخص شد که متن به‌اندازه کافی قابل بزرگ‌نمایی نیست، آن را به تایپوگرافی واکنش‌گرای معمولی بازگردانیم.

از نظر تئوری، می‌توانیم این مشکل را با بازنویسی مقادیر تایپوگرافی سیال هنگام وقوع رویداد بزرگ‌نمایی برطرف کنیم. با این حال، در حال حاضر این کار به‌سادگی امکان‌پذیر نیست، زیرا Visual Viewport API به‌درستی کار نمی‌کند و نمی‌تواند رویدادهای بزرگ‌نمایی کاربر را به‌طور قابل‌اعتماد تشخیص دهد.

نکات کلیدی مقاله

  • clamp() امکان تعیین حداقل، مقدار ترجیحی و حداکثر را در یک عبارت CSS فراهم می‌کند.
  • rem به سازگاری اندازه فونت با ترجیحات کاربر کمک می‌کند، اما به‌تنهایی تضمین‌کننده دسترس‌پذیری نیست.
  • محاسبه مقدار ترجیحی کمک می‌کند رفتار سیال در نقاط شروع و پایان مشخصی اتفاق بیفتد و اندازه چند عنصر با یکدیگر هماهنگ بماند.
  • کاربرد اصلی تایپوگرافی سیال عنوان‌های بزرگ، متن‌های نمایشی و حفظ هماهنگی فاصله‌ها و اندازه‌هاست.
  • تایپوگرافی سیال جایگزین کامل تایپوگرافی واکنش‌گرا نیست. انتخاب روش مناسب به نوع محتوا و نیازهای طراحی بستگی دارد.
  • آزمایش دسترس‌پذیری ضروری است. باید مطمئن شویم کاربران می‌توانند متن را به‌اندازه کافی بزرگ کنند و محتوای صفحه همچنان خوانا باقی می‌ماند.

دیدگاه‌ها


ثبت دیدگاه