نحو تجویزی

عنصر <picture> هیچ چیزی را به تنهایی ارائه نمی کند، بلکه به عنوان یک موتور تصمیم گیری برای یک عنصر <img> داخلی عمل می کند و به آن می گوید که چه چیزی را رندر کند. <picture> از سابقه ای پیروی می کند که قبلاً توسط عناصر <audio> و <video> تنظیم شده است: یک عنصر wrapper که حاوی عناصر <source> فردی است.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

آن <img> درونی همچنین یک الگوی بازگشتی قابل اعتماد برای مرورگرهای قدیمی بدون پشتیبانی از تصاویر پاسخگو به شما ارائه می دهد: اگر عنصر <picture> توسط مرورگر کاربر شناسایی نشود، نادیده گرفته می شود. سپس عناصر <source> نیز کنار گذاشته می‌شوند، زیرا مرورگر یا اصلاً آن‌ها را تشخیص نمی‌دهد، یا زمینه معناداری برای آنها بدون والد <video> یا <audio> نخواهد داشت. عنصر داخلی <img> توسط هر مرورگری شناسایی می‌شود، و منبع مشخص‌شده در src آن همانطور که انتظار می‌رود ارائه می‌شود.

تصاویر "هنر کارگردانی" با <picture>

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

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

اما هنگامی که برای نماهای کوچک کوچک می شود، ممکن است فوکوس مرکزی تصویر از بین برود:

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

موضوع این منابع تصویر یکسان است، اما برای تمرکز بهتر روی آن سوژه از نظر بصری، باید نسبت منبع تصویر در نقاط شکست تغییر کند. به عنوان مثال، زوم بیشتر در مرکز تصویر، و برخی از جزئیات در لبه ها برش داده شده است:

زوم شده در محصول گل پریوینک.

این نوع «برش» را می‌توان از طریق CSS به دست آورد، اما باعث می‌شود کاربر تمام داده‌های تشکیل‌دهنده آن تصویر را درخواست کند، حتی اگر هرگز آن را نبیند.

هر عنصر source دارای ویژگی‌هایی است که شرایط انتخاب آن source را مشخص می‌کند: media ، که درخواست رسانه را می‌پذیرد، و type ، که یک نوع رسانه را می‌پذیرد (که قبلاً به عنوان "نوع MIME" شناخته می‌شد). اولین <source> در ترتیب منبع برای مطابقت با زمینه مرور فعلی کاربر انتخاب شده است و محتویات ویژگی srcset در آن source برای تعیین نامزدهای مناسب برای آن زمینه استفاده خواهد شد. در این مثال، اولین source با ویژگی media که با اندازه دید کاربر مطابقت دارد، منبع انتخابی خواهد بود:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

شما همیشه باید آخرین img داخلی را به ترتیب مشخص کنید - اگر هیچ یک از عناصر source با معیارهای media یا type مطابقت نداشته باشد، تصویر به عنوان یک منبع "پیش فرض" عمل می کند. اگر از پرس‌وجوهای رسانه‌ای min-width استفاده می‌کنید، می‌خواهید ابتدا بزرگترین منابع را داشته باشید، همانطور که در کد قبلی مشاهده می‌شود. هنگام استفاده از پرس و جوهای رسانه max-width ، ابتدا باید کوچکترین منبع را قرار دهید.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

وقتی منبعی بر اساس معیارهایی که شما مشخص کرده‌اید انتخاب می‌شود، ویژگی srcset در source به <img> منتقل می‌شود، گویی در خود <img> تعریف شده است - به این معنی که شما آزاد هستید که sizes برای بهینه‌سازی هنر هدایت‌شده استفاده کنید. منابع تصویری نیز

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

البته، یک تصویر با نسبت‌هایی که می‌تواند بسته به عنصر <source> انتخاب شده متفاوت باشد، یک مشکل عملکردی را ایجاد می‌کند: <img> فقط از یک ویژگی width و height پشتیبانی می‌کند، اما حذف آن ویژگی‌ها می‌تواند منجر به تجربه کاربری بدتر شود . به منظور در نظر گرفتن این موضوع، یک افزوده نسبتاً جدید - اما به خوبی پشتیبانی شده - به مشخصات HTML امکان استفاده از ویژگی های height و width را در عناصر <source> می دهد. اینها به همان خوبی که در <img> انجام می‌دهند، تغییرات طرح‌بندی را کاهش می‌دهند، با فضای مناسبی که در طرح شما برای هر عنصر <source> انتخاب شده رزرو شده است.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

توجه به این نکته مهم است که جهت هنری را می‌توان برای تصمیم‌هایی بیش از تصمیم‌گیری‌های مبتنی بر اندازه دید مورد استفاده قرار داد - و با توجه به اینکه اکثر این موارد را می‌توان با srcset / sizes به طور مؤثرتری مدیریت کرد. به عنوان مثال، انتخاب منبع تصویری که با طرح رنگی که توسط ترجیح کاربر دیکته می شود، مناسب تر باشد:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

type

ویژگی type به شما امکان می دهد از موتور تصمیم گیری تک درخواست عنصر <picture> استفاده کنید تا فقط فرمت های تصویر را به مرورگرهایی که از آنها پشتیبانی می کنند ارائه دهید.

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

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

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

با این الگو، درخواست image.webp همچنان در هر مرورگر انجام می شود - به معنای انتقال بیهوده برای مرورگرهای بدون پشتیبانی از WebP. مرورگرهایی که نمی توانند رمزگذاری WebP را تجزیه کنند، یک رخداد onerror ایجاد می کنند و مقدار data-fallback را به src تغییر می دهند. این یک راه حل بیهوده بود، اما باز هم، رویکردهایی مانند این تنها گزینه موجود در بخش جلویی بودند. به یاد داشته باشید که مرورگر قبل از اینکه هر اسکریپت سفارشی فرصتی برای اجرا پیدا کند – یا حتی تجزیه شود – درخواست برای تصاویر را آغاز می‌کند، بنابراین ما نمی‌توانیم از این فرآیند جلوگیری کنیم.

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

در ویژگی type ، نوع رسانه (نوع MIME سابق) منبع تصویر مشخص شده در ویژگی srcset هر <source> را ارائه می دهید. این کار تمام اطلاعاتی را که به مرورگر نیاز دارد برای تعیین فوری اینکه آیا نامزد تصویر ارائه شده توسط آن source را می توان بدون درخواست خارجی رمزگشایی کرد در اختیار مرورگر قرار می دهد - اگر نوع رسانه شناسایی نشود، <source> و همه نامزدهای آن نادیده گرفته می شوند. و مرورگر به کار خود ادامه می دهد.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

در اینجا، هر مرورگری که از رمزگذاری WebP پشتیبانی می کند، نوع رسانه image/webp مشخص شده در ویژگی type عنصر <source> را تشخیص می دهد، آن <source> انتخاب می کند و – از آنجایی که ما فقط یک نامزد واحد در srcset ارائه کرده ایم – دستور می دهد داخلی <img> برای درخواست، انتقال و رندر pic.webp . هر مرورگری که از WebP پشتیبانی نمی‌کند source نادیده می‌گیرد، و اگر دستورالعمل‌های خلاف آن وجود نداشته باشد، <img> محتویات src را همانطور که از سال 1992 انجام داده است، ارائه می‌کند. نیازی نیست عنصر دوم <source> را با البته در اینجا type="image/jpeg" —شما می توانید پشتیبانی جهانی از JPEG را فرض کنید.

صرف نظر از زمینه مرور کاربر، همه اینها با یک انتقال فایل به دست می آید و هیچ پهنای باندی در منابع تصویری که قابل رندر نیستند هدر نمی رود. این نیز آینده‌نگر است: از آنجایی که فرمت‌های فایل جدیدتر و کارآمدتر با انواع رسانه‌های خاص خود عرضه می‌شوند، و ما می‌توانیم به لطف picture از آنها استفاده کنیم - بدون جاوا اسکریپت، بدون وابستگی به سمت سرور، و همه سرعت <img> .

آینده تصاویر واکنش گرا

همه الگوهای نشانه‌گذاری که در اینجا مورد بحث قرار گرفت، از نظر استانداردسازی پیشرفت سنگینی داشتند: تغییر عملکرد چیزی به‌عنوان <img> به‌عنوان تثبیت‌شده و مرکزی در وب، کار کوچکی نبود، و مجموعه مشکلاتی که این تغییرات با هدف حل آن‌ها انجام می‌شد، گسترده بود. حداقل بگو اگر فکر کرده اید که با این الگوهای نشانه گذاری فضای زیادی برای بهبود وجود دارد، کاملاً درست می گویید. از ابتدا، این استانداردها در نظر گرفته شده بودند که مبنایی برای توسعه فناوری های آینده فراهم کنند.

همه این راه‌حل‌ها لزوماً به نشانه‌گذاری بستگی دارند، به طوری که در بار اولیه از سرور گنجانده می‌شوند، و به موقع می‌رسند تا مرورگر منابع تصویر را درخواست کند - محدودیتی که منجر به مشخصه sizes ناکارآمد می‌شود.

با این حال، از آنجایی که این ویژگی ها به پلتفرم وب معرفی شدند، یک روش بومی برای به تعویق انداختن درخواست های تصویر معرفی شد. عناصر <img> با ویژگی loading="lazy" درخواست نمی‌شوند تا زمانی که طرح‌بندی صفحه مشخص شود، به منظور به تعویق انداختن درخواست‌ها برای تصاویر خارج از نمای اولیه کاربر تا بعداً در فرآیند رندر صفحه، احتمالاً اجتناب از درخواست های غیر ضروری از آنجایی که مرورگر در زمان انجام این درخواست‌ها، طرح‌بندی صفحه را کاملاً درک می‌کند، یک ویژگی sizes="auto" به عنوان افزوده‌ای به مشخصات HTML پیشنهاد شده است تا در این موارد از سختی ویژگی‌های sizes نوشته‌شده دستی جلوگیری شود.

همچنین افزودنی هایی به عنصر <picture> در افق نیز وجود دارد تا با برخی از تغییرات فوق العاده هیجان انگیز در نحوه استایل بندی صفحه آرایی مطابقت داشته باشد. در حالی که اطلاعات ویوپورت مبنایی مناسب برای تصمیم‌گیری‌های طرح‌بندی سطح بالا است، اما ما را از اتخاذ رویکردی کاملاً در سطح مؤلفه برای توسعه باز می‌دارد - به این معنی، مؤلفه‌ای که می‌تواند در هر بخشی از طرح‌بندی صفحه رها شود، با سبک‌هایی که به فضایی که خود جزء اشغال می کند. این نگرانی منجر به ایجاد کوئری های کانتینر شد: روشی برای استایل دادن به عناصر بر اساس اندازه کانتینر والد آنها، به جای نمای به تنهایی.

در حالی که دستور Container Query به تازگی تثبیت شده است – و پشتیبانی مرورگر در زمان نگارش بسیار محدود است – افزودن فناوری‌های مرورگر که آن را فعال می‌کند، عنصر <picture> را با ابزاری برای انجام همان کار فراهم می‌کند: یک پتانسیل ویژگی container که اجازه می دهد تا معیارهای انتخاب <source> را بر اساس فضایی که <picture> عنصر <img> اشغال می کند، به جای بر اساس اندازه نمای درگاه، تعیین کند.

اگر کمی مبهم به نظر می رسد، خوب، دلیل خوبی وجود دارد: این بحث های استانداردهای وب در حال انجام است، اما هنوز حل نشده است - هنوز نمی توانید از آنها استفاده کنید.

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