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

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

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

تفاوت پیکسل های دستگاه (device pixels) و پیکسل های CSS

اولین مفهومی که لازم است بدانیم تفاوت پیکسل های دستگاه و پیکسلهای CSS است. پیکسل های دستگاه (device pixels) تعداد پیکسل های دستگاهی است که با آن کار می کنیم و دید واقعی ما را از پیکسل بیان می کند. طول و عرض آن با screen.width/height بدست می آید.

فرض کنیم عنصری با طول 128 پیکسل(width : 128px) داریم و طول مانیتور 1024 پیکسل باشد اگر مروگر خود را بصورت کامل باز کنیم در اینصورت هشت عدد از این عنصر (element) طول مانیتور را پر می کند.(با صرفنظر کردن از بعضی مفاهیم حرفه ای تر)

بزرگ کردن تصور (zoom in) در مرورگرهای جدید باعث کش آمدن پیکسل ها می شود. طول عنصر از 128 پیکسل به 256 پیکسل تغییر نمی کند در عوض طول حقیقی پیکسل ها دو برابر می شود. عنصر ما هنوز 128 پیکسل (پیکسلهای CSS) طول دارد هر چند 256 پیکسل از مانیتور را استفاده کرده است (پیکسل های دستگاه)

به بیانی دیگر بزرگ کردن 200% تصویر باعث می شود که پیکسل ها در CSS چهار برابر بزرگ تر از پیکسل های مانیتور (پیکسل های دستگاه) شوند.(دو برابر در طول و دو برابر در عرض که نتیجه آن 4 برابر شدن پیکسل است).

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

پیکسل ها در بزرگنمایی 100%

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

پیکسل های دستگاه و css هنگام کوچک کردن مرورگر

اگر صفحه را بزگتر (zoom out) کنیم بر خلاف حالت بالا پیکسل های CSS بزرگتر از پیکسل های دستگاه می شوند.

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

نکته اینجاست که ما علاقمند به پیکسل های CSS هستیم. این پیکسل ها هستند که روند نمایش صفحه را توسط style sheet به مرورگر دیکته می کنند.

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

بزرگنمایی 100%

مثالی را بزرگنمایی 100% بیان می کنیم توجه داشته باشید که :

در بزرگنمایی 100% یک پیکسل CSS دقیقا  برابر یک پیکسل دستگاه است.

مفهوم بزرگنمایی 100% در توضیح نکات آتی بسیار مفید است اما نباید نگران روندکار فعلی خود باشیم. در مرورگرهای desktop سایت خود را در بزرگنمایی 100% چک می کنیم و این حالت جادویی پیکسل های CSS است که نمی گذارند طرح بندی صفحه با کوچک یا بزرگ کردن آن تغییر کند.

اندازه screen

معنی :
تمام اندازه مانیتور کاربر
اندازه گیری :
پیکسل های دستگاه
خطای مرورگر :
IE7 و IE8 این اندازه ها را بصورت پیکسل های CSS می دهند.

با اندازه بعضی خصوصیات بحث را ادامه می دهیم. ابتدا با screen.width/height شروع می کنیم. این مقادیر در بردارنده تمام طول و عرض مانیتور کاربر هستند. با توجه به اینکه این مقادیر تغییر نمی کنند و وابسته به مانیتور کاربر هستند تا به مرورگر با پیکسل های دستگاه محاسبه می شوند.

screen.width screen.height

خوب! اما این اندازه ها به چه کار می آیند؟

در اصل هیچ. اندازه مانیتور کاربر برای ما مهم نیست مگر اینکه بخواهیم آماری از اندازه مانیتور کاربران در اینترنت جمع آوری کنیم.

اندازه window

معنی :
اندازه تمام صفحه مرورگر کاربر به همراه نوار پیمایش
اندازه گیری :
پیکسل های CSS
خطای مرورگر :
IE از این ویژگی پشتیبانی نمی کند و Opera آنرا بصورت پیکسل های دستگاه محاسبه می کند.

برای بدست آوردن اندازه ای که مرورگر کاربر برای ما فراهم می کند یا مقدار فضایی که کاربر برای مشاهده سایت دارد از window.innerWidth و window.innerHeight استفاده می کنیم.

window.innerWidth window.innerHeight

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

(در اینجا استثناء Opera است که هنگام بزرگ نمایی، این دو مقدار در آن کوچک نمی شوند و بر حسب پیکسل های دستگاه اندازه گیری می شوند. این مورد در desktop آزار دهنده است اما در موبایل می تواند نابود کننده باشد.)

بزرگ نمایی در Opera  و مقدادیر window.innerWidth window.innerHeight

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

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

معنی :
فاصله (offset) پیمایش شده صفحه
اندازه گیری :
پیکسل های CSS
خطای مرورگر :
ندارد

window.pageXOffset و window.pageYOffset شامل مقدار افقی و عمودی انحرافی است که با پیمایش (بالا، پایین یا چپ و راست بردن صفحه) کاربر بوجود آمده است.

window.pageYOffset window.pageXOffset

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

در تئوری اگر کاربر صفحه را بالا ببرد و سپس بزرگنمایی را انجام دهد، مقدار window.pageX/YOffset تغییر خواهد کرد. مرورگرها سعی می کنند عنصری که هم اکنون بالای صفحه است کماکان در جای خود باقی بماند اما این روند همیشه بصورت کامل کار نمی کند و در عمل window.pageX/YOffset حقیقتا تغییر نمی کند و همچنین مقدار پیکسل های CSS ای هم که این مقادیر نشان می دهند تغییر نمی کنند. (البته نه کاملا بدون تغییر)

بزرگ نمایی مرورگر و تغییر window.pageYOffset

مفهوم viewport

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

عنصر <html> که بالاترین تگ سایت است تابعی از viewport است.

این موضوع ممکن است کمی مبهم باشد. فرض کنید طرحی شناور داریم و در گوشه آن بلاکی با طول width:10% وجود دارد. با کوچک و بزرگ کردن صفحه این بلاک بصورت منظم کوچک و بزرگ می شود. اما واقعا در این لحظه چه اتفاقی می افتد؟

بصورت فنی، چه اتفاقی می افتد اگر این بلاک 10% طول عنصر پدر را داشته باشد. فرض کنیم پدر تگ <body> است (و ما طول آنرا نداریم) بنابراین سوال اینجاست که طول <body> چقدر است.

و همچنین طول <html> چقدر است؟ با توجه به اینکه <html> اندازه ای برابر با طول پنجره مرورگر دارد بلاک مفروض ما 10% فضای پنجره مرورگر را می گیرد. توسعه دهندگان وب این موضوع را بصورت ضمنی می دانند و از آن استفاده می کنند.

مطلبی که ممکن است نسبت به آن شناختی نداشته باشیم این است که در تئوری این موضوع چگونه عمل می کند. در تئوری طول عنصر <html> محدود به طول viewport است. این عنصر 100% طول viewport را به خود اختصاص می دهد.

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

عواقب

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

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

این نتیجه تعریف viewport است. نوارآبی با طول 100% از عنصر <html> تنظیم شده است و این عنصر هم به اندازه viewport که برابر اندازه پنجره مروگر است می باشد.

نکته اینجاست که در بزرگنمایی 100% مشکلی وجود ندارد. اگر بزرگنمایی را بیشتر کنیم viewport کوچکتر از طول کلی سایت می شود. این موضوع به خودی خود مشکلی پیش نمی آورد، مطلب ها به بیرون <html> نشت کرده اند و این بخاطر overflow:visible است که باعث می شود مطالبی که بیرون نشت کرده اند قابل مشاهده باشند (در سایت فعلی بخاط اینکه طول مطالب محدود است بیرون زدگی مطلب وجود ندارد)

اما نوار آبی به بیرون نشت نمی کند طول آن 100% است و مرورگرها از این قانون که طول آن برابر viewport است تبعیت می کنند و توجهی به اینکه طول آن هم اکنون کم است ندارند.

طول (width) مطلب (document) ؟

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

من (نویسنده مطلب) در حال رسیدن به این اعتقاد هستم که به مقداری در جاوااسکریپت نیاز داریم که آنچه را که طول document می خوانیم را برای ما محاسبه کند (بدیهی است در پیکسل های CSS)

طول مطلب document width

ممکن است این احساس ناخوشایند را داشته باشیم که چرا این مقدار در CSS هم وجود ندارد؟ خیلی دوست داشتم طول نوار آبی بالای صفحه با width:100% نسبت به طول document محاسبه می شد تا عنصر <html> این موضوع تصمیمی برای حرفه ای بودن است هر چند از اینکه انجام نشود تعجب نمی کنم)

سازندگان مرورگرها، شما چه فکر می کنید؟

اندازه گیری viewport

معنی :
اندازه viewport
اندازه گیری :
پیکسل های CSS
خطای مرورگر :
ندارد

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

اندازه گیری viewport توسط document.documentElement.clientWidth و -Height

اگر اطلاعی درباره DOM داشته باشیم می دانیم document.documentElement در حقیقت همان عنصر <html> یا ریشه اصلی صفحه HTML است. هرچند viewport یک درجه بالاتر است و می توان گفت که دربردارنده <html> است. می توانیم به جای مقادیر بالا از طول عنصر <html> استفاده کنیم. (توصیه نمی شود ولی شدنی است)

با توجه به مطالب بالا document.documentElement.clientWidth و -Height هنوز اندازه viewport را نمایش می دهند نه اندازه عنصر <html> را. (این قاعده ای خاص است برای خصوصیات دیگر این عنصر در تمام موارد اندازه حقیقی خود عنصر محاسبه می شود)

اندازه viewport و اندازه <html>

بنابراین document.documentElement.clientWidth و -Height همیشه اندازه viewport را و نه اندازه عنصر <html> را نمایش می دهند.

دو جفت خصوصیت

آیا طول و عرض viewport با مقادیر window.innerWidth/Height قابل محاسبه است؟ در جواب هم بله و هم خیر.

یک تفاوت قراردادی ما بین این دو مقدار وجود دارد و آن این است که دو مقدار document.documentElement.clientWidth و -Height شامل نوار پیمایش (scrollbar) نمی شوند در صورتی که window.innerWidth و Height اندازه پنجره را به همراه نوار پیمایش نمایش می دهند. هر چند که این موضوع بی اهمیت است.

در حقیقت این دو جفت خصوصیت بین جنگ مرورگرها قرار داشته اند. اگر به قدیم بر گردیم Netscape تنها از window.innerWidth/Height پشتیبانی می کرد و اینترنت اکسپلورر از document.documentElement.clientWidth و -Height . از آن زمان تمام مرورگرها شروع به پشتیبانی از مقدار document.documentElement.clientWidth و -Height کردند اما اینترنت اکسپلورر هیچگاه window.innerWidth/Height را انتخاب نکرد.

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

اندازه گیری <html>

معنی :
اندازه عنصر <html> (وبنابراین اندازه صفحه)
اندازه گیری :
پیکسل های CSS
خطای مرورگر :
IE این خصوصیت را اندازه viewport می گیرد نه اندازه تگ <html>

بنابراین clientWidth/Height ابعاد viewport را محاسبه می کنند. ولی چگونه می توانیم اندازه خود عنصر <html> را بدست آوریم؟ اندازه <html> داخل مقادیر document.documentElement.offsetWidth و -Height قرار دارد.

اندازه <html> توسط document.documentElement.offsetWidth و -Height

این خواص به درستی اندازه عنصر <html> را به عنوان یک عنصر block-level بر می گردانند و اگر طول عنصر <html> را تغییر دهیم، offsetWidth مقدار جدید را بازتاب می کند.

اندازه <html> هنگام تغییر طول آن

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

معنی :
به متن اصلی مراجعه کنید
اندازه گیری :
به متن اصلی مراجعه کنید
خطای مرورگر :
IE از pageX/Y پشتیبانی نمی کند.
IE و Opera مقدار screenX/Y را در پیکسل های CSS محاسبه می کنند.

زمانی که رویداد موشواره (mouse) رخ می دهد بیشتر از پنج جفت خصوصیت وجود دارد که هر کدام در بردارنده اطلاعاتی درباره مکان درست رویداد هستند. برای بحث ما سه عدد از این رویدادها اهمیت دارد:

  1.  pageX/Y که مختصات را نسبت به عنصر <html> در پیکسل های CSS می دهد.
  2.  clientX/Y که مختصات را نسبت به viewport در پیکسل های CSS می دهد.
  3. screenX/Y که مختصات را نسبت به screen (مانیتور) به پیکسل های دستگاه می دهد.

screenX/Y , cientX/Y , pageX/Y

فاصله رویداد از صفحه توسط pageX/Y محاسبه می شود

در 90% موارد از pageX/Y استفاده می کنیم زیرا معمولا مکان رویداد را نسبت به document می خواهیم. در 10% باقی مانده از clientX/Y استفاده می کنیم. هیچگاه نیازی به دانستن مختصات رویداد نسبت به screen نداریم.

media queries

معنی :
به متن اصلی مراجعه کنید
اندازه گیری :
به متن اصلی مراجعه کنید
خطای مرورگر :
IE از آن پشتیبانی نمی کند
برای device-width/height فایرفاکس از screen.width/height استفاده می کند اگر آنها با پیکسل های CSS اندازه گیری شده باشند.
برای width/height مرورگرهای safari و chrome از document.documentElement.clientWidth/Height استفاده می کنند اگر آنها با پیکسل های device اندازه گیری شده باشند.

در انتها کمی به بحث درباره media queries می پردازیم. قاعده اش بسیار ساده است: می توانیم قواعد CSS ای برای اجرا در حالت هایی که طول صفحه بیشتر، مساوی یا کمتر از مقدار خاصی است تعیین کنیم. به عنوان مثال :

div.sidebar {
	width: 300px;
}

@media all and (max-width: 400px) {
	// styles assigned when width is smaller than 400px;
	div.sidebar {
		width: 100px;
	}

}

در این کد ماژول حاشیه صفحه دارای طولی برابر 300px است مگر هنگامی که طول صفحه کمتر از 400px باشد که در این حالت ماژول ما دارای طولی برابر 100px است.

سوال اینجاست : کدام طول را اندازه می گیریم.

دو media query در این زمینه وجود دارد : width/height و device-width/device-height

  1. width/height شبیه مقدار document.documentElement.cientWidth/Height است (همان viewport) و با پیکسل های CSS کار می کند.
  2. device-width/height مشابه screen.width/height است (مانیتور) و با پیکسل های دستگاه کار می کند.

نمایش اندازه media queries و مقادیر device-width/height و width/height

از width استفاده می کنیم زیرا توسعه دهندگان وب علاقه ای به device-width ندارند. آنها تمایل دارند که با طول پنجره مرورگر کار کنند.

بنابراین از width استفاده کرده و device-width را بر روی desktop فراموش می کنیم. همانطور که خواهید دید این مطلب در رابطه با موبایل بسیار بهم ریخته تر است.

نتیجه گیری

به خاتمه مبحث مرورگرهای desktop رسیدیم . در قسمت دوم این مقالات به بررسی موبایل و بیان بعضی تفاوت های مهم آن با desktop می پردازیم.

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

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