像素
逻辑像素
CSS语句width:1px这里的px是指逻辑像素。
浏览器的window.devicePixelRatio值是1,则1个逻辑像素等于1个物理像素。
window.devicePixelRatio值是2,则1个逻辑像素等于2个物理像素。
那么,物理像素是什么,devicePixelRatio(DPR)有是什么?物理像素
物理像素是指屏幕包含的像素数目。
可通过浏览器的window.screen.width跟window.screen.height来获取。devicePixelRatio(DPR)
DPR是指设备上物理像素和设备独立像素(device-independent pixels)的比例。
也就是devicePixelRatio = 屏幕物理像素/设备独立像素。
设备独立像素是什么,可等同于逻辑像素。
想对上述三个概念理解透彻点,则看知乎这个回答。
Viewport视图
viewport,等同于浏览器窗口。
功能:约束你网站中最顶级包元素html标签渲染。
Viewport相关数据
下表的数据是在html页面设置<meta name="viewport" content="width=device-width,initial-scale=1" />情况下。
| 属性 | 含义(单位都是px,设备独立像素) |
|---|---|
| document.documentElement.clientWidth | Viewport宽度(不包含滚动条尺寸的浏览器宽度) |
| window.innerWidth | 包含滚动条尺寸的浏览器宽度 |
| document.documentElement.offsetWidth | html标签宽度 |
| screen.width | 屏幕宽度 |
| document.documentElement.scrollTop | 元素内容向上滚动了多少像素,如果没有滚动则为0 |
| document.documentElement.scrollHeight | 元素内容的高度,包括溢出部分 |
利用meta标签对viewport进行控制
| 内容 | 含义 |
|---|---|
| width | 设置layout viewport 的宽度,为一个正整数,或字符串"device-width" |
| initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
| minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
| maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
| height | 设置layout viewport 的高度,这个属性对我们并不重要,很少使用 |
| user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许 |
例如<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
| 内容 | 含义 |
|---|---|
| width | 设置layout viewport 的宽度,为一个正整数,或字符串"device-width" |
| initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
| minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
| maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
| height | 设置layout viewport 的高度,这个属性对我们并不重要,很少使用 |
| user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许 |
文章参考
http://www.quirksmode.org/mobile/viewports.html
https://www.quirksmode.org/mobile/viewports2.html
Containing Block
- display、position、float三者关系
BFC(Block Fomatting Context)
IFC(Inline Fomatting Context)
IFC的机制比较复杂,得从font-size,font-family,line-box,line-height,vertical-align这几个概念入手。
1. 认识字体font-family
字体渲染的实际高度,
由字体本身的设置(升部ascender,降部descender,大写字母高度Capital Height,小写字母高度X-Height等等)
和
用户定义的font-size
来决定。
所以同样的font-size,不同的font-family会产生不同高度的元素。

比如Catamaran字体,
em-square是1000个单位。
升部是1100,降部是540。
在Mac OS上的HHead Ascent/ Descent值,Windows上的Win Ascent/Descent值(这些值可能是不同的!)。
Capital Height(大写字母高度)是680,X height(小写字母高度)是485。

这说明font-faimly:100px的Catamaran字体,content-area(字体渲染后的实际占用像素)为164px。
大写字母是68px(680单位),小写字母(X字高)高49像素(485单位)。

2. 理解line-box
line-box的高度由
子节点的最高点
到
子节点的最低点
来决定。
具体来说line-box的高度由子节点的font-size,font-family,line-height,vertic-align决定。
3. 什么是line-height
line-height是指字体的行间距值,简称行高。
line-height所决定的区域如图所示。

注意:它不是基线之间的距离。
当
line-height:normal;时,行间距大小其实就是content-area大小。如下
当
line-height:1;时,行间距大小由font-size来决定。如下
这时行间距大小很可能跟
content-area不同。这样就导致行之间的文字可能会重叠。
下面两个场景展示了不同的line-height对line-box高度的影响。
-
当子节点
line-height:normal;vertic-align:base-line;font-size:100px;一致,而font-family不同时
image
我们看到,第二个line-box比其他的高,因为第三个ba使用了Catamaran字体。其content-area为164px,比其他字体高。 -
当
line-height:200px;vertic-align:base-line;font-family:Catamaran;一致,而font-size不同时
image
我们看到这时line-box被撑高起来了。
因为第二个Ba为了与第一个Ba进行基线对齐,第二个Ba下沉了。 当父元素的
font-family和子元素的font-family不同时
比如下面代码
<style>
p {
line-height: 200px;
}
span {
font-family: Catamaran;
font-size: 100px;
}
</style>
<p>
<span>Ba</span>
</p>
的渲染效果

为什么会这样?
这是因为浏览器进行计算时,会以每行line-box的一个零宽度字符开始,这一规范称为strut。
零宽度字符的行间距大小,是以父元素为准。
所以这个p
4. 什么是vertical-align
vertic-align有四个值,其中
vertical-align:top/bottom对齐到父节点的line-box的顶部或底部
vertical-align:text-top /text-bottom对齐到自身的content-area的顶部或底部
如图

注意垂直对齐是以行间距区域开始。如图

5. 总结
- 文本之间的垂直对齐,靠
vertical-align不靠谱。 - 垂直对齐,还是得靠
font-size,font-family,line-height,vertic-align各种一致。
且自己手工微调吧。
参考链接:
入理解CSS:font metrics, line-height 以及 vertical-align
Deep dive CSS: font metrics, line-height and vertical-align
TFC(Table Fomatting Context)
FFC(Flex Formatting Context)
部分定宽,部分自适应。
GFC(Grid Formatting Context)
等高变宽方案
rem方案
这个方案解决了不同大小的屏幕,展示相同宽高比的元素的需求。
相当于变相地实现了vw功能。
(function (doc, win) {
// 分辨率Resolution适配
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 320) + 'px';
};
// Abort if browser does not support addEventListener
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
// 一物理像素在不同屏幕的显示效果不一样。要根据devicePixelRatio来修改meta标签的scale,要注释上面的meta标签
(function(){
return;
var dpr = scale =1;
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
//
var metaEl = "";
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
})();
})(document, window);
vw方案
依赖于视口大小而自动缩放,但失去了最大最小宽度的限制
https://zhuanlan.zhihu.com/p/30434537
https://www.w3cplus.com/css/vw-for-layout.html

