داستان دو viewport (قسمت دوم)

در این مقالات به بررسی روند کار viewport و همچنین width عناصر اصلی صفحات وب مانند window ، screen و <html> خواهیم پرداخت.

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

ایراد مرورگرهای موبایل

هنگامی که مرورگرهای موبایل را با دسکتاپ مقایسه می کنیم اولین تفاوت بارز، اختلاف اندازه screen (مانیتور) مرورگرها است. مرورگرهای موبایل بصورت قابل توجهی کوچکتر از دسکتاپ هستند در این مرورگرها یا باید آنقدر صفحه را کوچک کنیم که در نتیجه متون ناخوانا می شوند یا اینکه قسمت کوچکی از سایت را داخل مرورگر مشاهده کنیم.

اندازه مانیتور موبایل بسیار کوچکتر از مانیتورهای کامپیوترهای دسکتاپ است. حدکثر اندازه آنها تقریبا 400px  است و گاهی اوقات خیلی کوچکتر هستند. (بعضی سازندگان موبایل اندازه های بزرگتری را برای موبایل هایشان بیان کرده اند، اما یا دروغ می گویند یا اینکه اطلاعات ناکارآمدی به مشتریان می دهند.)

دستگاههای تبلت متوسط مانند iPad یا HP webOS-based هم که شکاف بین مرورگرهای دسکتاپ و موبایل را پر می کنند هم نتوانستند تغییری در این مشکل اساسی بوجود بیاورند. سایتها باید در مرورگرهای موبایل مشاهده شوند. بنابراین باید راهی برای نمایش مناسب آنها در مانیتورهای کوچک پیدا کنیم.

بیشتر ایرادات مربوط به CSS و مخصوصا اندازه viewport است. اگر از شیوه نامه دسکتاپ بر روی موبایل استفاده کنیم. این شیوه نامه بطور چشمگیری بهم ریختگی پیدا می کند.

به مثال قبلی برای بلاک با طول 10% کنار صفحه بر می گردیم. اگر مرورگرهای موبایل دقیقا مانند مرورگرهای دسکتاپ عمل کنند، طول بلاک ما حداکثر 40px خواهد شد، که بسیار نازک است. در اینصورت طرح ما بسیار فشرده خواهد بود.

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

سازندگان مرورگرهای موبایل می خواهند که بازدید کنندگان آنها بهترین تجربه را در مشاهده وب سایتها داشته باشند یا به بیانی دیگر سایت را "تا حد امکان مانند مرورگرهای دسکتاپ" مشاهده کنند. از اینرو نیاز به مقداری تردستی داریم.

دو viewport

بنابراین viewport به عنوان چهارچوبی برای کار با طرح بندی CSS، بسیار باریک است. راهکاری واضح این است که viewport را بزرگ تر در نظر بگیریم. هر چند برای اینکار نیاز به دو viewport داریم یکی visual viewport و دیگری layout viewport .

جورج کامینز به بهترین شکل این مفهوم را در سایت stack overflow بیان کرده است :

فرض کنید که layout viewport عکس بزرگی است که اندازه آن تغییر نمی کند. حال فرض کنید که قاب کوچکتری داریم که از آن به تصویر بزرگ نگاه می کنیم. قاب کوچک تنها امکان مشاهده قسمتی از تصویر را به ما می دهد و بقیه قاب با ماده کدری پوشیده شده است. قسمتی از عکس را که می توانیم از طریق قاب ببینیم همان visual viewport است اگر بزرگنمایی (zoom out) انجام دهیم توسط قاب تمام عکس را و یا اینکه با کوچک نمایی (zoom in) به قسمتی از عکس نزدیک تر شده و تنها بخشی از آنرا مشاهده می کنیم. حتی می توانیم قاب را بچرخانیم ولی در اندازه و شکل عکس بزرگ (layout viewport) تغییری حاصل نمی شود.

می توانید این مثال که توسط کریس بیان شده است را هم بخوانید.

visual viewport قسمتی از صفحه وب سایت است که در حال مشاهده آن در مانیتور هستیم. کاربر می تواند مکان آنرا تغییر دهد و قسمتی دیگر از صفحه را مشاهده کند یا اینکه با بزرگنمایی یا کوچکنمایی (zoom) اندازه آنرا تغییر دهد.

visual viewport موبایل

هر چند، طرح بندی CSS مخصوصا مقادیر درصدی آن (مانند width:100%) ، نسبت به layout viewport ، که بزرگ تر از visual viewport است مقایسه می شود.

بنابراین عنصر <html> در ابتدا اندازه layout viewport را به خود می گیرد، و CSS با توجه به صفحه ای که بزرگتر از صفحه موبایل شما است کار می کند. این موضوع این اطمینان را به ما می دهد که طرح بندی سایت همانگونه که در مرورگرهای دسکتاپ است نمایش داده شود.

طول layout viewport چقدر است؟ بستگی به مرورگرها دارد، در safari آیفن طول آن 980px، در Opera 850px ، در اندروید وب کیت 800px و در اینترنت اکسپلورر 974px است.

بعضی مرورگرها رفتار خاصی از خود نشان می دهند :

  • Symbian WebKit طول layout viewport را برابر visual viewport می گیرد، البته این باعث می شود که طول های درصدی رفتار عجیبی از خود نشان دهند. هر چند اگر صفحه بصورت کامل داخل visual viewport قرار نگیرد مروگر بزرگ می شود تا زمانیکه layout viewport به مقدار حداکثر آن یعنی 850px برسد.
  • WebKit سامسونگ (نصب شده بر روی bada) ، اندازه layout viewport را برابر اندازه طویل ترین عنصر صفحه می گیرد.
  • در بلک بری هنگام 10% بزرگ نمایی layout viewport برابر visual viewport است و  تغییر نمی کند.

بزرگ و کوچک کردن (Zooming)

بدیهی است که هر دو viewport با پیکسل های CSS اندازه گیری می شوند. اما با بزرگ نمایی یا کوچک نمایی(Zooming) visual viewport (اگر بزرگ نمایی (zoom in) را اعمال کنیم تعداد کمتری پیکسل های CSS در آن قرار می گیرند) اندازه layout viewport تغییر نمی کند. (اگر آنها نبودند صفحه سایت بصورت مداوم تا زمانی که طول های درصدی دوباره محاسبه می شدند روان می شد)

مفهوم layout viewport

هنگامی باید به بررسی اندازه layout viewport بپردازیم که مرورگر در حداکثر مقدار کوچک نمایی قرار دارد. بسیاری از مرورگرهای موبایل در ابتدا صفحه را بصورت کوچک نمایی کامل نمایش می دهند.

نکته اینجاست : مرورگرها اندازه layout viewport را برابر با اندازه صفحه هنگامی که حداکثر کوچک نمایی بر روی آن انجام شده باشد در نظر می گیرند. (بنابراین برابر visual viewport است)

visual viewport  هم اندازه layout viewport است

در نتیجه طول و ارتفاع layout viewport برابر عناصری است که در حداکثر کوچک نمایی در صفحه نمایش، مشاهده می شود. هنگامی که کاربر بزرگ نمایی را انجام می دهد این مقدارثابت می ماند.

visual viewport کوچک تر از layout viewport است

layout viewport همیشه اندازه ثابتی دارد. اگر موبایل را بچرخانیم visual viewport تغییر می کند، اما مرورگر با بزرگنمایی خود را با شرایط جدید وفق می دهد بنابراین دوباره layout viewport طولی برابر با visual viewport خواهد داشت.

layout viewport برابر با visual viewport است

این رفتار عواقبی بر روی ارتفاع layout viewport دارد، یعنی در حالت portrait ارتفاع بصورت قابل ملاحظه ای کم می شود. اما توسعه دهندگان وب تنها به طول توجه داند و نه به ارتفاع.

layout viewport بزرگتر از visaul viewport است

اندازه گیری layout viewport

معنی :
اندازه layout viewport
اندازه گیری :
پیکسل های CSS
پشتیبانی کامل :
Opera ، iPhone ، Android ، Symbian ، Bolt ، MicroB ، Skyfire ، Obigo
خطا ها :
Iris اندازه visual viewport را می دهد.
WebKit سامسونگ نتیجه درستی می دهد اگر <meta viewport> در صفحه وجود داشته باشد در غیر اینصورت اندازه عنصر را می دهد.
فایرفاکس اندازه screen را با پیکسل های دستگاه می دهد.
اینترنت اکسپلورر مقدار 1024 * 768 را می دهد، این اطلاعات را در document.body.clientWidth/Height ذخیره کرده است و برای IE6 دسکتاپ هم همینگونه است.
NetFront مقادیر را تنها در 100% بزرگنمایی درست نمایش می دهد.
Symbian WebKit 1 (قدیمی تر از S60V3) از این مقادیر پشتیبانی نمی کند.
عدم پشتیبانی :
بلک بری

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

اندازه layout viewport را می توانیم از طریق مقادیر document.documentElement.clientWidth و -Height بدست آوریم.

محاسبه اندازه layut viewport توسط مقادیر document.documentElement.clientWidth و -Height

چرخش موبایل بر روی ارتفاع تاثیر می گذارد اما طول را ثابت در نظر می گیرد.

چرخش موبایل و تاثیر آن بر روی مقادیر clientWidth و clientHeight

اندازه گیری visual viewport

معنی :
اندازه visual viewport
اندازه گیری :
پیکسل های CSS
پشتیبانی کامل :
iPhone ، Symbian ، BlackBerry
خطا ها :
Opera و فایرفاکس طول screen را توسط پیکسل های CSS اندازه گیری می کنند
Android ، Bolt ، MicroB و NetFront اندازه layout viewport را در پیکسل های CSS می دهند.
عدم پشتیبانی :
IE پشتیبانی نمی کند ولی می توان visual viewport را با مقادیر document.documentElement.offsetWidth/Height اندازه گیری کرد.
WebKit سامسونگ با توجه به وجود یا عدم وجود <meta viewport> اندازه layout viewport یا عنصر <html> را بر می گرداند.
نامفهوم (Gibberish) :
Iris ، Skyfire ، obigo

visual viewport توسط مقادیر window.innerWidth/Height اندازه گیری می شود، با توجه به اینکه با بزرگنمایی یا کوچکنمایی کاربر، تعداد بیشتر یا کمتری پیکسل های CSS در صفحه نمایش قرار می گیرد بدیهی است که اندازه بدست آمده از این جفت خصوصیت نیز تغییر خواهد کرد.

اندازه گیری visual viewport توسط مقادیر window.innerWidth/Height

متاسفانه در این قسمت با مشکل عدم پشتیبانی مناسب مرورگرها مواجه می شویم. تعداد بسیاری از مرورگرها هنوز از اندازه visual viewport پشتیبانی نمی کنند.

با توجه به اینکه مرورگری نیست که این مقادیر را در جفت خصوصیت دیگری ذخیره کند بنابراین حدس می زنم که window.innerWidth/Height استاندارد مناسبی است با اینکه پشتیبانی خوبی از آن انجام نشده است.

مانیتور (اندازه صفحه نمایش)

معنی :
اندازه صفحه نمایش
اندازه گیری :
پیکسل های دستگاه
پشتیبانی کامل :
Opera Mini ، Android ، Symbian ، Iris ، Firefox ، MicroB ، IE ، BlackBerry
خطا ها :
Opera موبایل بر روی ویندوزهای موبایل تنها اندازه landscape را می دهد. Opera موبایل در S60 مقدار صحیحی را محاسبه می کند.
WebKit سامسونگ اندازه layout viewport یا اندازه عنصر <html> را با توجه به اینکه <meta viewport> وجود داشته باشد یا نه، می دهد.
iPhone و Obigo تنها اندازه حالت portrait را می دهند.
NetFront تنها اندازه حالت landscape را می دهند.
نامفهوم (Gibberish) :
Skyfire ، Bolt

مانند دسکتاپ اندازه صفحه نمایش را می توانیم با استفاده از خصوصیات screen.width/height در پیکسل های دستگاه به دست آوریم.

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

محاسبه اندازه صفحه نمایش توسط مقادیر screen.width و screen.height

مرتبه بزرگ نمایی (zoom level)

مرتبه بزرگ نمایی فعلی مرورگر بصورت مستقیم بدست نمی آید اما با تقسیم screen.width بر window.innerWidth قابل محاسبه است. البته این در صورتی است که مرورگر از این دو مقدار پشتیبانی کند.

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

این اطلاعات را می توانیم با خصوصیت window.innerWidth بدست آوریم اگر مرورگر از این خصوصیت پشتیبانی کند.

انحراف حاصل از پیمایش صفحه (Scrolling offset)

معنی :
انحراف پیمایش، که به معنی انحرافvisual viewport نسبت به layout viewport است.
اندازه گیری :
پیکسل های CSS
پشتیبانی کامل :
iPhone ، Android ، Symbian ، Iris ، MicroB ، Skyfire ، Obigo
خطا ها :
Opera ، Bolt ، Firefox و NetFront همیشه مقدار 0 را می دهند.
WebKit سامسونگ اگر تگ <meta viewport> در صفحه وجود داشته باشد مقدار درست را می دهد.
عدم پشتیبانی :
IE ، BlackBerry. IE از خصوصیات document.documentElement.scrollLeft/Top استفاده می کند.

مکان نسبی visual viewport  نسبت به layout viewport، اندازه دیگری است که نیازداریم بدانیم. همانند دسکتاپ این اندازه بیانگر انحراف حاصل از پیشمایش است و در خصوصیات window.pageX/YOffset ذخیره می شود.

اندازه گیری طول پیمایش شده در صفحه توسط مقادیر window.pageXOffset و window.pageYOffset

عنصر <html>

معنی :
اندازه عنصر <html>
اندازه گیری :
پیکسل های CSS
پشتیبانی کامل :
Opera ، iPhone ، Android ، Symbian ، Samsung ، Iris ، Bolt ، Firefox ، MicroB ، Skyfire ، BlackBerry ، Obigo
خطا ها :
NetFront تنها هنگامی مقدار درست را می دهد که بزرگ نمایی 100% باشد.
اینترنت اکسپلورر از این خصوصیت برای visual viewport استفاده می کند و می توانیم در آن اندازه عنصر <html> را با document.body.clientWidth/Height بدست آوریم.

همانند دسکتاپ برای محاسبه اندازه عنصر <html> از خصوصیات document.documentElement.offsetWidth/Height استفاده می کنیم، اندازه بدست آمده در پیکسل های CSS است.

اندازه گیری عنصر <html> توسط مقادیر document.documentElement.offsetWidth/Height

Media queries

معنی :
اندازه عنصر <html> (با پیکسل های دستگاه) یا اندازه دستگاه را با (با پیکسل های دستگاه) محاسبه می کند.
پشتیبانی کامل :
Opera ، iPhone ، Android ، Symbian ، Samsung ، Iris ، Bolt ، Firefox ، MicroB
عدم پشتیبانی :
Skyfire ، IE ، BlackBerry ، NetFront ، Obigo
توجه :
در این قسمت آزمونی بر روی صحت اطلاعات انجام نشده و تنها این موضوع که مرورگر اطلاعات را از جفت خصوصیت مناسب می گیرد، بررسی شده است.

media query ها شبیه حالت دسکتاپ هستند. width/height اندازه layout viewport را در نظر می گیرند و مقادیر را در پیکسل های CSS می دهند، device-width/height از مانیتور دستگاه استفاده کرده و اندازه ها را در پیکسل های دستگاه می دهند.

به عبارت دیگر، width/height مقدار خصوصیت های document.documentElement.clientWidth/Height را بر می گردانند و device-width/height اندازه خصوصیت های screen.width/height (در حقیقت این قاعده برای همه مرورگرها صادق است حتی اگر خصوصیت ها مقدار نادرستی را بر گردانند)

media query ها در موبایل

حال کدام اندازه برای یک توسعه دهنده وب مناسب تر است؟ واقعا نمی دانم.

در ابتدا با این استدلال که device-width اطلاعاتی کاربردی درباره دستگاه به ما می دهد، فکر کردم که بسیار مهم تر است.  به عنوان مثال می توانیم اندازه layout viewport را تغییر دهیم تا با دستگاه هم اندازه شود و داخل آن قرار بگیرد. هر چند که این کار را با استفاده از تگ <meta viewport> هم می توان انجام داد. پس مطلقا نیازی به استفاده از device-width نداریم.

بنابراین آیا width در بین media query ها مهتر است؟ شاید، به این دلیل که سرنخ هایی درباره اینکه سازندگان مرورگر چه اندازه ای را برای وب سایت در دستگاه فعلی مناسب می دانند به ما می دهد. اما به غیر از این نکته مبهم در حقیقت width اطلاعات دیگری ندارد.

بنابراین مردد بود. در این زمان فکر می کنم media query ها تنها برای نشان دادن اینکه در کامپیوتر دسکتاپ یا تبلت یا موبایل هستیم سودمند هستند و در موبایل ها یا تبلت های مختلف کاربردی ندارند.

یا چیزی شبیه این

مختصات رویداد

معنی :
به متن اصلی مراجعه کنید.
اندازه گیری :
به متن اصلی مراجعه کنید.
پشتیبانی کامل :
Symbian ، Iris
خطا ها :
Opera موبایل در تمام جفت خصوصیات مقدار pageX/Y را بر می گرداند، اما هنگامی که در صفحه پیمایش بزرگی انجام دهیم خطاهایی بوجود می آید.
در آیفون، فایرفاکس و بلک بری مقدار clientX/Y برابر است با pageX/Y
در MicroB و اندروید screenX/Y برابر clientX/Y است (به عبارت دیگر هر دو توسط پیکسل های CSS محاسبه شده اند)
در فایرفاکس screenX/Y اشتباه است.
اینترنت اکسپلورر، بلک بری، و Obigo از pageX/Y پشتیبانی نمی کند.
در NetFront تمام مقادیر برابر screenX/Y هستند.
در Obigo جفت خصوصیت clientX/Y همان screenX/Y است.
WebKit سامسونگ همیشه pageX/Y را بر می گرداند.
تست نشده :
Opera Mini ، Bolt ، Skyfire

مختصات رویداد در موبایل تقریبا شبیه دسکتاپ است. متاسفانه در 12 مرورگر تست شده تنها Symbian webKit و Iris تمام سه مختصات را به درستی محاسبه می کنند. بقیه مرورگرها کم و بیش خطاهای عمده ای داشتند.

pageX/Y کماکان نسبت به صفحه در پیکسل های CSS است، و همانند دسکتاپ کاربردی ترین جفت خصوصیت است.

event.pageX و event.pageY در موبایل

clientX/Y نسبت به visual viewport در پیکسل های CSS است. هر چند معقول است اما کاملا مطمئن نیست که مناسب هم هست.

screenX/Y نسبت به screen در پیکسل های دستگاه محاسبه می شود. البته شبیه clientX/Y است و پیکسل های دستگاه هم غیر کاربردی هستند. بنابراین نیازی به نگرانی درباره screenX/Y نیست، زیرا کاملا شبیه دسکتاپ خصوصیت بی کاربردی است.

event.screenX/Y و event.clientX/Y در موبایل

Meta viewport

معنی :
تنظیم کننده طول layout viewport
اندازه گیری :
پیکسل های CSS
پشتیبانی کامل :
Opera موبایل ، iPhone ، اندروید ، Iris ، IE ، BlackBerry ، Obigo
خطا ها :
Skyfire صفحه آزمون را نتوانست اجرا کند.
اگر <meta viewport> در صفحه وجود داشته باشد، Samsung WebKit ، معنی چندین خصوصیت را تغییر می دهد.
Opera Mobile ، iPhone ، Samsung و BlackBerry به کاربر اجازه کوچک نمایی نمی دهند.

در نهایت به بررسی <meta name="viewport" content="width=320"> می پردازیم که در ابتدا توسط اپل استفاده شد و سپس بسیاری از مرورگرها از آن تقلید کردند. این تگ برای تغییر اندازه layout viewport استفاده می شود. برای نشان دادن اینکه چرا این تگ ضروری است باید کمی به عقب تر برگردیم.

فرض کنید که صفحه ساده ای ساخته اید و عناصر آن طول مشخصی ندارند. عناصر این صفحه تا زمانی که طول آنها 100% طول layout viewport شود کش می آیند. اکثر مرورگرها تا زمانی که تمام layout viewport داخل مانیتور قرار بگیرد کوچک نمایی (zoom out) را انجام می دهند. نتیجه چیزی شبیه تصویر زیر است :

نمایش اولیه تصویر در موبایل هنگامی که از meta viewport استفاده نشده است

تمام کاربران پس از نمایش صفحه شروع به بزرگ کردن آن می کنند و چون اکثر مرورگرها اندازه عناصر را ثابت نگه می دارند در نتیجه خواندن متون سخت خواهد شد.

نمایش صفحه بدون استفاده از meta viewport بعد از بزرگ نمایی کاربر

( در اینجا استثنا قابل توجه Android WebKit است که اندازه عناصر در بردارنده متن را تا زمانی که در صفحه نمایش قرار بگیرند کوچک می کند. این کاملا شاهکار است و من فکر می کنم مروگرهای دیگر هم باید این روند را انجام دهند. در این باره بعدا مطلبی بصورت کامل خواهم نوشت)

فرض کنید استایل html{width:320px} را در صفحه قرار دهیم. حالا اندازه <html> و بقیه عناصر داخل آن کوچکتر خواهد شد زیرا اندازه ای برابر با 100% از 320px را دارند. در ابتدا کاربر با صفحه ای حاصل از بزرگ نمایی مرورگر روبرو می شود که بیشتر قسمت های این صفحه خالی است و تنها با کوچکنمایی به نتیجه مطلوب از استایل بالا می رسیم.

مشاهده صفحه بدون استفاده از meta viewport و اندازه 320 پیکسل برای عنصر <html>

برای حل این موضوع اپل تگ meta viewport را بوجود آورد. با قرار دادن تگ <meta name="viewport" content="width=320"> داخل صفحه، مرورگر اندازه layout viewport  را برابر 320px در نظر می گیرد. در نتیجه صفحه در ابتدا نمایش هم ظاهر مطلوب ما را دارد.

مشاهده صفحه سایت در موبایل هنگام استفاده از تگ meta viewport

می توانیم اندازه layout viewport را در هر ابعادی تنظیم کنیم. مثلا می توانیم از device-width استفاده کنیم که اندازه screen.width را در (پیکسل های دستگاه) به عنوان مرجعی قرار داده و بر اساس آن layout viewport را تنظیم می کند.

نکته ای وجود دارد و آن این است که گاهی اوقات screen.width بخاطر زیاد بودن تعداد پیکسل ها احساس خوبی برای کاربر بوجود نمی آورد. به عنوان مثال Nexus دارای طولی برابر 480px است، اما بخاطر اینکه 480px زیاد است مهندسان گوگل تصمیم گرفتند که اندازه device-width را به اندازه بخشی از 480px در نظر بگیرند. آنها اندازه device-width را 2/3 مقدار اصلی در نظر گرفتند بنابراین نتیجه شبیه iPhone و برابر 320px خواهد بود.

اگر بر اساس شایعات، iPhone جدید هم تعداد بیشتری پیکسل داشته باشد. (و البته نیازی نیست که برای این موضوع صفحه نمایش بزرگ تر شود!) تعجب نمی کنم که Apple هم این کار را انجام دهد. شاید در نهایت device-width تنها به معنی 320px باشد.

اين متن ترجمه مقاله اي در سايت www.quirksmode.org است

تعداد بازدید از مطلب : 2084