HTML CSS 相关 

Last Update: 2024-06-03

目录

CSS 权重计算

CSS 权重 (256 进制):

!important          Infinity
行内样式              1000
id                   100
class|属性|伪类        10
标签选择器|伪元素        1
通配符                  0

浏览器会将所有 CSS 并列选择器的权重相加来确定生效的样式:

注: 权重相同,靠后的生效。

/*
<div class="cls1" id="id1">
  <p class="cls2" id="id2">tt</p>
</div>
*/

/* 100 + 1 = 101 */
#id1 p { background-color: red; }

/* 10 + 10 = 20 */
.cls1 .cls2 { background-color: green; }

/* 101 > 20 */
/* 最后结果是 red */
/*
<div class="cls1" id="id1">
  <p class="cls2" id="id2">tt</p>
</div>
*/

/* 100 + 1 = 101 */
#id1 p { background-color: red; }

/* 10 + 10 + Infinity = 20 + Infinity */
.cls1 .cls2 { background-color: green!important; }

/* 101 < 20 + Infinity */
/* 最后结果是 red */
/* 
<a style="text-decoration: overline;" href="baidu.com">baidu.com</a>
*/

/* 1 (来自标签选择器) + 1 (来自 :hover 这个伪类选择器) */
a:hover{
  text-decoration: none;
}

/* 1000 (来自 a 标签的行内样式) > 2 */
/* 所以 a 标签总是带上划线 */

浏览器自右向左检索 (即从 DOM 树的叶子节点向根节点搜索) 标签:

/* em -> a -> li -> ul -> div */
div ul li a em {
    /* ... */
}

CSS 属性值计算过程

属性无值 -> 确定声明值 -> 层叠冲突 -> 使用继承 -> 使用默认值 -> 结果

CSS 属性

font-size 设置的是字体的高。vertical-align 可以调整文本在行内的纵向相对位置。

opacity 是透明度值取 0-1,对对容器内的所有元素生效。alpha 通道 rgba 只对它所在的元素生效。

凡带有 display: inline; 的元素都有文本特性。多个 img 标签写在多行的话,从浏览器可以看到图片间有间隙,可以在调试阶段用 margin-left: 4px; 去除间隙。但把多个 img 标签写在一行,从浏览器看图片就没有间隙,此时就要把 margin-left 去掉,否则图片会有 4px 的重合。因为 .html 文件中,文本换行后,浏览器会为在存在换行的文本间添加文本分隔符,图片的间隙就是由这个文本分隔符产生的。

padding 和 margin 有三个值时,代表 , 左右, ;两个值代表 上下, 左右

<del> 标签的视觉效果可以用 <span> 标签做出来:

span {
  text-decoration: line-through;
}

<a> 标签的视觉效果可以用 <span> 标签做出来:

span {
  color: rgb(0, 0, 238);
  text-decoration: underline;
  cursor: pointer;
}

CSS 技巧

单行文本居中

单行文本 在容器内居中,重点在于让文字纵向居中。只需要让文字行高 (line-height) 等于容器高度 (height) 即可。

首行缩进

首行缩进,让段落缩进 2em (text-indent: 2em;)。 1em = 1 font-size

文本底对齐

inline-block 内如果有文本,那么 inline-block 外的文本和 inline-block 内的文本底对齐。inline-block 内如果没有文本,那么 inline-block 外的文本和 inline-block 的底对齐。

和 inline-block 内的文本对齐:

<style>
  span{
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: yellow;
  }
</style>
<span>对齐</span>呵呵

和 inline-block 的底对齐:

<style>
  span{
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: yellow;
  }
</style>
<span></span>呵呵

元素永远和文本底对齐:

<style>
  .dd {
    text-decoration: none;
    display: inline-block;
    width: 100px;
    height: 100px;
    display: inline-block;
    background-color: green;
  }
</style>
<div class="dd"></div>

<style>
  span{
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: yellow;
  }
</style>
<span>对齐</span>呵呵
<style>
  .dd {
    text-decoration: none;
    display: inline-block;
    width: 100px;
    height: 100px;
    display: inline-block;
    background-color: green;
  }
</style>
<div class="dd">对齐2</div>

<style>
  span{
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: yellow;
  }
</style>
<span>对齐</span>呵呵

元素的尺寸

大多数可以写尺寸的地方都可以写百分比。参考系为:

常见的标签上百分比的参考系:

css属性百分比相对于备注
width参考系的宽度
height参考系的高度参考系高度受本身宽度影响时,设置无效
padding参考系的宽度
border参考系的宽度
margin参考系的宽度

当一个元素的尺寸会自动变化时,设置最大最小宽高,可以让它不至于变得过小或过大。

通常用来为 PC 端的页面设置一个最小宽度 html { min-width: 1226px; },通常此宽度为设计稿的宽度;为页面中的所有图片设置一个最大宽度 img { max-width: 100%; } 让其不至于溢出容器。

让并列的图片没有间隙

这样的写法会让图片间有间隙:

<style>
  img {
    width: 100px;
  }
</style>
<img src="pic.jpg">
<img src="pic.jpg">
<img src="pic.jpg">

所有的 img 标签都是 inline-block 元素。inline 和 inline-block 元素都是文本类元素。文本类元素间的空格和换行都会被处理成文本分隔符。所以,多个 img 标签间的换行符被浏览器处理成了文本分隔符,从而有了间隙。只要把所有 img 标签写在一行,让浏览器不向 img 标签间加入文本分隔符,间隙就没有了:

<style>
  img {
    width: 100px;
  }
</style>
<img src="pic.jpg">
<img src="pic.jpg">
<img src="pic.jpg">

用超链接图片代替超链接文本

这个要求的重点在于如何让 .css 不被加载时还能有超链接用。核心的做法是让 a 标签的文本在 a 标签的空间之外,然后隐藏文本。

这是第一种思路,用 text-indent 让文本出界:

<style>
  .tb {
    text-decoration: none;
    display: inline-block;
    width: 100px;
    height: 100px;
    background-image: url(pic.png);
    background-size: 100px 100px;

    /* 通过 indent a 标签的宽度让文本处于 a 标签的空间之外 */
    text-indent: 100px;
    /* 让文本在遇到边界时不自动换行,一换行就又有文本回到 a 标签的空间中了 */
    white-space: nowrap;
    /* 隐藏 a 标签空间外的内容 */
    overflow: hidden;
  }
</style>
<a class="tb" href="taobao.com" target="_blank">淘宝</a>

第二种思路,用 a 标签的 padding-top 让文本出界:

<style>
  .tb {
    text-decoration: none;
    display: inline-block;
    width: 100px;
    /* 不算 border,标签的高度为内边框 padding + 内容高度 height */
    /* 在这里 a 标签的行高 = 内容的行高 = line-height */
    /* 但加了 height: 0px; 的话,内容高度就直接取 0 了 */
    /* 没有下面这行的话,a 标签高度就会加上一个实际内容的高度 */
    height: 0px; 
    background-image: url(pic.png);
    background-size: 100px 100px;

    /* 给 a 标签加一个等于其高度的 padding-top 让文本出界 */
    padding-top: 100px;
    /* 隐藏 a 标签空间外的内容 */
    overflow: hidden;
  }
</style>
<a class="tb" href="taobao.com" target="_blank">淘宝</a>

给单行文字的溢出部分加省略号

注: 下面这个写法只能给单行文字的溢出部分加省略号。多行文字的溢出部分只能截断。

<style>
  .pdemo {
    width: 100px;
    height: 20px;
    line-height: 20px;
    border: 1px solid black;
    white-space: nowrap; /* 遇到边界不换行 */
    overflow: hidden; /* 隐藏溢出容器的子元素 */
    text-overflow: ellipsis; /* 隐藏溢出父容器的文本 */
  }
</style>

<p class="pdemo">让单行文本在容器内居中,重点在于让文字纵向居中。只需要让文字行高 (line-height) 等于容器高度 (height) 即可。</p>

margin 合并

两个相邻的元素 (兄弟或父子) 之间如果没有非空内容,它们的 margin 空间会被共享。

父子元素在垂直方向上的 margin 会粘合在一起,纵向上的父元素的 margin 取父子 margin 的最大值,子元素在纵向上的 margin 不起作用。给父元素加个 border 可以规避该问题。BFC 也可以规避该问题。

触发盒子的 BFC:

position: absolute;
display: inline-block;
float: left/right;
overflow: hidden;

类似地,两个互为兄弟元素的 div 的 margin 也会合并,浏览器从 div1 的 margin-bottom 和 div2 的 margin-top 中取大的作为两个 div 的距离。规避方式也是 BFC。只要将两个 div 其中之一放进使用了 BFC 的容器中即可。将两个 div 都放进使用了 BFC 的容器中也行。

浮动和定位

position: absolute;float: left/right; 会让元素的 display 属性变为 inline-block。有了 inline-block 属性的元素就从行内元素变成了行内块元素 (就可以设置宽高了)。position: relative; 没有这个效果。

浮动元素

float: left/right; 可以让元素浮动。 浮动元素产生了浮动流,所有产生了湲流的元素,块级元素看不到它们。产生了 BFC 的元素和有文本类属性 (inline) 的元素能看到它们。 给一个例子:

<!-- demo1 demo2 重合 -->
<style>
  .demo1 {
    float: left;
    width: 100px;
    height: 100px;
    background-color: red;
    opacity: 0.5;
  }
  .demo2 {
    width: 150px;
    height: 150px;
    background-color: blue;
  }
</style>
<div class="demo1"></div>
<div class="demo2"></div>

<!-- demo3 和 demo4 重合,但 demo4 的 ddd 紧跟在 demo3 右侧 -->
<style>
  .demo3 {
    float: left;
    width: 100px;
    height: 100px;
    background-color: red;
    opacity: 0.5;
  }
  .demo4 {
    width: 150px;
    height: 150px;
    background-color: blue;
  }
</style>
<div class="demo3"></div>
<div class="demo4">ddd</div>

父级元素包住子浮动元素

浮动元素产生了浮动流,所有产生了湲流的元素,块级元素看不到它们。 所以解决问题的核心在于让父级元素看到子元素。要么清除子元素的浮动流,要么给父元素加上 BFC。

要让父级元素的尺寸包住其中的浮动子元素,可以在子元素的末尾加上一个用于清除浮动流的 p 标签:

<style>
  .wrapper {
    border: 1px solid black;
  }
  .content {
    width: 100px;
    height: 100px;
    background-color: green;
    color: #fff;
    float: left;
  }
  .clear {
    clear: both;
  }
</style>
<div class="wrapper">
  <div class="content">1</div>
  <div class="content">2</div>
  <div class="content">3</div>
  <p class="clear"></p>
</div>

但最好用伪元素 (伪元素天生是 inline 元素) 来清除浮动流:

<style>
  .wrapper {
    border: 1px solid black;
  }
  .content {
    width: 100px;
    height: 100px;
    background-color: green;
    color: #fff;
    float: left;
  }
  .wrapper::after {
    clear: both;
    content: '';
    display: block; /* clear 只能作用于块级元素 */
  }
</style>
<div class="wrapper">
  <div class="content">1</div>
  <div class="content">2</div>
  <div class="content">3</div>
</div>

给父元素加 BFC 的方法前文提过,不再重复。

absolute 和 relative 定位

absolute 定位导致元素失去其原本所占空间,relative 定位保留其原本所占的空间。absolute 定位相对于有定位 (设置了 position) 的父级元素来定位,如果没有这样的父级元素则相对于文档来定位。relative 定位相对于元素原来的位置定位。一般将父级盒元素设为 relative 元素 (或用 fixed 来相对可视区域定位),子元素用 absolute 对父级 relative 元素定位。比如这是一个在屏幕正中画五环的代码:

<style>
  .wrapper {
    position: fixed;
    width: 400px;
    height: 170px;
    left: 50%;
    top: 50%;
    margin: -85px 0px 0px -200px;
  }
  .circle1,
  .circle2,
  .circle3,
  .circle4,
  .circle5 {
    position: absolute;
    width: 100px;
    height: 100px;
    border: 10px solid;
    border-radius: 50%;
  }
  .circle4,.circle5{ z-index: 1; }
  .circle1{
    border-color: blue;
  }
  .circle2{
    border-color: black;
    left: 140px;
    z-index: 2;
  }
  .circle3{
    border-color: red;
    left: 280px;
  }
  .circle4{
    border-color: yellow;
    left: 70px;
    top: 50px;
  }
  .circle5{
    border-color: green;
    left: 210px;
    top: 50px;
  }
</style>
<div class="wrapper">
  <div class="circle1"></div>
  <div class="circle2"></div>
  <div class="circle3"></div>
  <div class="circle4"></div>
  <div class="circle5"></div>
</div>

渐变背景

.box {
  width: 400px;
  aspect-ratio: 1.6;
  /* 
  no-repeat: 背景图片在元素内不重复平铺
  center center: 背景图在水平和垂直方向上相对于元素的中心对齐。背景图片将水平和垂直居中放置在元素内
  /: CSS3 的语法,用于分隔背景图片的位置和大小
  cover: background-size 关键的字值,用于指定背景图片应该被放大或缩小以填充整个背景区域。图片可能会被剪裁以保持纵横比
  */
  background: url('https://fileshare.lishouzhong.com/lorem_picture_1.jpg') no-repeat center center/cover;
  /* border: 2px solid violet; */
  margin: 2em auto;
  position: relative;
  --x: 15px;
  --y: 15px;
}

.box::after {
  content: '';
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 100%;
  height: 100%;
  filter: blur(5px);
  background: conic-gradient(red 0deg, orange 90deg, yellow 180deg, green 270deg, violet);
  z-index: -1;
  clip-path: polygon(-100vmax -100vmax,
      100vmax -100vmax,
      100vmax 100vmax,
      -100vmax 100vmax,
      -100vmax -100vmax,
      calc(0px - var(--x)) calc(0px - var(--y)),
      calc(0px - var(--x)) calc(100% - var(--y)),
      calc(100% - var(--x)) calc(100% - var(--y)),
      calc(100% - var(--x)) calc(0px - var(--y)),
      calc(0px - var(--x)) calc(0px - var(--y)));
}

HTML 规则

行级元素只能套行级元素

<p><div></div></p> 中,浏览器处理的结果是 <p></p><div></div><p></p>,即 p 标签被 div 截成了两部分。但 span 标签套 div 浏览器的处理结果正常。

a 标签内不能套 a 标签。<a>ddd<a>fff</a></a> 会被处理成 <a>ddd</a><a>fff</a>