شصت و دو درصد وزن وب سایت تصویر است، و هر روز این رقم بیشتر میشود. اگر از این بایت ها بصورت درست استفاده کنیم خیلی خوب خواهد شد. اما در رزلوشن و یا صفحه نمایش های پایین اکثر این داده ها از دست میرود.
چرا؟ وب سایت ها برای این طراحی میشوند که از هر طریقی در دسترس همه باشد، و در سال های اخیر و با تغییر اندازه صفحه نمایش دستگاه ها حرکتی گسترده به سمت طراحی واکنش گرا صورت گیرد. زمانی که ما طراحی واکنش گرا را انتخاب میکنیم محتوای وب سایت ما در هر دستگاهی به خوبی نمایش داده میشود. همه محتوای ما به جز محتوای بیت مپ. تصاویر بیت مپ با رزلوشن فیکس میشود. و تگ img با اتریببیوت src آن غیر قابل انطباق است.
دو گزینه روبروی ما وجود دارد. برخی از جاهای وب سایت خود را برای یک عده کامل نشان ندهیم؟ و یا برای همه کند نمایش دهیم؟ بیشتر طراحان گزینه دوم را انتخاب میکنند، تصاویر را در بالاترین سایز و کیفیت به همه نشان میدهند. بنابراین زمان تلف میشود.
اما! بعد از سه سال محاسبه، چند مارک آپ تازه مشکل تصاویر واکنش گرا را حل کرده است:
Srcset
Sizes
Picture
- و دوست قدیمی ما
source
(که ازaudio
وvideo
قرض گرفته شده اند)
این المان ها و اتریبیوتهای تازه به ما این اجازه را میدهند که چندین منبع جایگزین را در نظر بگیرند و برای هر کاربر مناسب ترین منبع را نمایش دهند. اولین بار این المان ها و اتریبیوتهای تازه در کروم 38 و در ماه سپتامبر رسما وارد عرصه شد. با کمک polyfill که به کمک ما آمده میتوانیم تصاویر واکنش گرا را داشته باشیم.
بایید یک صفحه وب ایجاد کنیم و تصاویر داخل آنرا واکنش گرا کنیم. ما اینکار را در سه راه میتوانیم انجام دهیم و در هریک از این راه ها از تگ های تازه استفاده میکنیم:
- مطمئن شوید که تصاویر با
srcset
وsize
به خوبی تغییر مقیاس میکنند. - تصاویر خود را با
picture
وsource media
هدایت میکنیم. - تصویر را با استفاده از
pictue
وsource
جایگزین میکنیم.
در ادامه عملکرد این فیچرهای تازه را بررسی میکنیم.
وضعیت موجود
وب سایت لحاف یک وب سایت واکنش گرا است. راه زیادی برای پیاده سازی این سایت وجود ندارد: عکس های غول آسا. برای این سایت دو صفحه لیست و جزییات طراحی کردیم که برای هرکدام دو تصویر نشان میدهیم:
- صفحه لیست هم اندازه با عرض پاراگراف
- صفحه جرئیات 100 درصد عرض تصویر را پر میکند
چگونه اندازه تصویر را بدست می آوریم و بدون نوشتن کد HTML تصویر خود را بازسازی میکنیم؟
راه حل اول: صفحه لیست. برای اطمینان از اینکه تصاویر همواره سرتاسری نمایش داده شوند، لازم است تا بیشترین اندازه لی اوت را بدست آوریم. CSS مورد نیاز به شرح زیر است:
* { box-sizing: border-box; } body { font-size: 1.25em; } figure { padding: 0 1em; max-width: 33em; } img { display: block; width: 100%; }
میتوانیم حداکثر عرض نصویر را با محاسبه حداکثر عرض figure
، منحای padding
و تبدیل em
به pixel
بدست آوریم:
100% <img> width x ( 33em <figure> max-width - 2em <figure> padding ) x 1.25em <body> font-size x 16px default font-size = 620px
یا، میتوانیم به کمک حقه بزرگ کردن پنجره با ابزار dev اینکار را انجام دهیم:
(من این شیوه را ترجیح میدهم.)
با هر دو شیوه به حداکثر طول 620px تصویر میرسیم. ما تصاویر خود را دو برابر این مقدار وارد میکنیم تا تصویر در صفحه نمایش های 1.240 پیکسل نیز کامل رندر شود.
اما تصویر جزئیات چی؟ تصاویر جزئیات کل صفحه را پوشش میدهند و سایز آنها قابل محدود کردن نیست. پس عکسی با بزرگترین سایز تصویر انتخاب کنیم که بیش از 1.920 است.
زمانی که تصاویر ما در این سایز رندر شود وزن صفحه به 3.5MB می رسد. به جز 5.7KB تمامی این حجم متعلق به تصویر است. میدانیم خیلی از این بایت ها زمانی که تصویر کوچک میشود قابل دیدن نیست. اما چقدر؟ در ادامه معلوم میشود.
گذر اول: با کمک srcset و sizes تصویر را اسکیل کنیم
اولین مشکلی که با آن مواجه میشویم: تصاویر خود را طوری اسکیل کنیم که تصویر ما در هر رزولوشن درست نشان داده شود. ما تصاویر با چند رزولوشن را پیشنهاد میکنیم، بنابراین میتوانیم تصویر بزرگ را در رزولوشن بالا و تصویر کوچک را برای رزولوشن پایین لود شود. اما چگونه؟ با کمک srcset
.
یکی از تصاویر با حجم بالای جزئیات:
<img src="/quilt_2-detail.jpg" alt="Detail of the above quilt, highlighting the embroidery and exotic stitchwork." />
عرض تصویر quilt_2-detail.jpg حدود 1.920 پیکسل میباشد. بیایید دو تصویر کوچکتر را به همراه آن رندر کنیم:
<img srcset="/quilt_2/detail/large.jpg 1920w, /quilt_2/detail/medium.jpg 960w, /quilt_2/detail/small.jpg 480w" src="/quilt_2/detail/medium.jpg" alt="Detail of the above quilt, highlighting the embroidery and exotic stitchwork.">
اولین چیزی را که باید به آن توجه کنیم این است که img
همچنان src
را دارد. این اتریبیوت بخاطر مرورگرهای قدیمی است که این سینتکس تازه را پشتیبانی نمیکنند.
برای کاربرانی که این سینتکس را پشتیبانی میکنند ما srcset
داریم که شامل لیستی از سورس ها میباشد که با کاما از هم جدا شده اند. بعد از هر URL "عرض توصیف گر" آورده شده است که عرض هر تصویر را توصیف میکند. اگر تصویر شما 1024*768 باشد 1024w را پس از URL در srcset
بیاورید. srcset
به مرورگرها کمک میکند تا پیکسل عرض را بفهمند و تصویر مناسب را از این مجموعه لود کنند.
چگونه انتخاب میکنند؟ چیز جالب توجه درباره srcset
این است: نمیدانیم! نمیتوانیم بفهمیم. منطق انتخاب آنها بصورت تعمدی مشخص نیست.
این راه حل پیشنهادی برای حل مشکل تصاویر واکنش گرا سعی میکند تا به طراح وب سایت کنترل بیشتری بدهد. ما باید مجموعه ای از مدیاکوری ها را برای تمامی سایزها و رزولوشن های تصویر فراهم کنیم.
srcset
ما را در برابر خودمان حفظ میکند. کنترل هایی برای مدیریت این موضوع که مرورگر کدام تصویر را لود کند وجود دارد اما بهتر است بگذاریم خود مرورگر تصمیم بگیرد. مرورگرها صفحه نمایش، زاویه دید، اینترنت و ... افراد را میشناسند. بدون اعمال کنترل ما این اجازه را به مرورگر میدهیم تا از اطلاعات خود استفاده کند تا با کد کمتر عملکرد بهتری داشته باشیم.
ما نمیتوانیم از مرورگر بخواهیم تا پس از لود شدن HTML، CSS و جاوااسکریپت تصاویر را نمایش دهند. بنابراین باید با اتریبیوتی تازه تخمین سایز عکس را به مرورگر بدهیم: sizes
.
من از این جهت این اتیبیوت را در مثالهایم ذکر نکردم چون در آن مثال عرض تصاویر باید صددرصد می بود و این اندازه پیش فرض اتریبیوت size
است.
مثال ما قدری پیچیده است: از آنجایی که img
ها در استایل عرض صددرصد دارند و figure
هم حداکثر عرض 33em دارند.
خوشبختانه اتریبیوت size
به ما اجازه دو کار را میدهد:
- به ما اجازه میدهد چندین طول در نظر بگیریم و آنها را با کاما از هم جدا کنیم.
- به ما اجازه در نظر گرفتن شرط مدیا را میدهد.
مانند زیر:
sizes="(min-width: 33em) 33em, 100vw"
مثال بالا میگوید: آیا پنجره نمایش بیش از 33em است؟ این تصویر باید عرض 33em داشته باشد. در غیر اینصورت عرض تصویر 100vw است.
نزدیک آن چیزی است که ما میخواهیم، اما قصه در اینجا ختم نمیشود. بخاطر ذات وابسته em مثال ما قدری گول زننده شده است. اندازه فونت body برابر با 1.25em است، بنابراین “1em” در محتوای استایل figure برابر با 1.25x اندازه فونت پیش فرض مرورگر است. اما در شرط مدیا ما یک em همواره برابر با اندازه فونت پیش فرض مرورگر است. ضرب در 1.25 میشود:
1.25*33=41.25.
sizes="(min-width: 41.25em) 41.25em, 100vw"
این فرمول عرض تصاویر لحاف را بخوبی بدست می آورد و صراحتا باید بگویم که اینکار واقعا خوب است. 100 درصد برای size
مناسب است و به مرورگرها این امکان را میدهید تا لی اوت img
را تخمین بزند؛ اغلب دادن مقادیری برای تصاویر بزرگ انتخابی درست است. باید گفت که اکنون زمان آن است تا مثال خودمان را با محاسبه padding
که بصورت em
داده ایم ادامه دهیم: در سمت ضرب در 1.25 که میشود padding = 2.5em:
<img srcset="/quilt_3/large.jpg 1240w, /quilt_3/medium.jpg 620w, /quilt_3/small.jpg 310w" sizes="(min-width: 41.25em) 38.75em, calc(100vw - 2.5em)" src="/quilt_3/medium.jpg" alt="A crazy quilt whose irregular fabric scraps are fit into a lattice of diamonds." />
بیایید کاری که در بالا انجام داده ایم را مورد بازبینی قرار دهیم. ما با استفاده از srcset
تصاویر بزرگ، متوسط و کوچک را در اختیار مرورگرها قرار داده ایم و عرض آنها را با توصیف گر w مشخص کردیم و از طریق سایز به مرورگر گفتیم که تصویر چه مقدار از لی اوت را اشغال کند.
اگر مثال ما کوچک باشد، میتوانیم از طریق چند خط کوتاه CSS مانند sizes=”100px” و sizes=”50vw” قضیه را تمام کنیم. اما خیلی خوش شانس نیستیم. ما باید دو CSS بدهیم و بگوییم عرض اولی باید در شرایط مدیا خاص نمایش داده شود.
خوشبختانه این کارها بیهوده نیست. با استفاده از srcset
و sizes
که تعیین میکنیم به مرورگر این امکان را میدهیم تا سورس را انتخاب کند. زمانی که مرورگر عرض پیکسل سورس و عرض لی اوت img
را بفهمد، مقیاس سورس-به-لی اوت را برای هر سورس محاسبه میکند. بنابراین، size عدد 620px را بر میگرداند. سورس 620w برابر با 1x از img px است. سورس 1240 برابر با 2x است. 310w چطور؟ 0.5x. مرورگر این مقیاس را میشناسد و هر سورسی را که دوست دارد انتخاب میکند.
تنظیمات به شما این اجازه را میدهد تا مقیاس را مستقیما فراهم تعیین کنید و آن منبع بدون توصیف گر مقیاس پیش فرض 1x را اتخاذ میکند و به شما اجازه میدهد کدی مانند زیر بنویسید:
<img src="/standard.jpg" srcset="/retina.jpg 2x, /super-retina.jpg 3x" />
جالب است، شیوه ای جمع و جور برای فراهم کردن DPI بالا. اما فقط برای تصاویر فیکس استفاده میشود. تمامی تصاویر صفحه لحاف سیال هستند، بنابراین برای آخرین بار است که درباره توصیفگر x میشنویم.
اندازه گیری
اکنون که صفحه وب لحاف را مجددا با کمک srcset
و sizes
ساختیم به لحاظ عملکرد چه بدست آوردیم؟
وزن صفحه ما اکنون براساس شرایط مرورگر متغیر است. تفاوت دارد بنابراین نمیتوانیم عدد بدهیم. من صفحه را در گوگل کروم در عرض ها مختلف تصویر دیدم که به شرح زیر است:
خط صاف طوسی بالا وزن وضعیت موجود 3.5mb را نشان میدهد. خط زخیم 1x و باریک 2x وزن srcset
و size
صفحه را در هر عرض صفحه نمایش بین 320px و 1280px نشان میدهد.
در 2x و صفحه با عرض 320px وزن صفحه را دو سوم کاهش دادیم؛ وزن کلی صفحه 3.5mb بود و اکنون 1.1mb ارسال میکنیم. در 1x و صفحه با عرض 320px صفحه ما کمتر از یک دهم کاهش یافته وزن آن 306kb است. از اینجا به بعد سایز بایت ها با لود شدن سورس های بزرگتر افزایش میابد.
گذر دوم: با کمک art direction picture
برای تصاویری که میخواهیم تغییر شکل دهند، آنها را در سورس لیست میکنیم و عرض پیکسل آنها را در srcset
قرار میدهیم و با size
به مرورگر میگوییم که چه عرضی از تصویر را نشان دهد. اما! زمانی هست که میخواهید تصویر را فراتر از تغییر عرض ساده نمایش دهید. در این زمان از picture
استفاده کنید.
تصاویر صفحه جزییات نسبت 16:9 دارند. در صفحه نمایش بزرگ عالی نشان میدهند، اما در موبایل کوچک است. دوخت و قالب دوزی تصاویر کوچکتر از آن است که مشخص شوند.
اگر میتوانستید در برخی از صفحه نمایش ها آنرا "زوم" میکردید و نمای بسته تری از تصویر داشتیم خیلی خوب میشد.
این کار را – برشی از تصویر برای نمایش در محیطی خاص - art direction میگویند.
هر زمانی که ما یک تصویر را برش میزنیم و یا دگرگون میکنیم تا یک نقطه انقصالی را پر کند ما art direction انجام داده ایم.
اگر ما محصولات را در srcset
زوم کنیم روشی وجود ندارد که بفهمیم کدام عکس انتخاب شده است. اما با استفاده از picture
و source media
میتوانیم خواسته هایمان را اعمال کنیم: تنها زمانی که تصویر بزرگتر از 36em
است محصولات بزرگ و مستطیلی را لود کن. در صفحه نمایش کوچک تر محصولات مربعی شکل را لود کن.
<picture> <!-- 16:9 crop --> <source media="(min-width: 36em)" srcset="/quilt_2/detail/large.jpg 1920w, /quilt_2/detail/medium.jpg 960w, /quilt_2/detail/small.jpg 480w" /> <!-- square crop --> <source srcset="/quilt_2/square/large.jpg 822w, /quilt_2/square/medium.jpg 640w, /quilt_2/square/small.jpg 320w" /> <img src="/quilt_2/detail/medium.jpg" alt="Detail of the above quilt, highlighting the embroidery and exotic stitchwork." /> </picture>
المان picture
شامل تعدادی المان سورس و یک img
است. مرورگر سورس های picture
را ارزیابی میکند تا آن سورسی که اتریبیوت media
اش با محیط نمایش یکی است را پیدا کند. سپس source را که در srcset
وجود دارد به img
میفرستد، و آن المانی است که ما در صفحه "میبینیم".
مثال ساده آن:
<picture> <source media="(orientation: landscape)" srcset="/landscape.jpg" /> <img src="/portrait.jpg" alt="A rad wolf." /> </picture>
در حالت لنداسکیپ، landscape.jpg برای img
لود میشود. زمانی که در حالت پورتریت قرار داریم تصویر portrait.jpg لود میشود.
اگر شما از المان های audio
و video
استفاده کرده باشید این رفتار میتواند کمی عجیب باشد. برخلاف آن المان ها، picture
یک wrapper نامرئی است: یک span
جادویی که به راحتی img
را با srcset
تغذیه میکند. به عبارت دیگر ما img
را با کمک Picture
تقویت میکنیم.
در واقع این بدان معنا است اگر میخواهیم برای تصویر رندر شده خود استایلی در نظر بگیریم باید برای img
بنویسیم. برای مثال
picture. picture { width: 100% }
کار نخواهد کرد.
picture > img { width: 100% }
آن چیزی است که شما میخواهید.
در نظر داشته باشید که هدف ما در بکارگیری picture
استفاده صحیح از پیکسل برای کاربرانی که صفحه نمایش کوچک دارند میباشد، بیایید عملکرد را ببینیم:
خیلی بد نبود! ما بایت های کمتری را برای صفحات نمایش 1x میفرستیم. ذخیره گذر اول در 480px در صفحه نمایش 2x متوقف شده اما پس از گذر دوم تا 700px ادامه داشته است.
صفحه ما اکنون سریع تر لود میشود و در دستگاه های کوچک تر بهتر دیده میشود. ولی هنوز کار ما تمام نشده است.
گذر سوم: چندین فورمت با سورس
تاریخ 25 ساله وب تحت سلطه دو فورمت گذشته است: JPEG و GIF. دهه دردناکی برای PNG سپری شد تا توانست به این کلوپ اختصاصی ملحق شود. فورمت های تازه مانند WebP و JPEG XR پشت این در درحال انتظار هستند، و به طراحان سایت این وعده را میدهند که دست بازتری خواهند داشت. اما بخاطر این موضوع که المان img
تنها یک src
دارد، این انطباق به کندی صورت میگیرد و طراحان سایت نیاز به پشتیبانی جهانی از فرمتی که میخواهد استفاده کنند دارند. picture
کمک میکند تا با استفاده از source
که ما قبلا در video
و audio
هم دیده ایم فورمت های مختلفی را داشته باشیم:
<picture> <source type="image/svg+xml" srcset="/logo.svg" /> <img src="/logo.png" alt="RadWolf, Inc." /> </picture>
اگر مرورگر از source
پشتیبانی کند عکس موجود در srcset
سورس را به img
منتقل میکند.
اما در مثال لحاف، ما زمانی که WebP را به سورس اضافه میکنیم یک کم اوضاع پیچیده تر میشود:
<picture> <!-- 16:9 crop --> <source type="image/webp" media="(min-width: 36em)" srcset="/quilt_2/detail/large.webp 1920w, /quilt_2/detail/medium.webp 960w, /quilt_2/detail/small.webp 480w" /> <source media="(min-width: 36em)" srcset="/quilt_2/detail/large.jpg 1920w, /quilt_2/detail/medium.jpg 960w, /quilt_2/detail/small.jpg 480w" /> <!-- square crop --> <source type="image/webp" srcset="/quilt_2/square/large.webp 822w, /quilt_2/square/medium.webp 640w, /quilt_2/square/small.webp 320w" /> <source srcset="/quilt_2/square/large.jpg 822w, /quilt_2/square/medium.jpg 640w, /quilt_2/square/small.jpg 320w" /> <img src="/quilt_2/detail/medium.jpg" alt="Detail of the above quilt, highlighting the embroidery and exotic stitchwork." /> </picture>
کلی کد برای یک تصویر نوشتیم. و الان کلی فایل داریم: 12تا! سه رزولوشن، دو فورمت، و دو محصول برای هر تصویر اضافه شده است. هر چیزی که به ازای عملکرد و کارایی بدست آورده ایم به قیمت پیچیدگی و ثبات بوده است.
اتوماسیون دوست شما است؛ اگر صفحه شما بخاطر عکس های جایگزین برای یک تصویر کدهای زیادی داشته باشم بهتر از این است که اینکار را بصورت دستی انجام دهید.
بیایید نگاهی به سایت لحاف داشته باشیم و ببینیم با استفاده از WebP چه بدست آورده ایم.
25 تا 30 درصد ذخیره ای که در بالا بدست آورده ایم –نه فقط در صفحه نمایش کوچک بلکه در تمامی رزولوشن ها، چیز کمی نیست. اما متودولوژی من خیلی دقیق نیست؛ عملکرد WebP میتواند متفاوت باشد. نکته اینجاست: فورمت های تازه مزایای زیادی نسبت به JPEG/GIF/PNG دارند. picture
و source
محدودیت های کمتری دارند و مسیر را برای نوآوری در فورمتهای تازه عکس باز میکنند.
دم را غنیمت شمارید
برای سال ها ما میدانتیم چه چیزی باعث اضافه شدن وزن صفحات واکنش گرای ما میشود: تصاویر. بزرگترین آنها برای تصاویر بزرگ استفاده میشود که برای همه کاربران با هر صفحه نمایشی این تصویر ارسال میشد. الان میدانیم چکونه این موضوع را حل کنیم: بیایید سورس های مختلفی برای کاربران متفاوت ایجاد کنیم. المان های تازه به ما کمک میکند تا دقیقا همین کار را انجام دهیم. srcset
به ما این امکان را میدهد تا نسخه های متفاوتی از تصاویر را به مرورگر پیشنهاد کنیم که با کمک size مناسب ترین تصویر را لود کند. picture
و source
به ما این اجازه را میدهند تا کنترل بیشتری داشته باشیم و سورس ما بر اساس مدیا کوری و پشتیبانی از فایل لود میشود.
این فیچرها باهم به ما این امکان را میدهد تا تصاویری وفق پذیر، منعطف و واکنش گرا داشته باشیم. بیایید برای هر کدام از کاربرانمان تصویری بر اساس دستگاهش آماده کنیم. با استفاده از این المان و نگاه به آینده، طراحان سایت باید از همین حالا از این المان استفاده کنند!
اریک پورتیس چهار نوامبر 2014 | تصاویر در طراحی واکنش گرا
دیدگاهها