【每日一学】CSS这些使用原理掌握了吗

avatar
前端解决方案集 @华为

DevUI是面向企业中后台产品的开源前端解决方案,其设计价值观基于高效、开放、可信、乐趣四种自然与人文相结合的理念,旨在为设计师、前端开发者提供标准的设计体系,并满足各类落地场景,是一款企业级开箱即用的产品。快来🔥 加入我们吧~

感谢我们的DevUI社区贡献者徐挽月提供的优质文章!

css原理第一期

一、css背景

20 世纪 90 年代蒂姆·伯纳斯·李(Tim Berners-Lee)发明万维网,创造 HTML 超文本标记语言。此后网页样式便以各种形式存在,不同的浏览器有自己的样式语言来控制页面的效果,因为最原始的 Web 版本中根本没有提供一种网页装饰的方法。

在HTML迅猛发展的 90 年代,不同的浏览器根据自身的 HTML 语法结构来支持实现不同的样式语言。在最初的 HTML 版本中,由于只含有很少的显示属性,所以用户可以自己决定显示页面的方式。

background-1.png

但随着 HTML 的发展,HTML 增加了很多功能,代码也越来越臃肿,HTML 就变得越来越难以管理。网页失去了语义化,维护代码很艰难,代码也变得越来越混乱:

background-2.png

于是装饰网页样式的 CSS(层叠样式表,Cascading Style Sheets)诞生了。

background-3.png

W3C:World Wide Web Consortium(万维网联盟),创建于1994年,是目前Web技术领域,最具影响力的技术标准机构。共计发布了200多项技术标准和实施指南,对互联网技术的发展和应用起到了基础性和根本性的支撑作用,官网:www.w3.org

二、css选择器以及三大特性

1.常见选择器

1.1 常见选择器
常见选择器特点用法
通配选择器选中所有标签,一般用于清除样式*{}
元素选择器选中所有同种标签,但是不能差异化选择标签名{}
类选择器选中所有特定类名( class 值)的元素.类名{}
id选择器选中特定 id 值的那个元素(唯一)#id{}
并集选择器选中多个选择器对应的元素选择器1,选择器2{}
交集选择器选中同时符合多个条件的元素选择器1选择器2{}
1.2 组合器
组合器特点用法
后代选择器选中指定元素中,符合要求的所有后代元素选择器1 选择器2{}
子选择器选中指定元素中,符合要求的第一代子元素选择器1>选择器2{}
相邻兄弟选择器选择指定元素后相邻且紧挨着的兄弟结点选择器1+选择器2{}
通用兄弟选择器查找指定元素的后面的所有兄弟结点选择器1~选择器2{}
1.3 属性选择器
  1. [属性名] 选中具有某个属性的元素
  2. [属性名="值"] 选中包含某个属性,且属性值等于指定值的元素
  3. [属性名^="值"] 选中包含某个属性,且属性值以指定的值开头的元素
  4. [属性名$="值"] 选中包含某个属性,且属性值以指定的值结尾的元素
  5. [属性名*=“值”] 选择包含某个属性,属性值包含指定值的元素
1.4 伪类
1.4.1 结构伪类
  1. :first-child 所有兄弟元素中的第一个
  2. :last-child 所有兄弟元素中的最后一个
  3. :nth-child(n) 所有兄弟元素中的第 n 个
  4. :first-of-type 所有同类型兄弟元素中的第一个
  5. :last-of-type 所有同类型兄弟元素中的最后一个
  6. :nth-of-type(n) 所有同类型兄弟元素中的 第n个
  7. :not(选择器) 排除满足括号中条件的元素
1.4.2 动态伪类
  1. :link 未访问前的样式效果
  2. :visited 访问后的样式效果
  3. :hover 鼠标移动到元素上面时的样式效果
  4. :active 单击元素时的样式效果
  5. :focus 元素成为焦点时的样式效果
1.5 伪元素
  1. ::first-letter 选中元素中的第一个文字
  2. ::first-line 选中元素中的第一行文字
  3. ::selection 选中被鼠标选中的内容
  4. ::placeholder 选中输入框的提示文字
  5. ::before 在元素最开始的位置,创建一个子元素(必须用 content 属性指定内容)
  6. ::after 在元素最后的位置,创建一个子元素(必须用 content 属性指定内容)
<style>
    div::first-letter {
        color: red;
        font-size: 40px;
    }
    div::first-line {
        background-color: yellow;
    }
    p::before {
        content: "¥";
    }
    p::after {
        content: ".00"
    }
</style>
<body>
    <div>
        第一段<br>
        第二段
    </div>
    <br>
    <p>100</p>
    <p>200</p>
    <p>300</p>
</body>

页面效果:

pseudoElement.png

2.三大特性

characteristics-1.png

下面我们来看一个层叠性原理的案例:

<style>
    div {
        background: yellow;
        color: blue;
    }

    div {
        font-size: 20px;
        color: red;
    }
</style>
<body>
    <div class="box">文本内容</div>
</body>

characteristics-6.png

上述案例中选择器相同都为div,其中的background和font-size属性没有冲突,因此会进行叠加,而color属性会冲突,根据覆盖规则,后面声明的属性会覆盖前面声明的属性,因此文本内容会呈现红色

css1.webp

下面我们来看一个继承性的案例:

<style type="text/css">
    .box {
        width: 700px;
        border: 1px solid red;
        color: red;
        text-align: center;
        font-size: 14px;
    }

    .box p {
        background-color: khaki;
        font-size: 20px;
    }
</style>
<body>
    <div class="box">
        <p>文字颜色红色和文字水平居中,都是继承于父元素box的</p>
    </div>
</body>

characteristics-4.png

上述案例父元素box中的width和border无继承性,color、text-align和font-size属性有继承性,但是由于子元素中也设置了font-size属性,因此子元素不会再继承父元素的font-size

如果想要不可被继承的属性也能被子元素继承,可以给子元素的属性设置为inherit

<style type="text/css">
    .box {
        width: 700px;
        border: 1px solid red;
        color: red;
        text-align: center;
        font-size: 14px;
    }

    .box p {
        background-color: khaki;
        font-size: 20px;
        /* 给子元素border设置为inherit */
        border: inherit; 
    }
</style>
<body>
    <div class="box">
        <p>文字颜色红色和文字水平居中,都是继承于父元素box的</p>
    </div>
</body>

characteristics-5.png

给子元素border属性设置为inherit,之后便可以继承父元素的border

css3.webp

下面我们来看一个优先级的案例:

<style>
    #box1 #box2 p {
        color: red;
    }
    #box1 div.box2 #box3 p {
        color: green;
    }
    .box1 .box2 .box3 p {
        color: blue;
    }
</style>
<body>
    <div class="box1" id="box1">
        <div class="box2" id="box2">
            <div class="box3" id="box3">
                <p>标签</p>
            </div>
        </div>
    </div>
</body>

characteristics-7.png

根据上面给出的优先级表格,可以计算出代码中三种不同的优先级分别为:

  • #box1 #box2 p 优先级0201
  • #box1 div.box2 #box3 p 优先级0212
  • .box1 .box2 .box3 p 优先级0031

其中 #box1 div.box2 #box3 p 的优先级最高,因此最终字体颜色会呈现出绿色

三、盒子模型

在开始介绍盒子模型之前,我们先来了解下显示类型以及布局元素

1.display属性

display 属性可以设置元素显示类型,其中显示类型分为外部显示类型和内部显示类型,今天第一期的内容主要针对外部显示类型进行展开

1.1 外部显示类型:
  1. 元素的外部显示类型有 block 块、inline 内联等
  2. 外部显示类型将决定该元素在流式布局中的表现
1.2 内部显示类型:
  1. 内部显示类型flex 布局、grid 网格布局、流式布局等
  2. 元素的内部显示类型可以控制其子元素的布局方式

2. 外部显示类型

css5.PNG

3. 布局元素

box-2.png

接下来我们用一个案例来展示下不同布局元素之间的特点

<style>
    p {
        background-color: skyblue;
    }
    div {
        width: 400px;
        height: 50px;
        background-color: tomato;
    }
    span {
        width: 400px;
        height: 50px;
        background-color: yellow;
    }
</style>
<body>
    <p>p标签为块级元素,独占一行,默认宽度同父元素宽一样</p>
    <div>div是块级元素,独占一行,同时支持宽高设置</div>
    <span>span元素是内联元素,宽高由内容决定,不支持宽高属性1111111111111111</span>
</body>

box-3.png

不同布局元素之间也可以互相转换:
使用 display: block; 可将元素转换为块级元素
使用 display: inline; 可将元素转换为行内元素
使用 display: inline-block; 可将元素转换为行内块元素

4. 盒子模型

4.1 盒子模型的组成

css6.PNG

  1. margin(外边距): 盒子与外界的距离
  2. border(边框): 盒子的边框
  3. padding(内边距):边框内壁到内容之间的距离
  4. content(内容):元素中的文本或后代元素都是它的内容
4.2 盒模型类型
  • 标准盒模型:盒子模型的 content 部分就是元素的 width 和 height 属性组成的矩形部分
  • IE盒模型(怪异盒模型): 盒子的 width 和 height 包含了 padding 和 border
  • 注:可以通过box-sizing修改为content-box(标准盒模型)、border-box(IE盒模型)
4.3 盒模型外边距常见问题以及解决方案
4.3.1 父子元素之间,垂直方向上外边距塌陷

当一个元素包含在另一个元素中时,如果父元素没有设置内边距或边框把外边距分隔开,它们的上外边距会发生塌陷

<style>
    .father {
        width: 100px;
        height: 100px;
        background-color: gold;
        margin-top: 20px;
    }

    .son {
        width: 50px;
        height: 50px;
        background-color: skyblue;
        margin-top: 50px;
    }
</style>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

页面效果:

子元素上边距穿透了父元素,并与父元素的上边距发生塌陷(合并)
在页面上显示的间距并不是 父元素 与 子元素 的间距,而是 父元素 与浏览器上面产生了 50px 的间距

box-5.png

解决办法:

  1. 给父元素添加属性触发BFC,BFC可以形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素,常见触发BFC的方法有:

  • float设置为除了none以外的值

  • position设置为absolute或者fixed

  • display设置为inline-block, table-cell, table-caption, flex, inline-flex

  • overflow设置为除visible以外的值

  1. 给父元素设置外边框(border)或者内边距(padding)
  2. 将子元素的 margin 改成 padding(背景颜色属性会覆盖内边距)
4.3.2 兄弟元素之间 ,垂直方向上下外边距出现塌陷

兄弟元素垂直方向上下外边距重合时小的margin会出现塌陷,最终只有大的margin生效

<style>
    .brother {
        width: 200px;
        height: 100px;
    }

    .brother1 {
        background-color: blue;
        margin-bottom: 100px;
    }

    .brother2 {
        background-color: red;
        margin-top: 50px;
    }
</style>

<body>
    <div class="brother brother1"></div>
    <div class="brother brother2"></div>
</body>

页面效果:

兄弟元素之间发生的塌陷,小的margin会塌陷到大的margin中,最终呈现出来的只有大的margin,即100px

box-6.png

解决办法:

  1. 任何一个元素加上 display:inline-block
  2. 把外边距只加在其中一个元素上
  3. 任意一个元素外边距换成对应的 padding

参考文献:

🔥 加入我们

DevUI是面向企业中后台产品的开源前端解决方案,其设计价值观基于高效、开放、可信、乐趣四种自然与人文相结合的理念,旨在为设计师、前端开发者提供标准的设计体系,并满足各类落地场景,是一款企业级开箱即用的产品。

如果你今天刚刚加入我们,可以先看看官网上的示例组件,你可以在左侧导航栏中切换想要查看的组件,然后通过右侧的快速前往在不同Demo之间切换。

如果你准备添加 Vue DevUI,请前往快速开始文档,只需要几行代码。

如果你对我们的开源项目感兴趣,并希望参与共建,欢迎加入我们的开源社区,关注DevUI微信公众号:DevUI 。

文 / DevUI社区贡献者 徐挽月