CSS的理解
基础知识
Casading规则、选择器、继承、值和单位、盒模型
层叠(Casading)、优先级
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;
}
层叠三大规则
优先级别
样式表重要来源排序
选择器的类别
基础选择器
#id一一ID选择器。Tagname一一类型选择器或者标签选择器。 .class一一类选择器。*一一通用选择器。该选择器匹配所有元素
组合器
- 子组合器(>)一一匹配的目标元素是其他元素的直接后代。如:
.parent>.child。 - 相邻兄弟组合器(+)一一匹配的目标元素紧跟在其他元素后面。如:
p+h2。 - 通用兄弟组合器(~)一一匹配所有跟随在指定元素之后的兄弟元素,如:
i.active~li。 - 复合选择器多个基础选择器可以连起来使用,如:h1.page-header。
属性选择器
伪类选择器
伪元素选择器
逻辑选择器
选择器的优先级
注意:
- 内联样式不属于选择器,为了方便比较记忆,放在这里做对比
:is()``:not()``:has()本身不计入优先级,以参数中最高的优先级为准,:where()优先级为0源码顺序
源码顺序
- 对于@import的样式,根据@import的顺序。
- 对于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;
}
注意:
- 选择器尽量少用id
- 尽量不要用!important
- 自己的样式加载在引用库样式的后面
继承
- 大部分具有继承特性的属性跟文本相关:
color、font、font-family、font-size、font-weight、.font-variant、font-style、line-height、letter-spacing、text-align、text-indent、text-transform、white-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的值和单位
布局和定位
盒模型
浏览器根据视觉格式化模型(visual formatting model),将所有元素表示为盒子模型,css通过盒模型做layout
- 控制盒子类型
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/…
实现三角形
示例图
代码
//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;
}
实现固定比例矩形
示例图
代码
//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
实现水平居中
示例图
代码
//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的更多表现:链接
实现渐变边框
示意图
代码
//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可以设置负值
设置左边或顶部的负外边距,元素就会相应地向左或向上移动,导致元素与它前面的元素重叠:
如果设置右边或者底部的负外边距,并不会移动元素,而是将它后面的元素拉过来:
margin负值最终减少的是外界可感知的宽高
常规流、弹性盒子、Grid、定位
概述
CSS3之前的常用布局
Normal Flow常规流
- 默认的布局方式
- 有块级格式化上下文和内联
- 格式化上下文
Float浮动流
- 用float/属性控制
- 脱流,做横向布局
Positioning定位流
- 用position.属性控制
- fxed和absolute脱离文档流
- 可以自由定位、覆盖等
CSS3之后的新增布局
- Flex弹性盒子布局
- 一维空间布局
- Grid网格布局
- 二维空间布局
- Multicol多列布局
- 文本、内容的多列展示
常规流布局
块级格式化上下文(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
外边距塌陷
会产生外边距塌陷的情况:
- 两个兄弟元素之间相邻的上下外边距。
- 父子元素之间相邻的上下外边距。
- 内容为空元素自己上下外边距相邻。
消除外边距塌陷的方法:
- 在两个相邻的上下边距之间增加border、padding?或者内联元素,使之不相邻。
- 在父子元素重叠时,除了上述方法,还可以设置父元素为BFC,使得父子不在同级BFC中。
了解更多BFC特性:链接
内联级格式化上下文
在内联格式区域中,盒子会从包含块的顶圈开始,按序水平排列。只有水平外边距、边框和内边距 会被保留。这些盒子可以以不同的方式在垂直方向上对齐:可以底部对齐或顶部对其,或者按文字 底部进行对齐,我们把包含一串盒子的矩形区域称为一个线条柜。(The[ectangular area that contains the boxes that form a line is called a line box.)"-9.4.2
一些实际case:
- 单行文字垂直居中
我是标题
利用了ine-height的垂直居中特性
//html
<div class="title">我是标题</div>
//css
.title {
background:antiquewhite;
font-size:18px;
line-height:36px;
height:36px;//可以省略
}
- 文字和icon垂直对齐
//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是为了提供更加高效灵活的布局方式,在即便是宽高未知的情况下,也能排列和分割一个盒子内部的布局。而且在不同布局方向(横向纵向)的调整更为灵活。
弹性盒子的相关属性分为两类
作用于父元素(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;
}
展示筛子上的六个面
示例图(一)
代码(一)
//html
<div class="dot-one">
<div class="dot"></div>
</div>
.dot-one {
display:flex;
justify-content:center;
align-items:center;
}
示例图(二)
代码(二)
//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;
}
示例图(三)
代码(三)
//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布局可以定义由行和列组成的二维布局,然后将元素放置到网格中。元素可以只占其中一个单元格,也可以占据多行或多列。
源代码
.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布局
示意图
示例代码
.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;
}
示意图
示例代码
<div class="face">
<span class="dot cc-dot red"></span>
</div>
示意图
示例代码
<div class="face">
<span class="dot lt-dot"></span>
<span class="dot cc-dot"></span>
<span class="dot rb-dot"></span>
</div>
示意图
示例代码
<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
Grid
Grid for layout,Flexbox for components
定位 Position
为了我们可以在文档流的基础上,让元素移动,做出更多灵活的改变。当oosition属性的取值非static的时候,可以使用top,right,bottom,left对其进行定位。
relative
元素相对于自己原来在文档流中的位置进行定位,但是原来文档流的空间还在。
示意图
示例代码
.relatived {
position:relative;
top:30px;
left:10px;
}
absolute
元素被移出正常文档流,且没有预留空间,相对于最近的非static定位祖先元素的进行定位。
示意图
示例代码
.wrap {
position:relative;
}
.abosoluted {
position:absolute;
top:30px;
left:10px;
}
fixed
元素被移出正常文档流,且没有预留空间,相对于屏幕视口进行定位,屏幕滚动也不会改变位置。
示意图
示例代码
fixed-pos {
position:fixed;
t0p:10%;
left:10%;
}
sticky
元素相对它的最近滚动祖先(祖先的overflow是scrol/hidden/auto)的视口(scrollport)定位。
示意图
示例代码
.sticky {
position:sticky;
top:20px;
}
使用定位的示例
示意图
示例代码
<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轴排开.
页面展示
示例代码
<body>
<div class="wrap">
<div class="area1"></div>
<div class="area2">
<div class="area2-1"></div>
</div>
</div>
</body>
层叠上下文结构
浏览器渲染部分过程示意图 链接
一个新的层叠上下文渲染时会对应一个浏览器渲染时的render layer(渲染层)。
- 示意图
*注意:不是浏览器devtooll图层工具中看到的图层
形成新的层叠上下文的条件(任一即可):
- position:relative或absolute;并且z-index不是auto
- position:fixed或sticky
- oflex或grid的子元素;并且z-index不是auto 为CSS3之前
- opacity的值小于1
- transform的值不为none
- will-change的值不为通用值
- ..详见规范*
stacking order
- 层叠顺序不仅指不同的层叠上下文的顺序,同一个层叠上下文内,元素间也有顺序:
- z-index只在同一个层叠上下文内比较
- 子元素的z-index无法超越父元素的z-index显示顺序
例1:
实践网址:codepen.io/yao-mo/pen/…
例2:
编写z-index的建议
- 使用css变量或者预处理语言的变量,管理z-index的值
- 将预设间隔设置10或100,方便后续的插入
变形、过渡、动画
transform变形
2D相关属性
- transform:translate(移动)、rotate(旋转)、scale(放缩)、matrix(变形矩阵)等
- transform-origin:right top、center等,表示变形时依据的原点
示意图
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:元素正面只有朝向观察者的时候可见
示意图
transform变形3D
transition过渡
通过指定某些元素属性从一种起始状态,在一段时间内以某种变化节奏,过渡到终止状态。
示例代码
div {
transition:<property><duration><timing-function><delay>;
}
其中timing-function一般有三种用法:线性((linear)、贝塞尔曲线(cubic-bezier(0或ease-in等)、阶跃(step)
animation动画
@keyframes关键帧用来定义动画过程中出现的关键样式
animation-*相关属性用来为元素添加动画
transform、transition、animation一性能相关
如何写动画性能更好
- 尽量不用触发reflow的属性
- 在遇到性能问题时可以触发硬件加速,比如设置will-change属性、设置transform3d等
- 尽量使用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
- 媒体查询同样遵循cascading层叠覆盖原则,min-和max-选择一个
- 由于设备的多样化逐渐不可枚举,断点的选择尽量根据内容选择
- 由于断点的增加会增加样式处理的复杂度,所以尽量减少断点
示意图:
设备像素、参考像素和移动设备视口
设备像素
- 设备像素(物理像素):显示器上绘制的最小单位,显示屏通过控制每个像素点的颜色,使屏幕显示出不
同的图像。
- 设备像素和设备相关,屏幕从工厂出来那天起它上面的物理像素点就固定不变了。
![]()
DPI &PPI
- dpi(dots per inch):每英寸多少点。
- ppi(pixels per inch).:每英寸多少像素数。
- 当用于描述显示器设备时ppi与dpi是同一个概念,说的是每英寸多少物理像素及显示器设备的点距
当屏幕分辨率是X*Y,计算公式:
CSS像素
- CSS像素(reference pixel)其实是一个视角单位。规范给出的定义是,1css像素是从一臂之遥看解析度为96DPI(即1英寸96点)的设备输出时,1点(即1/96英寸)的视角。
- 通常认为常人臂长为28英寸,那么视线与水平线的夹角是:(1/96)in/(28in2P1/360deg)=0.0213度
- 如果1CSS像素永远等于1设备像素,那么
- 但是真正使用的CSS像素并不是用0.0213度去精确计算的,因为css像素存在的目的是为了保证阅读体验一致,所以对不同的物理设备,CSS使得浏览器中1CSS像素的大小在不同物理设备上看上去大小总是差不多。
- 真正实现时,为了方便基本都是根据设备像素换算的。浏览器根据硬件设备能够直接获取CSS像素。
DPR设备像素比
设备像素比(dpr): 描述的是未缩放状态下,设备像素和CSS像素的初始比例关系
![]()
移动端的viewport
- 布局视口(viewport)是页面中html元素(根元素)的包含块,默认情况下,window.document..documentElement..clientWidth就是viewport的宽度。
- 在移动设备中,默认的布局视口由于历史兼容pc屏幕的原因,并不符合需求,我们经常需要用标签对viewport进行设定,来完成移动端设备的适配。
- 比如:默认iphonel的布局视口是980px,展示如图:
viewport的meta标签中的属性
默认iPhone的viewport可以认为是:
<meta name="viewport"content="width=980">
- 其中initial-scale,在未设定时,如果width设定了,那么它会自动设置放缩值:initial-scale=屏幕宽度(例子中是390)/980≈0.398 相比scale=1的时候,缩小了0.398倍
常见的移动端viewport的设置:
- 保持scale为1
<meta name="viewport"content="width=device-width,initial-scale=1">
- 好处是:在所有设备上不管横屏还是竖屏,让布局视口的宽度和设备屏幕的宽度保持一致,且参考像素不放缩。
- 不好的是:如果设备的dpr>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
应用场景:可以让展示区域根据展示字号的不同,做出放缩调整。
示例代码
//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依然可以写为:
- 利用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依然可以写为:
- 利用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 完成不同设备上的等比放缩展现
绝对长度和视口
CSS生态相关
语言增强:预处理器、后处理器
语言增强一一CSS预处理器
示例代码
//变量:以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简单对比
| scss | less | stylus | |
|---|---|---|---|
| css语法兼容 | 兼容 | 兼容 | 常规兼容 |
| 可编程能力 | 较强逻辑处理能力丰富 | 较弱:不支持自定义函数 | 较强 |
| 社区活跃、使用人数 | 最多start3.3k;burbon,库支持 | 较多star16.9k;twitter bootstrap框架 | 相对少star11k |
广义CSS预处理器
编译过程中的广义预处理器
后处理器
postcss机制浅析
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;
}
CSS-in-JS
css-in-js:将应用的CSS样式写在JavaScript文件里面,利用js动态生成css
刺激的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
原子化CSS
原子化CSS是一种CSS的架构方式,它倾向于小巧且用途单一的class,并以视觉效果进行命名。
传统方式
<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如何做的?
- 实用工具库优先(Utilities-First)
@tailwind base;
atailwind components;
atailwind utilities;
利用基础的规则库预先定义好生成规则
- 按需生成
<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;
}
- 支持配置样式规则&自定义插件
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',
}
}
}
}
示意图
Facebook 重构拥抱atomic css: sebastienlorber.com/atomic-css-…