那些你需要知道的CSS知识

Flex 弹性布局

display: flex 弹性盒子,提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。

父容器属性

属性名默认值说明
flex-directionrow定义主轴方向,指定子元素在父容器中的从哪个方向排列
flex-wrapnowrap指定子元素换行方式(唯一能改变交叉轴开始、结束方向的属性)
flex-flowrow nowrapflex-flow 是 flex-direction flex-wrap 的简写
justify-contentflex-start子元素沿着父容器的主轴(理解成row方向的X轴)的对齐方式
align-itemsstretch子元素沿着父容器的交叉轴(理解成row方向的Y轴)的对齐方式
align-contentstretch设置了 flex-wrap 换行才生效,控制各行的对齐(多行交叉轴对齐)

若子元素未设置高度或设为 autostretch 属性值会使子元素的尺寸尽可能接近所在行的尺寸(撑满父元素),但同时会遵照 (min/max)-(width/height) 属性的限制。

弹性子元素属性

属性名默认值说明
order0定义排列顺序,数值小的排在前面。可以为负值
align-selfauto设置弹性元素自身在交叉轴方向上的对齐方式,可覆盖align-items属性值
flex-grow0一般取值为数字,表示占分配父容器 剩余宽度(高度)的份数
flex-shrink1子项目的宽度和(或者高度和)超过 flex 父容器的宽度,子项目会不会缩小
flex-basisauto元素本身大小的基准值。可以是0,auto,百分比,像素值
flex0 1 autoflex 是 flex-grow flex-shrink flex-basis 的简写

flex 搭配 margin: auto 可以做到很多其他的效果

例如:左边1个,右边两个,中间的给 margin-left: auto,或者最左边的给 margin-right: auto

在这里插入图片描述

/* 下方示例的前置代码 */

/* css */
.container{
  width: 550px;
  height: 250px;
  border: 5px solid silver;
  display: flex;
}
.item{
  width: 100px;
  height: 100px;
}
.item:nth-child(1) {
    background-color: green;
}
.item:nth-child(2) {
    background-color: yellow;
}
.item:nth-child(3) {
    background-color: pink;
}
.item:nth-child(4) {
    background-color: purple;
}

/* html */
<div class="container">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
</div>

flex-grow

表示在主轴方向上,如果子项目的宽度和(或者高度和)并没有完全占满 flex 父容器的宽度,父容器剩余宽度将如何分配。flex-grow 默认是0,即不拉伸子容器,即使父容器没有被占满

.item:nth-child(1){
  flex-grow: 1
}
.item:nth-child(2){
  flex-grow: 2
}
.item:nth-child(3){
  flex-grow: 2
}

表示如果父容器宽度还有剩余,则第一个元素占 1 份,第二个元素占 2 份,第三个元素占 2 份

// 结果
父元素剩余宽度:550 - 100 - 100 - 100 = 250
总份数:1 + 2 + 2 = 5
每份占的宽度:250 / 5 = 50
第一个子元素宽度:50*1 + 100 = 150
第二个子元素宽度:50*2 + 100 = 200
第三个子元素宽度:50*2 + 100 = 200

在这里插入图片描述

flex-shrink

表示在主轴方向上,如果子项目的宽度和(或者高度和)超过 flex 父容器的宽度,子项目会不会缩小。flex-shrink 默认为1,即如果空间不足,该项目将缩小。

.item{
  width: 200px;
  height: 100px;
}
.item:nth-child(1){
  flex-shrink: 1
}
.item:nth-child(2){
  flex-shrink: 2
}
.item:nth-child(3){
  flex-shrink: 2
}

如果父容器被超过时,则第一个元素缩小占 1 份,第二个元素缩小占 2 份,第三个元素缩小占 2 份

// 结果
父元素超过的宽度:200 + 200 + 200 - 550 = 50
每份占的宽度:50/(200*1 + 200*2 + 200*2) = 0.05
第一个子元素宽度:200 - 1*0.05*200 = 190
第二个子元素宽度:200 - 2*0.05*200 = 180
第三个子元素宽度:200 - 2*0.05*200 = 180

在这里插入图片描述

flex-basis

控制项目本身的宽度,浏览器根据这个属性,计算主轴是否有多余空间

  • 0:优先将内容项目会尽量占较小空间显示(本身元素能够渲染内容的最小宽度)
  • 百分比:相对比父容器的大小
  • auto:本身的原始大小显示

父容器无剩余空间时,需要设置 flex-shrink: 0 才有效

优先级: (min/max)-(width/height) > flex-basis > width

.item{
  width: 200px;
  height: 100px;
}
.item:nth-child(1){
  flex-basis: 0;
}
.item:nth-child(2){
  min-width: 100px;
  flex-basis: 50px;
}
.item:nth-child(3){
  flex-basis: auto;
}

在这里插入图片描述

flex属性

按照以往的经验,css 的属性只有一个值的时候,另外缺省的值应该使用默认值才对,但是 flex 属性并不是这样的。

  • flex 简写表示 flex-grow flex-shrink fkex-basis 的组合写法,后两个属性值可选
简写值实际值备注
flex: initialflex: 0 1 auto初始值
flex: 1flex: 1 1 0%适合等分布局
flex: noneflex: 0 0 auto适用于不换行的内容固定
flex: 0flex: 0 1 0%使用较少
flex: autoflex: 1 1 auto适合基于内容动态适配的布局

在这里插入图片描述

误区:以为 flex:1;flex:2; 可以按 1:2 比例分配项目;

实际flex: n 只是在父容器确定有多余空间的时候才按照相应的比例分配,而不是元素本身的比例,元素本身的大小比例是通过 max-width 实现的

项目本身的宽度以及是否拉伸或者缩小要根据 (min/max)-widthflexwidth 一起计算

/* flex + max-width 实现等比例栅格布局 */ 
.container {
    display: flex;
}
.item {
    flex:0 0 33.33333333%;  
    max-width: 33.33333333%;
}

Grid 网格布局

display: grid 网格布局,比较擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系,是目前唯一一种 CSS 二维布局。

注意:某些时候可能需要加上一个 min-width: 0; 或者 overflow: hidden

例如:当父元素采用 flex 布局或 grid 布局时

  1. 防止父元素被无限撑开‌:父容器没设宽度的情况,父元素可能会被子节点无限撑开。通过设置min-width: 0,可以确保父元素中的子元素内容不会超出父元素容器。
  2. 解决white-space: nowrap导致的问题‌:有助于解决由于white-space: nowrap导致的布局问题,确保元素不会因为内容过长而被撑开‌。

常见的 Grid 布局示例

Grid 练习小游戏

父容器属性

定义行、列

grid-template-columns 属性设置列宽,grid-template-rows 属性设置行高

固定列宽、行高
.contaienr {
    display: grid;
    /*  声明了三列,宽度分别为 200px 100px 200px */
    grid-template-columns: 200px 100px 200px;
    /*  声明了两行,行高分别为 50px 50px  */
    grid-template-rows: 50px 50px;
}
repeat

简化重复的值。该函数接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。

.contaienr {
    display: grid;
    grid-template-columns: 200px 100px 200px;
    /*  2行,而且行高都为 50px  */
    grid-template-rows: repeat(2, 50px);
}
auto-fill

自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。

.contaienr {
    display: grid;
    /* 列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素 */
    grid-template-columns: repeat(auto-fill, 200px);
    grid-auto-rows: 50px;
}
fr

fr 单位代表网格容器中可用空间的一等份。

.contaienr {
  display: grid;
  /* 第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3 */
  grid-template-columns: 200px 1fr 2fr;
  grid-gap: 5px;
  grid-auto-rows: 50px;
}
minmax

minmax() 函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。它接受两个参数,分别为最小值和最大值。

.contaienr {
  display: grid;
  /* 第三个列宽最少也是要 300px,但是最大不能大于第一第二列宽的两倍 */
  grid-template-columns: 1fr 1fr minmax(300px, 2fr);
  grid-gap: 5px;
  grid-auto-rows: 50px;
}
auto

由浏览器决定长度

.contaienr {
  display: grid;
  /* 表示第一第三列为100px,中间自适应 (三栏布局) */
  grid-template-columns: 100px auto 100px;
  grid-gap: 5px;
  grid-auto-rows: 50px;
}

gap间距

row-gap 属性、column-gap 属性分别设置行间距和列间距。 gap 属性是两者的简写形式。

.container {
    display: grid;
    row-gap: 10px;
    column-gap: 20px;
    /* 等同于 */
    gap: 10px 20px;
}

定义渲染区域

grid-template-areas 属性用于定义区域,一个区域由一个或者多个单元格组成。

这个属性跟网格元素的 grid-area 一起使用

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    html,body {
      width: 100%;
      height: 100%;
    }
    .container {
      display: grid;
      height: 100vh;
      grid-template-rows: 50px auto 50px;
      grid-template-columns: 140px 1fr 1fr;
      grid-template-areas: 
        "left top top"
        "left middle middle"
        "left footl footr";
    }
    .item:nth-child(1) {
      grid-area: left;
      background-color: red;
    }
    .item:nth-child(2) {
      grid-area: top;
      background-color: blue;
    }
    .item:nth-child(3) {
      grid-area: middle;
      background-color: yellow;
    }
    .item:nth-child(4) {
      grid-area: footl;
      background-color: orange;
    }
    .item:nth-child(5) {
      grid-area: footr;
      background-color: green;
    }
  </style>
</head>
<body>
  <section>
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
    </div>
  </section>
</body>
</html>

排列顺序

grid-auto-flow 属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。

row :默认值,先行后列,左到右,即先填满第一行,再开始放入第二行。

row dense :尽可能填满表格。中途有空位,后面的补上来

column :先列后行,上到下

column dense

在这里插入图片描述

内容区域对齐方式

justify-content 属性是整个内容区域在容器里面的水平位置(左中右),align-content 属性是整个内容区域的垂直位置(上中下),类似 flex 的属性。

.container {
  display: grid;
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

隐式网格

如果你在网格定义之外又放了一些东西,或者因为内容的数量而需要的更多网格轨道的时候,网格将会在隐式网格中创建行和列。

假如有多余的网格(也就是上面提到的隐式网格),那么它的行高和列宽可以根据 grid-auto-columns 属性和 grid-auto-rows 属性设置。

.wrapper {
  display: grid;
  grid-template-columns: 200px 100px;
  grid-template-rows: 100px 100px;
  /* 只设置了两行,但实际的数量超出了两行,超出的行高会以grid-auto-rows算 */
  grid-auto-rows: 50px;
}

在这里插入图片描述

网格元素属性

grid-column / grid-row

  • grid-column: 下面两个属性的简写方式
    • grid-column-start :左边框线
    • grid-column-end :右边框线
  • grid-row :简写方式
    • grid-row-start :上边框线
    • grid-row-end :下边框线

下方示例中,.item 元素渲染位置是 列3 - 列4行2 - 行4 ,所以是在右下角的位置。多个元素单元格占据同样的格子,可以通过 z-index 控制层级渲染关系。

在这里插入图片描述

在这里插入图片描述

grid-area

指定项目放在哪一个区域。看上方 父级容器属性 定义渲染区域示例;

Grid 解决空缺单元格问题

auto-fitminmaxdense

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      grid-gap: 10px 20px;
      grid-auto-rows: 50px;
      grid-auto-flow: row dense;
    }
    .item {
      text-align: center;
      font-size: 200%;
      color: #fff;
    }
    .item:nth-child(1) {
      background-color: #ff0000;
    }
    .item:nth-child(2) {
      background-color: #00ff00;
    }
    .item:nth-child(3) {
      background-color: #0000ff;
    }
    .item:nth-child(4) {
      background-color: #ff00ff;
    }
    .item:nth-child(5) {
      background-color: #ffff00;
    }
    .item:nth-child(6) {
      background-color: #00ffff;
    }
    .item:nth-child(7) {
      background-color: #2bff00;
    }
    .item:nth-child(8) {
      background-color: #f56161;
    }
    .item:nth-child(9) {
      background-color: #ae8cfc;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item" style="grid-column-start: span 3;">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item" style="grid-column-start: span 3;">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
  </div>
</body>
</html>

在这里插入图片描述

小知识

css单位

  • px :像素,屏幕上显示的最小单位

  • rem :相对单位, 相对于根元素字体大小的倍数

  • em :相对单位,当前元素的字体大小的倍数,如果用于设置字体大小,则相对于父元素的字体大小

  • vw / vh :相对单位,相对于浏览器可视区域窗口的宽高比

  • % : 相对单位,相对于父容器的宽高比

选择器

优先级

  1. !important
  2. 行内样式
  3. Id 选择器
  4. 类选择器、属性选择器、伪类
  5. 元素(标签)选择器,伪元素

同级选择器

# 选择h1的同级元素中的所有p标签
h1 ~ p {
    color: blue;
}

奇数偶数选择器

li:nth-child(even) {
    background-color: #f2f2f2;
}

li:nth-child(odd) {
    background-color: #e6e6e6;
}

倍数选择器

/* 选择所有3的倍数元素 */
li:nth-child(3n) {
    color: green;
}

/* 选择所有的5的倍数加3的元素 */
li:nth-child(5n+3) {
    color: purple;
}

选中文字样式

::selection {
    background-color: #ffcc00;
    color: #333;
}

水平垂直居中方式

定位

.parent { position: relative; }
.child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

flex

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

grid

.parent {
     display: grid;
    justify-content: center;
    align-items: center;
}

table

.parent {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
.child {
    display: inline-block;
}

文字

.text {
    text-align: center;
    line-height: 父容器的高度
}

字体懒加载

使用 font-display: swap; 属性提高网页字体性能,让自定义字体加载时显示备用字体。

@font-face {
    font-family: 'YourFont';
    src: url('your-font.woff2') format('woff2');
    font-display: swap;
}

像素

  • 设备像素 / 物理像素(DP) :物理屏幕上的实际像素,设备出场时就确定了,是固定不变的,每个设备像素代表显示器上的一个点。比如分辨率为 1920 * 1080 的屏幕有 1920 个水平像素和 1080 个垂直像素。
  • css 像素 :抽象单位,与设备无关(DIPs),主要用于浏览器上,就是常用的 px。根据设备的屏幕分辨率和尺寸进行适配的,确保在不同设备上显示的一致性。
  • DIP 设备独立像素 :是一种逻辑上的像素单位,在不同的设备上会映射到不同数量的物理像素,取决于设备,用于保证设计和应用的跨设备兼容性,例如 CSS像素
  • DPR 设备像素比DPR = DP / DIP 高DPR 的设备能够以更精细的物理像素点来显示一个 CSS像素点,从而提供更清晰的显示效果。
    • 电脑端: 1dip === 1dp1px 就是一个像素点 (页面缩放比为 1:1
    • 手机两倍屏: 1dip === 0.5dp
  • DPI像素密度 :衡量显示清晰度的一个主要参数,它表示每英寸所包含的像素点数。

浏览器渲染过程

  1. 解析 HTML,生成 DOM
  2. 解析 CSS,生成 CSSOM
  3. DOM 树和 CSSOM 树结合,生成渲染树Render Tree
    • 从DOM树的根节点开始遍历每个可见节点,就是除了 display:none 的节点
    • 对于每个可见的节点,找到 CSSOM 树中对应的内容,使用 css 样式
    • 组合生成渲染树
  4. 根据生成的渲染树,进行回流 Layout 运行布局,计算每个节点的几何图形,得到节点的几何信息(位置,大小)
  5. 重绘 painting,根据 渲染树 以及 回流得到的几何信息,得到节点的绝对像素
  6. GPU 将各个节点绘制到屏幕上

在这里插入图片描述

回流 / 重绘

  • 回流
    • 指的是浏览器必须重新计算元素的大小和位置等布局信息,并根据新的布局信息重新布局页面的过程
      1. 添加或删除可见的DOM元素
      2. 元素的位置发生变化
      3. 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
      4. 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
      5. 页面一开始渲染的时候(这肯定避免不了)
      6. 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
    • 回流是一种相对耗费性能的操作,可能会导致全局的重新布局。
  • 重绘
    • 指的是浏览器对页面进行重新绘制的过程,这个过程是根据元素在页面上的显示位置、边框、背景等样式属性进行的
    • 重绘则比较快捷,仅涉及到样式的变化,不会触及页面的布局信息。

注意:回流一定重绘,但是重绘不一定回流

属性
display: none脱离文档流回流,重绘
visibility: hidden占据文档流重绘
opacity: 0占据文档流重绘,若是动画,则不发生回流重绘
position: absolute脱离文档流回流,重绘
clip-path: circle(0%)占据文档流重绘
减少回流重绘
  • style 样式操作使用 class 切换 或者 style.cssText 一次性替换

  • 批量修改 DOM

    1. 使元素脱离文档流 ,例如 display: none,定位之类的
    2. 对其进行多次修改
    3. 将元素带回到文档中
  • 动画效果使用 绝对定位 , 脱离文档流

  • transformopacityfilters 这些动画不会引起回流重绘

clip-path

clip-path 是裁剪属性,可以将元素裁剪为指定的形状,使得元素只显示裁剪区域的内容,隐藏裁剪外的元素。

clip-path: circle(0) 也可以做到隐藏元素。

裁剪工具网站: https://bennettfeely.com/clippy/

常用函数

/* 圆形:半径50%,x位置50%,y位置50% */
clip-path: circle(50% at 50% 50%);

/* 椭圆: x半径25%, y半径25%,位置同上 */
clip-path: ellipse(50% 25% at 50% 50%);

/* 多边形:每一组数据代表一个x,y坐标点 */
clip-path: polygon(25% 0%, 100% 25%, 75% 100%, 0% 75%);

/* 内嵌裁剪区域:上、右、下、左, 圆角效果,上右下左。 可以简写 */
clip-path: inset(20px 40px 60px 80px round 15px);

/* 定义任意形状(使用一个可选的 SVG 填充规则和一个 SVG 路径定义) */
clip-path: path('M 100 0 Q 200 100 Q 100 200, 0 100');

cubic-bezier 贝塞尔曲线

贝塞尔曲线是计算机图形学中一个非常有用的工具,它可以用来创建平滑的曲线,而不是直线,在 CSS 中可以使用贝塞尔曲线来 创建复杂的形状,定义 动画的速度曲线

由四个点构成,只需要关注 P1P2 两点的取值

P0:默认值 (0, 0)
P1:动态取值 (x1, y1)
P2:动态取值 (x2, y2)
P3:默认值 (1, 1)

最直接的理解是,将以一条直线放在范围只有 1 的坐标轴中,并从中间拿出两个点来拉扯(X 轴的取值区间是 [0, 1],Y 轴任意),最后形成的曲线就是动画的速度曲线。

语法:

cubic-bezier(x1,y1,x2,y2)

使用:

  • X 轴的取值范围是 0 ~ 1,当取值超出范围时 cubic-bezier 将失效
  • Y 轴的取值没有规定
transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1);

调试网站: https://cubic-bezier.com/#.17,.67,.83,.67

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值