CSS的理解

112 阅读22分钟

CSS的理解

基础知识

Casading规则、选择器、继承、值和单位、盒模型

层叠(Casading)、优先级

image.png

HTML代码

<head>
<style>
#title{
color:red;
}
</style>
<link rel="stylesheet"href="./index.css"type="text/css">
</head>
<body>
<h1 id="title"style="color:green;">I am a Tittle</h1>
</body>

index.css 代码

h1{
  color:blue;
  font-size:48px;
}

层叠三大规则

优先级别

image.png

样式表重要来源排序

image.png

选择器的类别

基础选择器

#id一一ID选择器。Tagname一一类型选择器或者标签选择器。 .class一一类选择器。*一一通用选择器。该选择器匹配所有元素

组合器
  • 子组合器(>)一一匹配的目标元素是其他元素的直接后代。如:.parent>.child
  • 相邻兄弟组合器(+)一一匹配的目标元素紧跟在其他元素后面。如:p+h2
  • 通用兄弟组合器(~)一一匹配所有跟随在指定元素之后的兄弟元素,如:i.active~li
  • 复合选择器多个基础选择器可以连起来使用,如:h1.page-header。
属性选择器
  • 通过约束属性值,div[data-title="aaa"]
伪类选择器
  • 选中处于某个特定状态或相对于其父级或兄弟元素的位置的元素。如:first-child,hover
伪元素选择器
  • 匹配在文档中没有直接对应HTML元素的特定部分,或插入内容。如h2::first-letter,div::before
逻辑选择器
  • 较新的选择器::is()``has()``where()``not()

选择器的优先级

image.png
image.png

注意:

  • 内联样式不属于选择器,为了方便比较记忆,放在这里做对比
  • :is()``:not()``:has()本身不计入优先级,以参数中最高的优先级为准,:where()优先级为0源码顺序

源码顺序

  1. 对于@import的样式,根据@import的顺序。
  2. 对于Iink和style标签的样式,根据在document中的顺序决定。
∥html
<head>
  <style>
    .red(
    color:red;
    }
  </style>
  <link rel="stylesheet"href="./index.css"
    type="text/css">
</head>
<body>
  <h1 class="green blue red">A Tittle</h1>
</body>
.index.css
.blue{
  color:blue;
  font-size:48px;
}
.green {   //生效
  color:green;
}

注意:

  1. 选择器尽量少用id
  2. 尽量不要用!important
  3. 自己的样式加载在引用库样式的后面

继承

image.png

  • 大部分具有继承特性的属性跟文本相关:colorfontfont-familyfont-sizefont-weight.font-variantfont-styleline-heightletter-spacingtext-aligntext-indenttext-transformwhite-space以及word-spacing
  • 还有少部分列表、表格的属性。
  • 可以使用inherit关键字显式指定一个属性值从其父元素继承。

HTML代码

<h1>I am a Tiltle</h1>
<div class="card">
  <h1>I am a inside Tiltle</h1>
</div>

CSS代码

h1 {
	font-size:28px;
}
card {
	font-size:24px;
}
card h1 {
	font-size:inherit;
}

CSS的值和单位

image.png

布局和定位

盒模型

浏览器根据视觉格式化模型(visual formatting model),将所有元素表示为盒子模型,css通过盒模型做layout

image.png

  • 控制盒子类型

display:block、inline、inline-block、flex、..

  • 控制盒子大小&计算方式

width,height... box-sizing:content-box,border-box

  • 控制盒中内容流

overflow:auto、scroll、hidden、.

  • 控制定位

position:static、relative、absolute、fixed、sticky

  • 是否可见

visibility:visible、hidden、..

视觉格式化模型:develop.mozilla.org/zh-CN/docs/…

实现三角形

示例图

image.png

代码
//html
<div class="triangle-bottom"></div>
//css
.triangle-botton {
	width:0;
	height:0;
	border-left:50px solid transparent;
	border-right:5epx solid transparent;
	border-bottom:50px solid red;
 }

实现固定比例矩形

示例图

image.png

代码
//html
<div class="ratio-box"></div>
//css
.ratio-box {
	background-color:cadetblue;
	//w1dth是父元素宽度108路
	width:100%;
	height:0;
	padding:0;
	//Padd1ng-bottom是父元素宽度75%
	padding-bottom:75%;
 }

或使用新特性:aspect-ratio

实现水平居中

示例图

image.png

代码
//html
<div class=wrap">
<div class="h-center">c/div>
</div>
//css
.wrap {
	width:1008;
	height:80px;
	border:1px dashed grey;
}
.h-center {
	width:100px:
	height:sepx;
	background-color:navajowhite;
	//左石两的arEn使用uto
	//将水平万向W亲空闻均分aut©
	pargin:10px auto;
}

margin auto的更多表现:链接

实现渐变边框

示意图

image.png

代码
//htnl
<div class="awesone-border"></div>
//css
.awesone-border {
	width:156px;
	height:100px;
	border:8px solid transparent;
	border-radius:12px;
	background-clip:padding-bo×,border-bo×;
	background-origin:padding-box,border-box;
background-img:
	linear-gradient(to right,#fff,#fff),
	1inear-gradient(135deg,#e941ab,#a557ef);
 }

负外边距

padding、border、margin中,只有margini可以设置负值

设置左边或顶部的负外边距,元素就会相应地向左或向上移动,导致元素与它前面的元素重叠:

image.png

如果设置右边或者底部的负外边距,并不会移动元素,而是将它后面的元素拉过来:

image.png

margin负值最终减少的是外界可感知的宽高

常规流、弹性盒子、Grid、定位

概述

CSS3之前的常用布局

Normal Flow常规流
  • 默认的布局方式
  • 有块级格式化上下文和内联
  • 格式化上下文

Float浮动流
  • 用float/属性控制
  • 脱流,做横向布局

Positioning定位流
  • 用position.属性控制
  • fxed和absolute脱离文档流
  • 可以自由定位、覆盖等

CSS3之后的新增布局
  • Flex弹性盒子布局
  • 一维空间布局
  • Grid网格布局
  • 二维空间布局
  • Multicol多列布局
  • 文本、内容的多列展示

常规流布局

image.png

块级格式化上下文(block formatting context)

格式化上下文的布局规范为:

“在一个块格式区域中,盒子会从包含块的顶部开始,按序垂直排列。同级盒子间的垂直距离会由 "mrgn属性决定。相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠,在一个块格式区域中,每个盒子的左外边缘会与包含块左边缘重合(如果是从右到左的排版顺序,则盒子的右外边缘与包含块右边缘重合),”-9.41

那么,我们平时说的BFC是什么呢?

BFC本身是block formatting context的缩写,是一种格式规范。如果说一个盒子是BFC或者有BFC特性,那么BFC表示的是block formatting context root。不管它外部显示类型是什么,但是它的内部显示类型是flow-root,其实就是这个盒子内部形成了一个新的块级格式化上下文。

如何触发一个盒子的BFC特性?以下条件满足任何一个即可
  • display:flow-root I inline-block;
  • position:absolute | fixed;
  • float:不为none;
  • overflow:不为visible

外边距塌陷

会产生外边距塌陷的情况:

image.png

  • 两个兄弟元素之间相邻的上下外边距。
  • 父子元素之间相邻的上下外边距。
  • 内容为空元素自己上下外边距相邻。

消除外边距塌陷的方法:

image.png

  • 在两个相邻的上下边距之间增加border、padding?或者内联元素,使之不相邻。
  • 在父子元素重叠时,除了上述方法,还可以设置父元素为BFC,使得父子不在同级BFC中。

了解更多BFC特性:链接

内联级格式化上下文

在内联格式区域中,盒子会从包含块的顶圈开始,按序水平排列。只有水平外边距、边框和内边距 会被保留。这些盒子可以以不同的方式在垂直方向上对齐:可以底部对齐或顶部对其,或者按文字 底部进行对齐,我们把包含一串盒子的矩形区域称为一个线条柜。(The[ectangular area that contains the boxes that form a line is called a line box.)"-9.4.2

image.png

一些实际case:
  • 单行文字垂直居中

我是标题

利用了ine-height的垂直居中特性

//html
<div class="title">我是标题</div>
//css
.title {
	background:antiquewhite;
	font-size:18px;
	line-height:36px;
	height:36px;//可以省略
 }
  • 文字和icon垂直对齐

image.png

//htmI
<div class="wrap">
<ing class="image"src="dy.png">
<span class="te×t">抖音同款能力</span>
</div>
//css
.image {
	width:24p×;
	height:24px;
	vertical-align:middle;
}
.text {
	font-size:16px;
	line-height:32px;
	margin-left:4px;
	vertical-align:middle;
 }
  • 利用了line box中计算高度的原理和vertica-align的设置,垂直对齐,但不是完全垂直居中
  • 如果设置父元素font-size:0,基线和中线重叠,则居中对齐

弹性盒子布局

Flexible Box Layout是为了提供更加高效灵活的布局方式,在即便是宽高未知的情况下,也能排列和分割一个盒子内部的布局。而且在不同布局方向(横向纵向)的调整更为灵活。

image.png

弹性盒子的相关属性分为两类

作用于父元素(flex container):
  • 建立一个弹性盒子

display:flex I inline-flex;

  • 规定盒子的主轴方向

flex-direction:row I column I...;

  • 子元素折行显示形式

flex-wrap:nowrap I wrap I wrap-reverse;

  • 主轴方向子元素的排列方式

justify-content:center I space-between I ...

  • 交叉轴方向子元素的对齐方式

align-items:flex-start I center I stretch I...;

  • 交叉轴方向多行子元素的布局方式

align-content:flex-start I space-between I...;

  • 以明确值设定子元素间的间隔

gap:;

作用于子元素(flex items):
  • 规定tem未放缩之前的默认大小

flex-basis:auto I长度值.

  • 规定有剩余空间时,对item的分配比例

flex-grow:number;

  • 规定空间不够时,对item的压缩的比例

flex-shrink:number;

  • 以上三项的缩写

flex:grow shrink basis;默认01auto

  • 规定tem从左到右(row布局)显示的顺序

order:number::默认是0

  • 规定单个item在交叉轴上的位置

align-self:auto I center I flex-start 1...

使用弹性盒子布局的示例

展示灵活的文件长度省略展示:例子出处

this-file-has-a-really-really-really-long-fi...pdf

//html
<div class-"filenane">
	<span class="filename__base">
		this-file-has-a-really-really-really-long-filename.
	</span>
	<span class="filename__extension">
		pdf
	</span>
</div>
//css
.filename {
	display:flex;
}
.filename_base {
	text-overflow:ellipsis;
	white-space:nowrap;
	over flow:hidden;
}
.filename__extension {
	flex-shrink:0;
 }

展示筛子上的六个面

示例图(一)

image.png

代码(一)
//html
<div class="dot-one">
<div class="dot"></div>
</div>

.dot-one {
	display:flex;
	justify-content:center;
	align-items:center;
}

示例图(二)

image.png

代码(二)
//html
<div class="dot-three">
<span class"dot"></span>
<span class"dot dot-center"></span>
<span class"dot dot-end"></span
</div>
//css
.dot-three {
	display:flex;
	justify-content space-between;
}
.dot-center {
	align-self:center;
}
.dot-end {
	align-self:flex-end;
 }

示例图(三)

image.png

代码(三)
//html
<div class="dot-five face">
	<div class="row'>
		<div class=dot"></div>
		<div class="dot"></div>
	</div>
	<diy class="row row-center">
		<div class="dot"></div>
	</div>
	<div class="row'>
		<div class="dot"></div>
		<div class="dot"></div>
	</div>
</div>
//css
.dot-five {
	display:flex;
	flex-direction:column;
	justify-content:space-between;
}
.row {
	display:flex;
	justify-content:space-between;
.row-center {
	justify-content:center;
}

网格布局

2017年推出的Gd布局可以定义由行和列组成的二维布局,然后将元素放置到网格中。元素可以只占其中一个单元格,也可以占据多行或多列。

image.png

源代码
.grid-container {
	display:grid;
	grid-template-columns:100px 1fr;
	grid-template-rows:60px 6fr 1fr;
}

作用于父元素

display:grid I inline-grid;

  • 用来生成显式的列、行

grid-template-colums/rows:数值/百分比fr/repeat0等;

  • 规定区域(area)的分布

grid-tempate-areas:"header header" "sidebar content" "footerfooter";

  • 规定默认的排序方向

grid-auto-flow:row(dense)I column (dense);

  • 其他属性

作用于子元素
  • 规定占用的列、行

grid-colum/row:/;

  • 是grid-colum/row-start和

grid-colum/row-end的缩写形式

  • 规定占用的area

grid-area:header;

使用Grid布局的示例

将面设置为均分的3*3grid布局

示意图

image.png

示例代码
.face {
	display:grid;
	grid-terplate-rows:repeat(3,1fr);
	grid-terplate-colunns:repeat(3,ifr);
	grid-terplate-areas;
	"lt.rt"
	"lc cc rc"
	"lb.rb";
}

规定好所需要的点占用的area

示例代码
.lt-dot {
	grid-area:lt;
}
.rt-dot {
	grid-area:rt;
}
.lc-dot {
	grid-area:Lc;
}
.cc-dot {
	grid-area:cc;
}
.rc-dot {
	grid-area:rc;
}
.lb-dot {
	grid-area:lb;
}
rb-dot {
	grid-area:rb;
}

示意图

image.png

示例代码
<div class="face">
  <span class="dot cc-dot red"></span>
</div>

示意图

image.png

示例代码
<div class="face">
	<span class="dot lt-dot"></span>
	<span class="dot cc-dot"></span>
	<span class="dot rb-dot"></span>
</div>

示意图

image.png

示例代码
<div class="face">
	<span class="dot lt-dot"></span>
	<span class="dot lb-dot"></span>
	<span class="dot cc-dot"></span>
	<span class="dot rt-dot"></span>
	<span class="dot rb-dot"></span>
</div>

Grid和Flex布局的使用策略

Flex

  1. 一维布局
  2. 基于内容
  3. 浏览器兼容性更好

Grid

  1. 二维布局
  2. 基于布局
  3. 2017年后浏览器的版本普遍支持

Grid for layout,Flexbox for components

  1. 大面积或整体布局推荐使用Grid布局
  2. 小面积或组件中,或Grid Item中可以使用Flex做灵活布局

定位 Position

为了我们可以在文档流的基础上,让元素移动,做出更多灵活的改变。当oosition属性的取值非static的时候,可以使用top,right,bottom,left对其进行定位。

relative

元素相对于自己原来在文档流中的位置进行定位,但是原来文档流的空间还在。

示意图

image.png

示例代码
.relatived {
  position:relative;
  top:30px;
  left:10px;
}

absolute

元素被移出正常文档流,且没有预留空间,相对于最近的非static定位祖先元素的进行定位。

示意图

image.png

示例代码
.wrap {
	position:relative;
}
.abosoluted {
	position:absolute;
	top:30px;
	left:10px;
}

fixed

元素被移出正常文档流,且没有预留空间,相对于屏幕视口进行定位,屏幕滚动也不会改变位置。

示意图

image.png

示例代码
fixed-pos {
	position:fixed;
	t0p:10%;
	left:10%;
}

sticky

元素相对它的最近滚动祖先(祖先的overflow是scrol/hidden/auto)的视口(scrollport)定位。

示意图

image.png

示例代码
.sticky {
	position:sticky;
	top:20px;
}

使用定位的示例

示意图

image.png

示例代码
<div class="modal">
	<div class="modal-mask"></div>
	<div class="modal-container">
		<div class="header">Modal Header</div>
		<div class="body">
			<p>
				contentcontent content
			</p>
		</div>
		<div class="footer">
			<button class:="confirm'">确定</button>
		</div>
		<button class="close">关闭</div>
	</div>
</div>

fixed定位
.modal-mask {
	position:fixed;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background-color;
	rgba(0,0,0,0.5);
}

fixed定位
.modal-container {
	position:fixed;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	min-width:600px;
	min-height:400px;
	background-color:white;
	display:flex;
	flex-direction:column;
}

absolute定位
.close {
	position:absolute;
	top:16px;
	right:20px;
}

层叠上下文(The Stacking Context)

层叠上下文是对HTML元素的三维构想,将元素沿着垂直屏幕的虚构的Z轴排开.

页面展示

image.png

示例代码

<body>
	<div class="wrap">	
		<div class="area1"></div>
		<div class="area2">
			<div class="area2-1"></div>
		</div>
	</div>
</body>

层叠上下文结构

image.png

浏览器渲染部分过程示意图 链接

image.png

一个新的层叠上下文渲染时会对应一个浏览器渲染时的render layer(渲染层)。

  • 示意图

image.png

*注意:不是浏览器devtooll图层工具中看到的图层

形成新的层叠上下文的条件(任一即可):

  • position:relative或absolute;并且z-index不是auto
  • position:fixed或sticky
  • oflex或grid的子元素;并且z-index不是auto 为CSS3之前
  • opacity的值小于1
  • transform的值不为none
  • will-change的值不为通用值
  • ..详见规范*

stacking order

  • 层叠顺序不仅指不同的层叠上下文的顺序,同一个层叠上下文内,元素间也有顺序:

image.png

  • z-index只在同一个层叠上下文内比较
  • 子元素的z-index无法超越父元素的z-index显示顺序

例1: image.png 实践网址:codepen.io/yao-mo/pen/…

例2: image.png

编写z-index的建议

  1. 使用css变量或者预处理语言的变量,管理z-index的值
  2. 将预设间隔设置10或100,方便后续的插入

image.png

变形、过渡、动画

transform变形

2D相关属性

  • transform:translate(移动)、rotate(旋转)、scale(放缩)、matrix(变形矩阵)等
  • transform-origin:right top、center等,表示变形时依据的原点

示意图 image.png

3D相关属性

  • transform:translate3d rotate3d、scale3d、matrix3d等
  • transform-origin:right top、50px30px等,表示变形时依据的原点
  • transform-style:flat或preserve-3d看子元素的3d表现
  • perspective:观看点距离z=0这个平面的距离,可以在transform中用perspective(0使用作用为当前元素,也可以直接使用,给后代元素一个统一值
  • perspective-origin:观看者的位置,如top、bottom等
  • backface-visibility:元素正面只有朝向观察者的时候可见

示意图 image.png

transform变形3D

image.png

实践网址:codepen.io/yao-mo/pen/…

transition过渡

通过指定某些元素属性从一种起始状态,在一段时间内以某种变化节奏,过渡到终止状态。

示例代码

div {
	transition:<property><duration><timing-function><delay>;
}

其中timing-function一般有三种用法:线性((linear)、贝塞尔曲线(cubic-bezier(0或ease-in等)、阶跃(step) image.png

animation动画

@keyframes关键帧用来定义动画过程中出现的关键样式

image.png

animation-*相关属性用来为元素添加动画

  • animation-name:定义好的关键帧的名字 链接
  • animation-duration:动画时长 链接
  • animation-timing-function:动画节奏 链接
  • animation-delay:延时开始的时间 链接
  • animation-iteration-count:执行次数 链接
  • animation-direction:是否反向或交替 链接
  • animation-fill-mode:动画执行前后的样式采用 链接
  • animation-play-state:动画运行状态 链接

transform、transition、animation一性能相关

image.png
image.png

如何写动画性能更好

  1. 尽量不用触发reflow的属性
  2. 在遇到性能问题时可以触发硬件加速,比如设置will-change属性、设置transform3d等
  3. 尽量使用transform和opacity去写动画

链接:硬件加速详解 动画性能相关深入了解

响应式设计

响应式设计原则

  • 优先选用流式布局,如百分比、flex、grid等
  • 使用响应式图片,匹配尺寸,节省带宽
  • 使用媒体查询为不同的设备类型做适配
  • 给移动端设备设置简单、统一的视口
  • 使用相对长度,em、rem、vw做为长度度量

媒体查询

媒体查询允许某些样式只在页面满足特定条件时才生效。我们可以将媒体类型(如screen、prit)以及媒体特性(如视口宽度、屏幕比例、设备方向:横向或纵向)做为约束条件。

//css中使用格式:@media媒体类型(省略表示a1)  逻辑操作符  媒体特性1  逻辑操作符  媒体特性2  ···
@media screen and (min-width: 320px)and (orientation: Landscape) {
	···
}
//link标签中使用示例
<link rel="stylesheet"media="screen and (max-width:600px)"href="smallscreen.css">

使用媒体查询的一些Tips

  1. 媒体查询同样遵循cascading层叠覆盖原则,min-和max-选择一个
  2. 由于设备的多样化逐渐不可枚举,断点的选择尽量根据内容选择
  3. 由于断点的增加会增加样式处理的复杂度,所以尽量减少断点

示意图: image.png

设备像素、参考像素和移动设备视口

设备像素

image.png

  • 设备像素(物理像素):显示器上绘制的最小单位,显示屏通过控制每个像素点的颜色,使屏幕显示出不

同的图像。

  • 设备像素和设备相关,屏幕从工厂出来那天起它上面的物理像素点就固定不变了。

image.png image.png

DPI &PPI

  • dpi(dots per inch):每英寸多少点。
  • ppi(pixels per inch).:每英寸多少像素数。
  • 当用于描述显示器设备时ppi与dpi是同一个概念,说的是每英寸多少物理像素及显示器设备的点距

当屏幕分辨率是X*Y,计算公式: image.png

CSS像素

image.png

  • CSS像素(reference pixel)其实是一个视角单位。规范给出的定义是,1css像素是从一臂之遥看解析度为96DPI(即1英寸96点)的设备输出时,1点(即1/96英寸)的视角。
  • 通常认为常人臂长为28英寸,那么视线与水平线的夹角是:(1/96)in/(28in2P1/360deg)=0.0213度
  • 如果1CSS像素永远等于1设备像素,那么

image.png

  • 但是真正使用的CSS像素并不是用0.0213度去精确计算的,因为css像素存在的目的是为了保证阅读体验一致,所以对不同的物理设备,CSS使得浏览器中1CSS像素的大小在不同物理设备上看上去大小总是差不多。
  • 真正实现时,为了方便基本都是根据设备像素换算的。浏览器根据硬件设备能够直接获取CSS像素。

DPR设备像素比

设备像素比(dpr): 描述的是未缩放状态下,设备像素和CSS像素的初始比例关系 image.png image.png

移动端的viewport

  • 布局视口(viewport)是页面中html元素(根元素)的包含块,默认情况下,window.document..documentElement..clientWidth就是viewport的宽度。
  • 在移动设备中,默认的布局视口由于历史兼容pc屏幕的原因,并不符合需求,我们经常需要用标签对viewport进行设定,来完成移动端设备的适配。
  • 比如:默认iphonel的布局视口是980px,展示如图:

image.png

viewport的meta标签中的属性
  • width
  • height
  • initial-scale
  • minimum-scale
  • maximum-scale
  • user-scalable
默认iPhone的viewport可以认为是:
<meta name="viewport"content="width=980">
  • 其中initial-scale,在未设定时,如果width设定了,那么它会自动设置放缩值:initial-scale=屏幕宽度(例子中是390)/980≈0.398 相比scale=1的时候,缩小了0.398倍

常见的移动端viewport的设置:
  1. 保持scale为1
<meta name="viewport"content="width=device-width,initial-scale=1">
  • 好处是:在所有设备上不管横屏还是竖屏,让布局视口的宽度和设备屏幕的宽度保持一致,且参考像素不放缩。
  • 不好的是:如果设备的dpr>1,那么想要画出一个设备像素粗细的线,需要其他方法实现。
  1. 保持scale放缩参数是1/dpr
const calcScale 1 window.devicePixelRation;
<!--在meta标签中使用calcScale的值,示意如下:-->
<meta name="viewport"content="initial-scale=calcScale,maximum-scale=calcScale,minimum-scale=calcScale,user-scalable=no">
  • 好处是:1个css px等于1个设备像素,全局层面解决“真实1像素"”问题。
  • 不好的是:不同设备想达到1个css px严格等于1个设备像素,需要处理兼容性才能达到。而且,全局等比放缩,对某些固定尺寸需要特殊处理。

相对长度

相对长度的使用

em

image.png

应用场景:可以让展示区域根据展示字号的不同,做出放缩调整。

示例代码
//html
<div class="font-small paragraph">
	文字较小时候的段落呈现
</div>
<div class="font-large paragraph">
	文字较大时候的段落呈现
</div>
//css
.font-small {
	font-size:12px;
}
.font-large {
	font-size:20px;
}
.paragraph {
	padding:1em;
	border-radius:0.5em;
	line-height:1.5em;
}

rem

rem:根元素的字体大小。通过伪类:root或者html选择器选定。由于是根元素的font-size,所以不会像em那样出现多重嵌套问题,减少了复杂性,同时作为一个相对单位,可以进行适配放缩,可以用来做响应式布局。

以之前Flexible.js的方案为例

设置
  • 根据dpr设置viewport,.将1 css px等于1个设备像素
  • 用js设置rem为视口宽度的1/10,rem跟随视口不同改变
function setRem () {
const rem document.documentElement.clientwidth / 10;
	//如果是375 dpr = 2 的屏幕,clientwidth=750,rem=75
document.documentElement.style.fontsize rem  + 'px';
}

应用
  • 对于750px的设计稿,给一个卡片宽度的是60px,代码的css依然可以写为:

image.png

  • 利用px2rem之类的转换工具,将px替换为rem;因为设计稿是750,我们设定转换的基准是75

表现
  • 375dpr=2的设备上:

rem 75px width:0.8 75 60px

  • 320dpr=2的设备上:

rem 64px width:0.8*64=51.2px 完成不同设备上的等比放缩展现

w和vh
  • Vw:视窗宽度的1%。vh:视窗高度的1%。同样,w也可以作为响应式布局的基准单位。由于vw天然是视口宽度的1%,所以不需要js动态配置。
  • 和rem方案类似,方案设定可以如下:

设置
  • 设置scale:=1,保持视口和屏幕宽度一致

应用

对于750px的设计稿,给一个卡片宽度的是60px,代码的CSS依然可以写为: image.png

  • 利用px2 viewport,之类的转换工具,将px替换为w;因为设计稿是750,我们设定转换的基准是1vw=750*1%=7.5pX

表现
  • 375dpr=2的设备上:

1vw=375*1%=3.75px width:8 3.75 30px

  • 320dpr=2的设备上:

rem=3201%=3.2px width:83.2=25.6px 完成不同设备上的等比放缩展现

方法参见:www.w3cplus.com/css/vw-for-…

绝对长度和视口

CSS生态相关

语言增强:预处理器、后处理器

语言增强一一CSS预处理器

image.png
image.png
image.png

示例代码
//变量:以Iess为例
@primary-font-size:24px;/*定义变量*/
@primary-blue:#245bdb;/*定义变量*/
@width:50px;
@height:@width + 10px;/*使用变量,和逻辑语句*/
.title {
	width:@width;/*使用变量*/
	height:@height;
	font-size:@primary-font-size;
	color:@primary-blue;
}
//嵌套、作用域:以Iess为例
//css
.container {
	width:100px;
	height:100px;
}
.container .container-title {
	font-size:24px;
}
.container .container-desc {
	font-size:12px;
}
//less
.container {
	width:100p×;
	height:100px;
	.&-title {
		@font-size:24px;
		font-size:@font-size;
	}
}
//imixins:以less为例
.special-border {
	border-top:dotted 1px black;
	border-bottom:solid 2px black;
}
.title-1 {
	color:#111;
	.bordered();
}
.title-2 {
	color:red;
	bordered();
}
//自定义函数:以Scss为例
//计算单列的单个宽度
@function column-width($col,stotal) {
	@return percentage(Scol/Stotal);
}
//一个列宽
.co1-1 {
	width:column-width (1,10);
}
//三个列宽
.col-3 {
	width:column-width(3,10);
}
//编译为
.col-1 {
	width:10%;
}
.col-3
width:30%;
8643

scss、less、stylus简单对比
scsslessstylus
css语法兼容兼容兼容常规兼容
可编程能力较强逻辑处理能力丰富较弱:不支持自定义函数较强
社区活跃、使用人数最多start3.3k;burbon,库支持较多star16.9k;twitter bootstrap框架相对少star11k

广义CSS预处理器

编译过程中的广义预处理器

image.png

后处理器

image.png

插件网址:postcss.org/docs/postcs…

postcss机制浅析

image.png

ast资源管理器网址:astexplorer.net/

工程架构:.CSS模块化、·CSS-ln-Js、:Atomic CSS

CSS模块化

CSS Module就是为了解决全局污染问题出现的方案,解决CSS全局污染,本质上是保证样式集合对应的选择器是唯一的,从这个角度看,主流的单纯针对于防止全局污染的方案大概有:

BEM命名规范

  • 通过.block__element-modifier这种命名规范来约束开发者,从而实现样式隔离
.header-btn_prev {
	width:50px;
	height:20px;
	color:black;
}
.header-btn_next {
	width:50px;
	height:20px;
	color:gray;
}

vue-loader的scoped方案 通过编译的方式,在html元素上添加data-xxx的唯一属性,然后css添加属性 选择器[data-xxx]的方式,实现样式隔离

//编译前
<style scoped>
.example {
	color:red;
}
</style>
<template>
	<div class="example">hi</div>
</template>


//编译后
<style>
.example [data-v-f3f3eg9] {
	color:red;
}
</style>
<template>
	<div class="example" data-v-f3f3eg9 >
		hi
	</div>
</template>

CSS Modules 通过编译的方式,将一个css file中的样式命名默认转换为一个全局唯一的名称,实现样式隔离,(常用css-loader或postcss-module)

//编译前
import styles from './index.module.css';

export default () => (
	<div className={styles.container}>
		Test Container
</div>
);
.container {
	width:100%;
	height:100%;
	background-color:white;
}

//编译后
<div class="index-module_container--sMp20">Test Container</div>

.index-module__container--sMp20 {
	width:100%;
	height:100%;
	background-color:white;
}

网址:qithub.com/css-modules…

CSS-in-JS

css-in-js:将应用的CSS样式写在JavaScript文件里面,利用js动态生成css

image.png

刺激的playground网址:www.cssinjsplayground.com/?activeModu…

styled-component机制浅析

  • Step1生成第一个classname做为componentld这个类名没有CSS样式,但是当需要引用其它组件的时候,可以作为一个嵌套选择器来使用。
  • Step2生成第二个classname做为唯一类名(hash值),使用stylis,生成和唯一类名关联的CSS字符串。
  • Step3唯一类名对应的css样式insert<head><style>中。
  • Step4将两个类名写到目标节点的class中。

CSS-in-JS pros cons

image.png

原子化CSS

原子化CSS是一种CSS的架构方式,它倾向于小巧且用途单一的class,并以视觉效果进行命名。

现有的库or框架: TailwindVindicssTachyons unocss..

传统方式
<style>
.chat-notification {
	display:flex;
	max-width:24rem;
	margin:0 auto;
	padding:1.5rem;
	border-radius:0.5rem;
	background-color:#fff;
	box-shadow:0 20px 25px -5px rgba(0,0,0,0.1),
						 0 10px 10pX -5px rgba(0,0,0,0.04)
}
chat-notification-logo-wrapper {
	flex-shrink:0;
}
.chat-notification-logo {
	height:3rem;
	width:3rem;
}
.chat-notification-content {
	margin-left:1.5rem;
	padding-top:0.25rem;
}
.chat-notification-title {
	color:#1a202c;
	font-size:1.25rem;
	line-height:1.25;
}
.chat-notification-message {
	co10r:#718096
	font-size:lrem;
	line-height:1.5;
}
</style>


<div class="chat-notification">
	<div class="chat-notification-logo-wrapper">
		<img class="chat-notification-logo" src="/img/logo.svg"alt="ChitChat Logo">
	</div>
	<div class="chat-notification-content">
		<h4 class="chat-notification-title">
			ChitChat
		</h4>
		<p class="chat-notification-message">
		You have a new message!</p>
	</div>
</div>

量子化CSS
<div class=p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4>
	<div class="shrink-0">
		<img class="h-12 w-12 src="/img/logo.svg" alt="ChitChat Logo">
	</div>
	<div>
		<div class="text-xl font-medium text-black">
			ChitChat
		</div>
		<p class="text-slate-500">
			You have a new message!
		</p>
	</div>
</div>

原子化CSS

Tailwind如何做的?
  1. 实用工具库优先(Utilities-First)
@tailwind base;
atailwind components;
atailwind utilities;

利用基础的规则库预先定义好生成规则

  1. 按需生成
<body>
	<h1 class="text-3xl font-bold underline text-blue flex-grow">
		Hello world!
	</h1>
</body>
.flex-grow {
`flex-grow:1;
}
.text-3xl {
	font-size:1.875rem;
	line-height:2.25rem;
}
.font-bold {
	font-weight:700;
}
.underline {
	text-decoration-line:underline;
}
  1. 支持配置样式规则&自定义插件
module.exports {
//······
theme: {
	colors: {
	'blue':'#1fb6ff',
	'purple':'#7e5bef',
	'pink':'#ff49db',
	orange'#ff7849',
	'green':'#13ce66',
	'yellow':'#ffc82c',
	"gray-dark':"#273444',
	'gray':'#8492a6
	'gray-light':'#d3dce6',
   		 },
	fontFamily:	{
	sans:['Graphik','sans-serif'],
	serif:['Merriweather','serif'],
   			 },
extend: {
	spacing: {
	'8xl': '96rem',
	'9xl': '128rem',
   		 }
	borderRadius: {
	'4x1':'2rem',
    	}
		}
	}
}

示意图

image.png

Facebook 重构拥抱atomic css: sebastienlorber.com/atomic-css-…

总结

image.png