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 {
/* ... */
}
属性无值 -> 确定声明值 -> 层叠冲突 -> 使用继承 -> 使用默认值 -> 结果
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;
}
让 单行文本 在容器内居中,重点在于让文字纵向居中。只需要让文字行高 (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>呵呵
大多数可以写尺寸的地方都可以写百分比。参考系为:
position: absolute;
) 的元素的参考系是父元素中 第一个定位元素的 padding+content 区域常见的标签上百分比的参考系:
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 不起作用。给父元素加个 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 定位相对于有定位 (设置了 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)));
}
<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>
。