布局和包含块
包含块的作用(意义):包含块会影响元素的定位和布局、大小。
left
、margin
、padding
(包括margin-top
和 padding-top
)的值是百分比时,它们的参考值就是包含块的 width
。
- 初始包含块
- The initial containing block has the dimensions of the viewport and is also the block that contains the
<html>
element. <html>
根元素所在包含块称为初始化包含块,它的大小和视口的大小一样。
- The initial containing block has the dimensions of the viewport and is also the block that contains the
格式化上下文(formatting context)
关键词:块级格式上下文
BFC是一个独立的渲染区域,内部的元素布局不受外部影响,并且BFC内部的元素也不会影响到外部。
什么情况下会创建BFC:设置元素的
float
属性、绝对定位和固定定位、overflow
属性不是 visible、display
属性等contain: layout
等是无副作用的,可在不影响已有布局的情况下触发 BFC
BFC的作用:避免margin穿透,清除浮动
包含内部 float 元素,隔离外部 float 元素
避免外边距折叠
定位
position: sticky fixed 参考点? position-mdn
z-index、left、top 对静态定位的元素无效。z-index 只作用于非静态定位元素和
flex items
。静态定位元素的 z-index 由该元素所在的stacking context
决定。相对定位的元素以【正常布局的位置】为参考进行偏移,被偏移后,该元素偏移前所占的空间仍然还在,不会变化,也不会影响其他元素。
绝对定位脱离文档流,不在占由原有的空间,以
containing element
为参考(怎么确定 containing element 包含块)。left、top 指定该元素与包含块之间的距离。不会发生 margin 合并。fixed 固定定位:通常相对于【视口的可视区域】定位元素
- fixed元素被另一个fixed元素包含的时候在chrome下fixed子元素的定位会受到父元素的影响。
sticky
Sticky elements are "sticky" relative to the nearest ancestor with a "scrolling mechanism", which is determined by its ancestors' position property。scrolling mechanism 就是 overflow is
hidden
,scroll
,auto
, oroverlay
The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of
top
,right
,bottom
, andleft
. The offset does not affect the position of any other elements。粘性定位元素必须至少设置一个 top、left、right、bottom,没有超出设置的偏移之前元素视为相对定位,否则视为固定定位(直到该元素到达其父元素的边界)。
z-index | stacking context(堆叠上下文)
div1、div2、div3 属于同一个 stacking context,div3 创建了一个新的包含了div4、div5、div6 的上下文,当两个不属于同一个上下文的元素比较 z-index 时,会一直向上直到使这两个元素属于同一个上下文。例如当 div4 与 div1比较 z-index时,div3被看作一个整体(z-index: 4)与 div1 比较。
技巧
- 把 z-inde 看作版本号(目录号),从主版本依次进行比较。
- 一个dom 元素如果没有形成新的 stacking context,那么在进行层叠顺序的比较时该元素等价于它所在的 stacking context 的层叠顺序。
- 普通文本流中的元素,dom位置在后面的层叠顺序更高
什么情况会创建新的 stacking context? 如果元素没有创建新的 stacking context 设置 z-index 无效。
参考
scale
- 负margin 抵消多余的空白
复合图层
将某个元素变成一个复合图层后会启用硬件加速,复合图层由 GPU 单独绘制
如何创建合成层
- 3D转换:translate3d,translateZ依此类推;
- video,canvas,iframe元件
- transform 和 opacity经由Element.animate();
- transform 和 opacity经由СSS过渡和动画;
- will-change;
- 拥有加速 CSS 过滤器的元素filter;
- 元素有一个z-index较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
使用硬件加速时,尽可能的使用index,防止浏览器默认给后续的元素创建复合层渲染
- 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
- 更多参考 性能优化-复合层
css 目录计数
.zl_parse_t.h1::before {
counter-increment: h1;
content: counter(h1) ". ";
}
CSS 获取屏幕宽度和高度
使用 @property
@property --_w {
syntax: '<length>';
inherits: true;
initial-value: 100vw;
}
@property --_h {
syntax: '<length>';
inherits: true;
initial-value: 100vh;
}
:root {
--w: tan(atan2(var(--_w),1px)); /* screen width */
--h: tan(atan2(var(--_h),1px)); /* screen height*/
/* The result is an integer without unit */
}
body:before {
content: counter(w) "x" counter(h);
counter-reset: h var(--h) w var(--w);
font-size: 50px;
font-family: system-ui,sans-serif;
font-weight: 900;
position: fixed;
inset: 0;
width: fit-content;
height: fit-content;
margin: auto;
}
文本截断
- 多标签溢出整块省略
// 单行溢出省略
.single-overflow {
width: 200px;
outline: 1px solid red;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 多行溢出省略
.multi-overflow {
width: 200px;
outline: 1px solid red;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.item {
display: inline-block;
background: #673AB7;
border-radius: 5px;
color: #fff;
padding: 2px 6px;
margin-right: 6px;
margin-bottom: 4px;
}
js判断文本溢出-js判断div文本是否溢出 - 云+社区 - 腾讯云
命名空间
解决 css 类名冲突
- 创建命名空间
// 生成带命名空间的 className 字符串
// 支持对象类型和不限数量的 modifier,例如:
// const cls = createCls('namespace')
// cls('className')
// cls('className', 'modifier1', 'modifier2')
// cls('className', {'modifier1': true, 'modifier2': false}, 'modifier3')
export const createCls = (namespace) => (
className: string,
...modifiers: Array<string | number | object>
) => {
let primitiveResult = `${namespace}-${className}`;
const modifierResult = modifiers.map(makeObjectClassName(primitiveResult)).join(' ');
return primitiveResult + ' ' + modifierResult;
};
const makeObjectClassName = (primitiveResult: String) => (modifier) => {
let result = "";
if (typeof modifier === "string") {
result = `${primitiveResult}--${modifier}`;
} else {
let keys = Object.keys(modifier).filter((k) => modifier[k]);
keys.forEach((m) => (result += `${primitiveResult}--${m}`));
}
return result;
};
- 使用
// 可以用组件名或页面的名字作命名空间
// createCls 可以直接挂到 vue 原型链上
const cls = createCls('checkbox');
// checkbox 组件模板
<template>
<div class="cls('wrap')">
<input class="cls('input', {focus: true})"/>
</div>
</template>
<style>
/* 这个组件的所有样式都写在这个类名下面 */
.checkbox{
&-wrap{
color: red;
}
&-input{
color: red;
}
&-input--focus{
color: blue;
}
}
</style>
宽高等比例缩放
高度与宽度相关联,当 padding-top 的值是百分比时,是根据父元素的宽度来计算的(margin-top 也是)。
<div class='container'><div class='placeholder'>占位, 撑开高度</div></div>
.container {
width: 50%
.placeholder {
width: 100%;
height: 0;
padding-top: 100%;
}
}
<link>
和 <script>
js 的区别
<link href="/assets/js/app.js" rel="preload" as="script" />
<script src="/assets/js/app.js"></script>
link 预加载资源,但是不会执行js,script 会执行js
viewport | 视口
我们通常所说的显示器分辨率,其实是指桌面设定的分辨率,而不是显示器的物理分辨率。只不过现在液晶显示器成为主流,由于液晶的显示原理与CRT
不同,只有在桌面分辨率与物理分辨率一致的情况下,显示效果最佳,所以现在我们的桌面分辨率几乎总是与显示器的物理分辨率一致了。
设备像素(物理像素)从生产后就固定不变,window.screen.width
和window.screen.height
来获取设备屏幕的物理像素宽度和高度
设备独立像素,也称为逻辑像素,简称dip
。在一般情况下,CSS 像素等同于逻辑像素,页面缩放时 CSS 像素可能等于多个【物理像素】
CSS 像素:
- 页面缩放为1时 CSS 像素等于设备独立像素
- 页面缩放比例为1时,1设备度量像素等于1 CSS 像素,缩放比例变化是设备度量像素与 CSS 像素的比率不一样,但是缩放不会影响设备度量像素
CSS像素
是很容易被改变的,当用户对浏览器进行了放大,CSS像素
会被放大,这时一个CSS像素
会跨越更多的物理像素。
- 物理像素分辨率 / CSS 像素分辨率,它告诉浏览器应使用多少【物理像素】来绘制单个 CSS 像素。
- 比值越大,CSS 像素分辨率越低(总的像素数量越少),单个CSS像素需要越多的物理像素显示。所以对网页进行放大时 DOM 元素会变大,可视范围内能显示的内容变少。
页面的缩放系数=CSS像素/设备独立像素
。
打开 chrome
的开发者工具,我们可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,比如 iPhone X
显示的尺寸是 375x812
,实际 iPhone X
的分辨率会比这高很多,这里显示的就是【设备独立像素】。
视口
视觉视口(可见视口):浏览器窗口,肉眼可见的矩形区域,它的尺寸大小会随着用户的手动缩放页面而变化
布局视口:浏览器渲染页面的区域(文档的区域),documentElement.clientWidth/clientHeight
来获取
当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。
页面缩放比例:布局视口宽度 / 可见视口宽度
<meta name="viewport" content="width=device-width, user-scalable=yes,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
viewport的meta标签的设置只对移动端生效,不影响PC端视口。PC端视口大小一般固定为浏览器窗口的大小。
viewport 中设置的缩放比例是以【理想视口】为参考
2K、4K
我们经常见到用K
和P
这个单位来形容屏幕:
P
代表的就是屏幕纵向的像素个数,1080P
即纵向有1080
个像素,分辨率为1920X1080
的屏幕就属于1080P
屏幕。
我们平时所说的高清屏其实就是屏幕的物理分辨率达到或超过1920X1080
的屏幕。
K
代表屏幕横向有几个1024
个像素,一般来讲横向像素超过2048
就属于2K
屏,横向像素超过4096
就属于4K
屏。
移动端适配
RetinaDisplay
(视网膜屏幕)
设计像素?
CSS 像素与设备独立像素?
rem
(function(doc, win) {
var docEl = doc.documentElement, // 获取html标签
// 页面大小改变事件
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
// 动态设置html标签字体大小,便于使用rem缩放
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);