一文疏通你的CSS,提高CSS能力!

571 阅读14分钟

CSS知识体系

一、CSS盒模型

1. css盒模型

盒模型是CSS中最重要最核心的概念

1.1 组成
  • margin:边距,外部透明区域,负责隔离相邻盒子
  • border:边框,内部着色区域,负责隔离边距和填充,包含widthstylecolor三个扩展属性
  • padding:填充,内部着色区域,负责扩展盒子内部尺寸
  • content:内容,以文本节点存在的占用位置

CSS3中box-sizing属性可以区别盒模型的类型

  • content-box:标准盒模型 (默认)
  • border-box: ie盒模型 , 区别不包含 padding border
1.2 块级格式化上下文

BFC是页面上一个独立且隔离的渲染区域,容器里的子节点不会在布局上影响到外面的节点

特点
  • 子节点的垂直方向距离由margin决定,相邻节点的margin会发生重叠,以最大margin为合并值
  • 每个节点的margin-left/right与父节点的左边/右边相接触,即使处于浮动也如此,除非自行形成BFC
  • BFC区域不会与同级浮动区域重叠
  • BFC是一个隔离且不受外界影响的独立容器
  • 计算BFC高度时其浮动子节点也参与计算
触发方式
  • 根节点:html
  • 非溢出可见节点:overflow:!visible
  • 浮动节点:float:left/right
  • 绝对定位节点:position:absolute/fixed
  • 被定义成块级的非块级节点:display:inline-block/table-cell/table-caption/flex/inline-flex
  • 父节点与正常文档流的子节点(非浮动)自动形成BFC
解决什么场景问题
  • 清除浮动
  • 防止浮动节点被覆盖
  • 防止垂直margin合并
1.3 文档流

文档流指节点在排版布局过程中默认使用从左往右从上往下的流式排列方式。在窗体自上而下分成一行行,且每行按照从左至右的顺序排列节点,其显著特点就是从左往右从上往下

脱流文档流指节点脱流正常文档流后,在正常文档流中的其他节点将忽略该节点并填补其原先空间。文档一旦脱流,计算其父节点高度时不会将其高度纳入,脱流节点不占据空间,因此添加浮动或定位后会对周围节点布局产生或多或少的影响。

文档流的脱流有两种方式。

  • 浮动布局:float:left/right
  • 定位布局:position:absolute/fixed

脱离文档流后和重绘回流的关系

当元素脱离文档流后,其重绘和回流的情况会受到一定影响。

对于脱离文档流的元素:

  • 重绘:其自身的样式改变(如背景颜色、边框颜色等)仍会触发重绘。

  • 回流:它不会影响到原来文档流中其他未脱离文档流元素的布局,即不会导致其他未脱离文档流元素的回流。但自身的布局改变(如位置、大小等)可能会引起自身的回流。

总的来说,脱离文档流可以减少对文档流中其他元素的回流影响,但自身的布局和样式变化仍可能导致自身的重绘和回流。

2. 布局样式

2.1 样式计算权重
直观权重
  • 10000!important
  • 1000内联样式外联样式
  • 100ID选择器
  • 10类选择器伪类选择器属性选择器
  • 1元素选择器伪元素选择器
  • 0通配选择器后代选择器兄弟选择器

**注意:遇到样式覆盖不能盲目使用!important

!important > 内联样式 = 外联样式 > ID选择器 > 类选择器 = 伪类选择器 = 属性选择器 > 元素选择器 = 伪元素选择器 > 通配选择器 = 后代选择器 = 兄弟选择器

2.2 css单位

单位定义类型描述
px像素绝对单位代表屏幕上的一个固定的物理像素点
rpx小程序中的像素相对单位750rpx 为基准宽度会自适应屏幕
%百分比相对单位相对父节点,宽度对应,高度不一定对应
emM的宽度相对单位相对当前节点字体
remM的宽度相对单位相对根结点字体
vw1%视窗宽度相对单位相对视窗
vh1%视窗高度相对单位相对视窗

2.3 布局

  • 普通布局:display:block/inline
  • 浮动布局:float:left/right
  • 定位布局:position:relative/absolute/fixedleft/right/top/bottom/z-index
  • 表格布局:table系列属性
  • 弹性布局:display:flex/inline-flexflex系列属性
  • 多列布局:column系列属性
  • 格栅布局:display:grid/inline-gridgrid系列属性
  • 响应式布局:em/rem/vw/vh/vmin/vmax媒体查询

一般 定位布局 弹性布局 就能解决大部分需求,栅格布局在部分浏览器上兼容性不好

2.4 文字溢出

  • 单行文字溢出显示...
.s-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
  • 多行文字溢出... (两种方式)
.m-ellipsis {
    display: -webkit-box;
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: break-all;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2; /* Webkit 内核浏览器(如 Chrome、Safari) */
    -moz-line-clamp: 2; /* Firefox */
    -ms-line-clamp: 2; /* Internet Explorer/Edge */
    line-clamp: 2; /* 标准属性 */
}
/* 可以通过伪元素设置 */
/* .m-ellipsis {
    overflow: hidden;
    position: relative;
    max-height: 120px;
    line-height: 40px;
    &::after {
        position: absolute;
        right: 0;
        bottom: 0;
        padding-left: 20px;
        background: linear-gradient(
            to right,
            transparent,
            #fff 50%
        );
        content: "...";
    }
} */

5. 背景和遮罩

5.1 背景属性

background包含以下子属性,而mask子属性也大部分与background一致。

  • background-color:背景颜色
  • background-image:背景图像
  • background-repeat:背景图像平铺方式
  • background-attachment:背景图像依附方式
  • background-position:背景图像起始位置
  • background-size:背景图像尺寸模式
  • background-origin:定位区域
  • background-clip:绘制区域
  • background-blend-mode:混合模式

详细说明所有取值

  • background-color:颜色
    • HEX:十六进制色彩模式
    • RGBRGBA:RGB/A色彩模式
    • Color1/Color2:覆盖颜色,背景颜色可能是Color1,若背景图像无效则使用Color2代替Color1
  • background-image:图像
    • none:无图像(默认)
    • url():图像路径
  • background-repeat:图像平铺方式
    • repeat:图像在水平方向和垂直方向重复(默认)
    • repeat-x:图像在水平方向重复
    • repeat-y:图像在垂直方向重复
    • no-repeat:图像仅重复一次
    • space:图像以相同间距平铺且填充整个节点
    • round:图像自动缩放直到适应且填充整个节点
  • background-attachment:图像依附方式
    • scroll:图像随页面滚动而移动(默认)
    • fixed:图像不会随页面滚动而移动
  • background-position:图像起始位置
    • Position:位置,可用任何长度单位,第二个位置(Y轴)不声明默认是50%(默认0% 0%)
    • Keyword:位置关键字left、right、top、bottom、center,可单双使用,第二个关键字不声明默认是center
  • background-size:图像尺寸模式
    • auto:自动设置尺寸(默认)
    • cover:图像扩展至足够大,使其完全覆盖整个区域,图像某些部分也许无法显示在区域中
    • contain:图像扩展至最大尺寸,使其宽度和高度完全适应整个区域
    • Size:尺寸,可用任何长度单位,第二个尺寸(高)不声明默认是auto
  • background-origin:定位区域(与background-position结合使用)
    • padding-box:图像相对填充定位(默认)
    • border-box:图像相对边框定位
    • content-box:图像相对内容定位
  • background-clip:绘制区域 可以取值为text作用于文字效果
    • border-box:图像被裁剪到边框与边距的交界处(默认)
    • padding-box:图像被裁剪到填充与边框的的交界处
    • content-box:图像被裁剪到内容与填充的交界处
  • background-blend-mode:混合模式
    • normal:正常(默认)
    • color-burn:颜色加深
    • color-dodge:颜色减淡
    • color:颜色
    • darken:变暗
    • difference:差值
    • exclusion:排除
    • hard-light:强光
    • hue:色相
    • lighten:变亮
    • luminosity:亮度
    • multiply:正片叠底
    • overlay:叠加
    • saturation:饱和度
    • screen:滤色
    • soft-light:柔光
/* 简写 */
.elem {
    background-color: #f66;
    background-image: url("./img.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 100px 100px;
}
/* 连写 */
.elem {
    background: #f66 url("./img.png") no-repeat center/100px 100px;
}

连写顺序 background: color image repeat attachment position/size

5.2 渐变

每个渐变函数都必须在backgroundbackground-image上使用,可认为gradient()就是一个图像,只不过是通过函数产生的图像。

渐变函数
  • linear-gradient():线性渐变 沿着指定方向从起点到终点逐渐改变颜色,渐变形状是一条直线

  • radial-gradient():径向渐变 沿着任意方向从圆心往外面逐渐改变颜色,渐变形状是一个圆形椭圆形

  • conic-gradient():锥形渐变 沿着顺时针方向从圆心往外面逐渐改变颜色,渐变形状是一个圆锥体 兼容性较差 使用率不高

  • repeating-linear-gradient():重复线性渐变

  • repeating-radial-gradient():重复径向渐变

  • repeating-conic-gradient():重复锥形渐变

  • background-image: linear-gradient(direction, color-stop)

    • (方向,色标)
  • background-image: radial-gradient(shape size at position, color-stop)

    • (形状 , 尺寸 , 位置 , 色标)
5.3 遮罩

详细属性不一一展开了,maskbackground的格式和用法大部分相似,作用效果也相似

实现镂空背景有两个要点:

  • 声明background时可选纯色、图像或渐变
  • 声明mask时必须选择透明格式的图像才能用该图像的透明区域遮挡背景

6. 阴影和滤镜

阴影滤镜能让视觉元素看上去更具立体感,阴影为视觉元素提供了边界轮廓,滤镜为视觉元素提供了多变外观

6.1 阴影
  • box-shadow
    • 盒子轮廓产生阴影效果
  • text-shadow
    • 文本轮廓产生阴影效果
  • drop-shadow() filter里的滤镜函数
    • 透明图像的非透明部分轮廓产生阴影效果

阴影的参数

  • OffsetX:水平偏移 (长度单位)
  • OffsetY:垂直偏移 (长度单位)
  • Blur:模糊半径 (长度单位)
  • Spread:扩展距离 (长度单位)
  • Color:投影颜色 (颜色)
  • Position:投影位置
6.2 滤镜
  • blur():模糊 (长度单位)
  • brightness():亮度 (百分比)
  • contrast():对比度 (百分比)
  • drop-shadow():阴影 上述
  • grayscale():灰度 (百分比)
  • hue-rotate():色相旋转 (角度)
  • invert():反相 (百分比)
  • opacity():透明度 (百分比)
  • saturate():饱和度 (百分比)
  • sepia():褐色 (百分比)

7. 变换与动画

主要学习的是transformtransitionanimation三大交互属性

7.1 transform

变换分为2D变换3D变换。通过transform-style属性进行区别 , 默认是2D

属性
  • translate() 位移 (长度单位)
    • translate(x,y):2D位移 也可以单独设置translateX 只偏移X轴
    • translate3d(x,y,z):3D位移
  • scale():缩放 (数值或百分比)
    • scale(x,y):2D缩放 同样可以单独设置scaleX(x)
    • scale3d(x,y,z):3D缩放
  • skew():扭曲 (Angle角度或Turn周)
    • skew(x,y):2D扭曲
  • rotate():旋转 (Angle角度或Turn周)
    • rotate():2D旋转
    • rotate3d(x,y,z,a):3D旋转,[x,y,z]是一个向量,数值都是0~1
  • matrix():矩阵(太过复杂,可放弃)
7.2 transition

不同状态间切换属性,让切换时过渡更加丝滑

属性
  • transition-property 添加过渡的属性 默认是all
  • transition-duration 过渡时间
  • transition-timing-function 缓动函数
    • ease 逐渐变慢
    • linear 匀速
    • ease-in 加速
    • ease-out 减速
    • ease-in-out 先加后减
    • cubic-bezier 贝塞尔曲线
  • transition-delay 延迟生效
7.3 animation

transform能让节点拥有更多形态,而animation能让节点拥有更多状态

CSS动画可通过设置多个点精确控制一个或一组动画,用来实现复杂的动画效果。

  • 关键帧动画:在时间轴的关键帧上绘制关键状态并使之有效过渡组成动画 @keyframes
  • 逐帧动画:在时间轴的每一帧上绘制不同内容并使之连续播放组成动画 steps()

关键帧动画可看作是一个连续的动画片段,逐帧动画可看作是一个断续的动画片段,两种动画都是通过时间流逝将多个动画片段串联在一起。

浏览器可将关键帧动画的关键帧自动过渡成片段,而将逐帧动画的每一帧按顺序播放成片段,可认为逐帧动画是一个GIF

属性
  • animation-name:动画名称
  • animation-duration 动画执行时间
  • animation-timing-function 缓动函数 基本与上述一致 多了steps
    • steps([,[start|end]]?) 把动画平均划分成n等分,直到平均走完该动画
  • animation-delay 动画延迟
  • animation-iteration-count 动画播放次数
    • infinite:无限次
    • number : 次数
  • animation-direction 轮流反向播放
    • normal:正常播放(默认)
    • alternate:轮流反向播放,奇数次数正常播放,偶数次数反向播放
  • animation-play-state 播放状态
    • running:正在播放(默认)
    • paused:暂停播放
  • animation-fill-mode 播放前后效果
    • none:不改变默认行为(默认)
    • forwards:在动画结束后保持最后一帧

二、一些效果(不定期更新扩展,目前放一些自己练习的)

2.1 手机element进度条动画

<div class="loading-box">
    <div class="progress-bar"></div>
</div>
...
<style>
.loading-box{
    width: 100px;
    height: 20px;
    overflow: hidden;
    border-radius: 8px 8px 8px 8px;
}
/* 
重复的渐变  repeating-linear-gradient  实现加载条效果
如果使用 linear-gradient  那么需要一直重复
linear-gradient(
    45deg, 
    #f06a0e, 
    #f06a0e 11px, 
    transparent 11px, 
    transparent 20px, 
    #f06a0e 20px, 
    #f06a0e 31px, 
    transparent 31px, 
    transparent 40px,
    #f06a0e 40px, 
    #f06a0e 51px, 
    transparent 51px, 
    transparent 60px
);
*/
.progress-bar {
    width: 200px;
    height: 20px;
    background-color:  rgba(206, 207, 206, 0.2);
                background-image: repeating-linear-gradient(
                        45deg,
                        #f06a0e,
                        #f06a0e 9px,
                        transparent 9px,
                        transparent 16px
                );
    animation: loading .8s linear infinite;
        }
@keyframes loading {
    0%{
        transform: translateX(-50px);
    }
    50%{
        transform: translateX(-30px);
    }
    100%{
        transform: translateX(0px);
    }
}
</style>

微信截图_20240902141018.png

2.2 两张图无限切换动画

使用遮罩完成小美banner的动画 动态改变 mask 属性范围、大小等值

<div class="g-outer">
    <div class="g-inner"></div>
</div>
...
<style>
 .g-outer {
    margin: auto;
    width: 376px;
    height: 144px;
    background: url(https://ly-sys-image.oss-cn-beijing.aliyuncs.com/img/static/mine/banner1_cn.png) center no-repeat;
    background-size: contain;
}
.g-inner {
    width: 376px;
    height: 144px;
    background: url(https://ly-sys-image.oss-cn-beijing.aliyuncs.com/img/static/mine/banner2_cn.png) center no-repeat;
    background-size: contain;
    mask: linear-gradient(90deg, #fff 0%, #fff 50%, transparent 50%, transparent 100%);
    mask-size: 200% 100%;
    animation: maskChange 2s infinite alternate linear;
}
@keyframes maskChange {
    0% {
        mask-position: -100% 0;
    }
    100% {
        mask-position: 0 0;
    }
}
</style>

动画2.gif

2.3GTA不规则图形封面

<div class="grid-parent">
        <div class="child">
                <img src="./assets/GTA-1.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-3.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-2.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-3.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-3.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-2.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-2.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-3.png" alt="" />
        </div>
        <div class="child">
                <img src="./assets/GTA-2.png" alt="" />
        </div>
</div>
...
<style>
/* 
整体思路:
先利用网格布局 分割成四行四列  划分出9*9不规则排列
再利用
clip-path 和 放大图像 切割成不规则图形
*/
.grid-parent {
    width: 500px;
    height: 80vh;
    border: 1px solid #c9b473;
    overflow: hidden;
    display: grid;
    background: #000;
    /* 
    定义了网格的列宽。1fr 表示一个等分的单位,0.7fr 和 0.3fr 则表示按照比例分配的宽度。
    这意味着第一列和第四列将占据相等的空间,第二列约占第一列的 70%,第三列约占第一列的 30%
    */
    grid-template-columns: 1fr 0.7fr 0.3fr 1fr;
    /* 
    定义了网格的行高。分别将网格的高度按比例分为 20%、40%、20%、20%
    */
    grid-template-rows: 20% 40% 20% 20%;
    /* 
    通过给每个网格区域命名来定义网格的布局结构
    第一行,从左到右分别为区域 one 、 two 、 two 、 three 。 依次类推
    */
    grid-template-areas:
        "one two two three"
        "four five five five"
        "six five five five"
        "six seven eight eight";
        & img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            object-position: 70% 20%;
            transition: 0.25s;
            cursor: pointer;
            &:hover {
                transform: scale(120%);
            }
        }
    }
    .child {
        &:nth-child(1),
        &:nth-child(2),
        &:nth-child(3){
            img{
                width:120%;
                height: 120%;
            }
        }
        &:first-child {
            grid-area: one;
            clip-path: polygon(0% 0%, 93.24% 0%, 105.04% 110.16%, 0% 90%);
        }
        &:nth-child(2) {
            grid-area: two;
            clip-path: polygon(0% 0%, 108.28% 0%, 96.45% 110.13%, 10.55% 110.93%);
        }
        &:nth-child(3) {
            grid-area: three;
            clip-path:polygon(15.05% 0%, 100% 0%, 99.35% 91.7%, 3.08% 108.48%);
        }
        &:nth-child(4) {
            grid-area: four;
            clip-path: polygon(0% -0.85%, 106.34% 9.98%, 121.32% 65.63%, 99.66% 109.89%, 1.86% 124.41%);
            img{
                width: 135%;
                height: 135%;
            }
        }
        &:nth-child(5) {
            grid-area: five;
            clip-path: polygon(6.4% 6.48%, 47.24% 5.89%, 100% 0%, 98.41% 96.85%, 53.37% 100%, 53% 63.21%, 3.23% 73.02%, 14.30% 44.04%);
        }
        &:nth-child(6) {
            grid-area: six;
            clip-path:  polygon(2.14% 29.3%, 99.34% 15.42%, 98.14% 100.82%, 1.57% 101.2%);
        }
        &:nth-child(7) {
            clip-path: polygon(7.92% 33.47%, 96.31% 23.39%, 95.38% 100%, 5.30% 100.85%);
            grid-area: seven;
        }
        &:nth-child(8) {
            clip-path: polygon(2.5% 22.35%, 100% 0%, 100% 100%, 1.55% 100%);
            grid-area: eight;
        }
        &:nth-child(9) {
            clip-path:polygon(5.94% 28.66%, 100.61% -0.67%, 101.1% 108.57%, 5.4% 126.28%);
            /* 起始行 */
            grid-row-start: 3; 
            /* 终止行 */
            grid-row-end: 4;
            /* 起始列 */
            grid-column-start: 2;
            /* 终止列 */
            grid-column-end: 4;
            img {
                object-position: 30% 50%;
                height: 135%;
            }
        }
    }
</style>

动画3.gif

写在最后

本文只是自己做了总结,绝大部分内容都是取自掘金小册。 欢迎大家互相学习