热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

两个viewport的故事桌面版(译)

在这个系列文章中,我将说明viewports和重要元素的宽度是如何工作的,比如元素、window和scrren的宽度。这篇文章是关于桌面浏览器的,目的是为介绍移动浏览器

在这个系列文章中,我将说明viewports和重要元素的宽度是如何工作的,比如元素、window和 scrren的宽度。

这篇文章是关于桌面浏览器的,目的是为介绍移动浏览器做好准备。大部分的web开发者已经对桌面浏览器的一些概念很熟悉了。在移动浏览器上我们会发现同样的概念,只不过要更复杂一些,回顾一下这些熟悉的概念将对我们理解移动浏览器有很大的帮助。

设备像素和css像素

你需要理解的第一个概念是css像素和设备像素之间的区别。

设备像素,顾名思义,无论你用什么设备,设备像素都是表示设备的实际分辨率。设备像素可以从screen.width/height读取。

如果你给一个元素widht:128px,你的显示器是1024px宽,你最大化你的浏览器,这个元素可以在屏幕上平铺8个。(大概;忽略一些不确定因素)

如果用户缩放了页面,这个值将发生改变。如果用户放大浏览器到200%,你的128px的元素只能在屏幕上平铺4个了。

用户缩放在浏览器中是通过拉伸像素实现的。也就是说,元素的宽度并没有从128px变成256px,而是像素的尺寸变成了原来的两倍。综上,这个元素仍旧有128px的css像素,但是此时它却占有256px的设备像素。

换句话说,放到到200%使一个css像素尺寸了变成了4倍的设备像素的尺寸。(两倍的宽,两倍的高)。

下面几个图片可以很清楚的说明这个概念。第一个是缩放为100%,这个没什么可看的。css像素完全覆盖了设备像素。

《两个viewport的故事-桌面版(译)》

现在我们缩小页面。css像素开始缩小,意味着一个设备像素可以覆盖若干个css像素。

《两个viewport的故事-桌面版(译)》

如果你放大,相反的事情就发生了。css像素开始变大,现在一个css像素可以覆盖若干个设备像素

《两个viewport的故事-桌面版(译)》

关键点在于你只需要关系css像素,它决定你的样式如何渲染。

设备像素对于你来说几乎是无用的。对用户来说不是,用户会缩放页面直到页面看起来舒服位置。但是这个缩放比对你来说不重要,浏览器会自动根据缩放比来缩小或者放大的你的css像素。

100% zoom

我上面提到的例子,前提是100%的缩放。现在可以更严格的定义一下:

在100%缩放的情况下,css像素和设备像素是严格相等的。

这100%缩放的概念在我们的这个解释中是非常有用的,但是我们在日常开发中不需要过度担心这个。在桌面浏览器开发中通常你都是在100%缩放的情况下,即使用户缩放页面,css像素的原理也能保证你的布局保持比例,不能打乱。

Screen Size

让我们来看一下实际的尺寸吧。我们从screen.widthscreen.height开始。他们表示用户屏幕的总宽度和总高度。他们的单位是设备像素,因为它们从来不会改变:它们是显示器的特性,不是浏览器的特性。

《两个viewport的故事-桌面版(译)》

很有意思!但是我们能用这个信息做什么那?

基本没有用。用户的显示器尺寸对我们来说不重要,除非你想做一个web资料数据库。

Window Size

相反,你关心的是浏览器窗口的内部尺寸是什么。那会告诉你用于展示你的css布局的空间是多大。你可以通过window.innerWidthwindow.innerHeight来获取。

《两个viewport的故事-桌面版(译)》

很明显,窗口的内部宽度的单位是css像素。你需要知道的是你的css布局有多少可以呈现在浏览器窗口中,而且这个呈现的数量会随着用户放大页面而减少(css像素越大,所呈现的内容越少)。因此如果用户放大页面,你可用的空间也就越少,在window.innerWidth/Height反应为值减小。

《两个viewport的故事-桌面版(译)》

注意!这个宽度和高度包括滚动条。滚动条也被认为是浏览器窗口的一部分。(这个有历史的原因)

Scrolling offset

window.pageXOffsetwindow.pageYOffset,表示document横向和纵向的滚动偏移。通过这两个属性,你可以知道用户滚动的位置。

《两个viewport的故事-桌面版(译)》

这两个属性的单位也是css像素。理论上,如果用户向上滚动然后放大,window.pageX/YOffset应该发生改变。但是浏览器做了一些处理,在用户缩放的时候,浏览器试图使同一个元素保持在浏览器窗口的顶部来使页面看起来不会跳动。这意味着window.pageX/YOffset在用户缩放的时候不会改变:被滚动出屏幕的css像素数不会改变。

《两个viewport的故事-桌面版(译)》

概念:the viewport

在我们继续介绍更多的js属性之前,我们必须介绍另外一个概念:viewport。

viewport的作用是限制元素,是网站的最顶级的块级元素。

这听起来或许有一点模糊,我们来举一个实际的例子。假设你有一个流体布局,你的侧边栏是width:10%.当你调整浏览器的大小时,侧边栏随着增大或减小。那它到底是怎么工作的那?

从技术上说,侧边栏在获取它父元素的宽度的10%的时候发生了什么。我们假定元素为父元素。所以现在问题变成了元素(你没有给赋宽度)的宽度是多少。

通常来说,所有的块级元素的宽度都是父元素的宽度的100%。因此元素是和它的父元素一样宽的。

现在元素的宽度是多少那?为什么它和浏览器一样宽。这也是为什么你的width:10%的侧边栏占整个浏览器宽度的10%的原因。所有的web开发者都知道这个事实。

你或许不知道这其中的工作原理。理论上,html元素的宽度是被viewport的宽度限制的。html元素等于viewport的宽度。

viewport和浏览器窗口相等的:它就是这么被定义的。viewport不是一个HTML结构,所以你不能靠css影响它。它就是有浏览器窗口的宽度和高度(桌面);在移动浏览器上它是比较复杂的。

结果

这些东西有时候会有一些奇怪的结果。你能这个网站(http://www.quirksmode.org/mob…。滚动到最顶部,然后放大页面2到3倍,使页面内容溢出浏览器窗口。

现在滚动到最右边,你将会看到顶部的蓝色栏不再被正确的排列。

《两个viewport的故事-桌面版(译)》

这个行为是viewport被定义的方式导致的。我给了蓝色顶部栏一个width:100%.什么的100%?html元素的100%。元素和viewport是等宽的,所以和浏览器窗口也是等宽的。

重点是:在100%缩放时,它是正常的,现在我们放大页面,导致viewport变的比我们页面的总宽度小。对于它自己来说这不重要,页面的内容溢出了html元素,但是html元素是[overflow](http://www.quirksmode.org/css/overflow.html): visible,这就意味着超出的元素会被显示。

但是蓝色顶部栏没有溢出。我给了它width:100%,浏览器会给它一个viewport的宽度。他们不关心现在的宽度太小了。

《两个viewport的故事-桌面版(译)》

document width?

我真正想知道的是页面内容的总宽度是多少,包括突出的部分。据我所知,浏览器并未提供这个值。

我开始相信我们需要一个js属性对来表示我称作”document width”的值。

《两个viewport的故事-桌面版(译)》

如果我们真是觉得这样不爽,为什么不把document width的值暴露给css那?我希望蓝色顶部栏继承document宽度,而不是html元素的宽度。(这个确实有些棘手,如果不可能实现我也不会觉得惊讶)

浏览器厂商,你们怎么认为那?

viewport尺寸

你或许想要知道viewport的尺寸。他们可以通过document.documentElement.clientWidth/clientHeight来获取.

《两个viewport的故事-桌面版(译)》

如果你了解dom结构,你就知道document.documentElement其实是元素:文档的根元素。然而,viewport是更高一级的,可以说它是包含元素的元素。如果你给了元素一个宽度,那就变得比较重要了(不推荐这样做,但是这是可以的)。即使在这种情况下,document.documentElement.clientWidth/clientHeight仍旧给出的是viewport的尺寸,而不是html的尺寸。(这是一个只对这个元素和这个属性对起作用的特例。其他情况下clientWidth/clientHeight都是取元素的真实尺寸)。

《两个viewport的故事-桌面版(译)》

因此document.documentElement.clientWidth/clientHeight总是给出viewport的尺寸,无视html的尺寸。

两对属性值

那么viewport的尺寸是不是也可以由window.innerWidth/Height给出。答案是也不是。

这两对属性值的唯一区别在于,window.innerWidth/Height包括滚动条的宽度,document.documentElement.clientWidth/clientHeight不包括。

我们之所以有两对属性是浏览器大战的产物。当时Netscape只支持window.innerWidth/Height,而IE只支持document.documentElement.clientWidth/clientHeight。当所有其他浏览器开始支持document.documentElement.clientWidth/clientHeight的时候,IE仍旧不支持window.innerWidth/Height.在桌面浏览器上有两个属性对是一个烦人的事情,但是在移动浏览器上它是一个福音。

html元素的尺寸

document.documentElement.clientWidth/clientHeight在所有的情况下都给出的是viewport的尺寸。那么我们从哪里获取html元素自身的宽和高那?他们被存在document.documentElement.offsetWidth/offsetHeight里。

《两个viewport的故事-桌面版(译)》

这两个属性真地给了你一个访问元素作为块级元素的接口。如果你设置width或者offsetWidth将会影响这两个属性。

《两个viewport的故事-桌面版(译)》

事件坐标

有一些事件坐标值。当一个鼠标事件发生时,不少于5对属性值会被暴露出来给你事件发生的具体位置信息。其中3对是对我们的讨论来说重要的:

1. pageX/Y给出相对于html元素的坐标,单位是css像素
2. clientX/Y给出相对于viewport的坐标,单位是css像素
3. screenX/Y给出相对于屏幕的坐标,单位是设备像素

pageX/Y

《两个viewport的故事-桌面版(译)》

clientX/Y

《两个viewport的故事-桌面版(译)》

screenX/Y

《两个viewport的故事-桌面版(译)》

你90%的情况下都会使用pageX/Y;通常你想要知道相对于document的位置。其他的10%你想要用clientX/Y.你基本不需要知道相对于屏幕的尺寸。

媒体查询

最后,说一些媒体查询。这个思想很简单:你可以指定在页面在不同条件下运行不同的css,比如页面宽度大于、等于、小于某个尺寸的时候。

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

现在这个sidebar在宽度大于400px的时候宽300px,小于等于400px的时候宽100px;

问题是哪个宽度和400px比较?

有两个相关的媒体查询:width/heightdevice-width/device-height.

1. `width/height`用的是`documentElement.clientWidth/height`(就是viewport)。单位是css像素。
2. `device-width/device-height`用的是`screen.width/height`.单位是设备像素。

《两个viewport的故事-桌面版(译)》

应该用哪个宽度?想都不用想,当然是width。web开发者对设备宽度不感兴趣,只是对浏览器窗口的宽度感兴趣。

在桌面浏览器上使用width,忘记device-width.正如我们所看到的,这在移动设备上是更复杂的。

总结

这篇文章总结了我们对桌面浏览器的探索。第二篇文章将介绍这些概念在移动浏览器的应用,并重点说明和桌面浏览器的不同。

博客地址


推荐阅读
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文介绍了腾讯最近开源的BERT推理模型TurboTransformers,该模型在推理速度上比PyTorch快1~4倍。TurboTransformers采用了分层设计的思想,通过简化问题和加速开发,实现了快速推理能力。同时,文章还探讨了PyTorch在中间层延迟和深度神经网络中存在的问题,并提出了合并计算的解决方案。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • React基础篇一 - JSX语法扩展与使用
    本文介绍了React基础篇一中的JSX语法扩展与使用。JSX是一种JavaScript的语法扩展,用于描述React中的用户界面。文章详细介绍了在JSX中使用表达式的方法,并给出了一个示例代码。最后,提到了JSX在编译后会被转化为普通的JavaScript对象。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • 本文介绍了2015年九月八日的js学习总结及相关知识点,包括参考书《javaScript Dom编程的艺术》、js简史、Dom、DHTML、解释型程序设计和编译型程序设计等内容。同时还提到了最佳实践是将标签放到HTML文档的最后,并且对语句和注释的使用进行了说明。 ... [详细]
  • 第8章 使用外部和内部链接
    8.1使用web地址LearnAboutafricanelephants. ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
author-avatar
包子F3R
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有