margin负值对布局的影响
在文档流中,元素的最终边界是由margin决定的,margin为负的时候就相当于元素的边界向里收,文档流认的只是这个边界,不会管你实际的尺寸是多少。
在文档流中,如果元素前面的元素设置了负margin,则他会以流的形式跟上去。所以将元素都设置负margin后,就会产生覆盖。
margin设置移动时的参考:margin的参考线有两类,一类是top、left,它们以外元素作为参考线,使自己移动。另一类是right、bottom,它们以自身作为参考线。让兄弟元素移动
总地来说,就是当margin-top、left为负值的时候与参考线的距离减少,当margin-right、bottom为负值的时候参考线(不是本身,是相隔的那个)就向左、上面移动。
表现
虽然margin可以应用到所有元素,但display属性不同时,表现也不同
-
block元素可以使用四个方向的margin值
-
inline元素使用上下方向的margin值无效
<style> * { margin: 0; padding: 0; } span { border: 1px solid black; margin: 100px; } </style> <span>inline上下的margin是无效的</span> -
inline-block使用上下方向的margin负值看上去无效
-
其中只是vertical-align:baseline / bottom是无效的,top / middle是有效的
<style> * { margin: 0; padding: 0; } input { margin-top: -100px; vertical-align: bottom; } </style> <input type="text" value="inline-block的上下margin负值是无效果的">
-
[注意]inline-block使用上下方向的margin负值只是看上去无效,这与其默认的vertical-align:baseline有关系,当垂直对齐的属性值为其他值时,则会显示不同的视觉效果
重叠
margin负值并不总是后面元素覆盖前面元素,它与元素display属性有关系
-
两个block元素重叠时,后面元素可以覆盖前面元素的背景,但无法覆盖其内容
* { padding: 0; margin: 0; } .top { width: 100px; height: 100px; background-color: yellow; } .bot { width: 100px; height: 100px; background-color: blue; margin-top: -100px; } </style> //这里的top不会被覆盖 <div class="top">top</div> <div class="bot"></div> -
当两个inline元素,或两个line-block元素,或inline与inline-block元素重叠时,后面元素可以覆盖前面元素的背景和内容
.st { background-color: yellow; opacity: .8; } .sb { background-color: blue; margin-left: -30px; opacity: .8; } </style> <div class="top">top</div> <div class="bot"></div> <span class="st">sttttttttttttttttt</span> <span class="sb">sbssssssssssssssssssss</span> -
当inline元素(或inline-block元素)与block元素重叠时,inline元素(或inline-block元素)覆盖block元素的背景,而内容的话, 后面的元素覆盖前面的元素
<style> span { background: red; margin-left: -5px; } div { background: blue; width: 100px; float: left; height: 100px; } </style> //浮动后span元素会在div后面,加上margin-left负值后,span覆盖div的内容和背景 <span>我是内联元素</span> <div>我是块级元素</div>
综上所述,个人理解,在普通流布局中,浏览器将页面布局分为内容和背景,内容的层叠显示始终高于背景。block元素分为内容和背景,而inline元素或inline-block元素,它本身就是内容(包括其背景等样式设置)
当元素都浮动时
-
全部设置margin负值时,会正常移动元素,但是相互浮动的元素会覆盖一部分浮动的元素
-
这里并不是我们想的那样,如果将若干元素都设置同样的margin,他们都移动相同的距离,但是还是会相互遮盖
<style> div { border: 1px solid black; margin-top: -50px; width: 200px; height: 200px; } </style> <div class="box1">1</div> <div class="box2">2</div> <div class="box3">3</div> -
如果只给浮动元素的一个元素加负的margin,则他会向内联一样
<style> div { float: left; width: 100px; height: 100px; background: red; } div:nth-child(1) { background: blue; } div:nth-child(2) { background: green; margin-left: -10px; } </style> <div class="box1">1</div> <div class="box2">2</div> <div class="box3">3</div>
定位元素
-
对于相对定位,通过margin的值偏移,该元素原来的位置会空出来,但是通过left等偏移,该元素原来的位置依然存在
-
但是绝对定位元素就不同了,他将所有定位元素都加上一样的负margin,那么将是整体移动,不会彼此遮盖
```
<style>
* {
margin: 0;
padding: 0;
}
div {
border: 1px solid black;
position: absolute;
width: 200px;
height: 200px;
}
.box2 {
left: 200px;
margin-left: -100px;
}
.box3 {
left: 400px;
margin-left: -100px;
}
</style>
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3</div>
```
对自身的影响
-
当元素不存在width属性或者(width:auto)的时候,负margin会增加元素的宽度。
<style> .container { margin: 0 auto; width: 500px; border: 1px #ccc solid; margin-bottom: 20px; } .box1 { margin-left: -20px; /* margin-bottom: -100px; */ } </style> <div class="container"> //box1不设置宽度或者width: auto;这样设置margin负值就可以增加他的宽度 <div class="box1"> I dont have the width </div> </div>
对内联元素
-
如果只改变一个内联元素的margin为负值,紧跟其后的所有连续的内联元素,也会移动,不会改变布局
<style> * { margin: 0; } .box2 { margin-left: -20px; background: red; } span { border: 1px solid black; } </style> <span class="box1">1111</span> <span class="box2">2222</span> <!-- <div>0000</div> --> <span class="box3">3333</span>
双飞翼布局
-
将中间的布局放在最前面,因为我们利用margin负值会覆盖他前面的元素,而中间的元素宽度最大,刚好被覆盖。
-
左边的布局margin-left: -100%;
-
右边的布局marfin-left: -自身宽度
-
将中间元素用一个div包裹,使中间内容不被覆盖,设置子元素margin,来撑开与父元素的距离则可以做到。
<style> * { padding: 0; margin: 0; } .content { margin: 10px; } .left { width: 300px; height: 200px; float: left; background: red; margin-left: -100%; } .middle { height: 200px; background: blue; /* 这个表示距离父元素的距离 */ margin: 0 310px; } .content-main { width: 100%; float: left; } .right { width: 300px; height: 200px; float: left; background: skyblue; margin-left: -300px; } </style> <div class="content"> <div class="content-main"> <div class="middle"></div> </div> <div class="left"></div> <div class="right"></div> </div>
圣杯布局
-
布局和双飞翼相同,但是避免中间的元素内容被覆盖,需要设置padding来使内容在中间显示,而不被覆盖。
<style> * { margin: 0; padding: 0; } /* .content { padding: 0 310px; } */ .left { width: 300px; height: 200px; float: left; background: red; margin-left: -100%; /* position: relative; left: -310px; */ } .middle { width: 100%; height: 200px; float: left; box-sizing: border-box; padding: 0 310px 0 310px; background: blue; } .right { width: 300px; height: 200px; float: left; background: skyblue; margin-left: -300px; /* position: relative; right: -310px; */ } </style> <div class="content"> <div class="middle">333333333333</div> <div class="left"></div> <div class="right"></div> </div>
圣杯和双飞翼异同
圣杯布局和双飞翼布局解决的问题是一样的,都是两边定宽,中间自适应的三栏布局,中间栏要在放在文档流 前面以优先渲染。
-
两种方法基本思路都相同:首先让中间盒子 100% 宽度占满同一高度的空间,在左右两个盒子被挤出中间盒子所在区域时,使用 margin-left 的负值将左右两个盒子拉回与中间盒子同一高度的空间。接下来进行一些调整避免中间盒子的内容被左右盒子遮挡。
-
主要区别在于 如何使中间盒子的内容不被左右盒子遮挡:
- 圣杯布局的方法:设置父盒子的 padding 值为左右盒子留出空位,再利用相对布局对左右盒子调整位置占据 padding 出来的空位;
- 双飞翼布局的方法:在中间盒子里再增加一个子盒子,直接设置这个子盒子的 margin 值来让出空位,而不用再调整左右盒子。
简单说起来就是双飞翼布局比圣杯布局多创建了一个 div,但不用相对布局了,少设置几个属性。
等高布局
-
利用flex
-
利用table-cell,将每一列都设置display:table-cell;但是有关table的都不可以设置margin属性
-
利用margin-bottom负值和padding-bottom正值
- margin-bottom负值是让父元素可以在子元素下边距之上,可以让padding-bottom增加的内容溢出。然后在使用overflow:hidden来将其隐藏。
- padding-bottom正值是增加子元素的内容高度,来弥补margin-bottom负值引起的父元素在子元素之上。并且视觉上仍然可以显示子元素内容高度增加。
盒子模型的经典问题
margin叠加问题:
-
兄弟元素之间设置的margin-top,margin-bottom,如果有一个设置为负margin,那么它会把正值和负值计算后的值设置为margin,如果两个值都是负值,那么取那个较小的负值。
-
父子元素的叠加,由于子元素的margin-top,margin-bottom会传递给父元素,就会与父元素自己设置的margin进行叠加成一个较大的margin,忽略那个较小的margin值
margin传递问题
margin-top的传递。如果块级元素的顶部线和父元素的顶部线重叠,那么这个块级元素的margin-top值会传递给父元素。如果顶部不重叠就不会出现这种情况
<style>
div:nth-child(1) {
background: red;
width: 100px;
height: 100px;
margin-bottom: -20px;
overflow: hidden;
}
div:nth-child(2) {
background: blue;
width: 100px;
height: 100px;
margin-top: -10px;
opacity: 0.5;
}
</style>
//间距为-20px
<div>1</div>
<div>2</div>
margin-bottom的传递。如果块级元素的底部线和父元素的底部线重叠,并且父元素的高度是auto,那么这个块级元素的margin-bottom值会传递给父元素。
解决方法:
- 给父元素设置padding-top\padding-bottom
- 给父元素设置border
- 触发BFC,给父元素设置overflow: auto / hidden / scroll
一般来讲:margin一般是用来设置兄弟元素之间的间距。
padding一般是设置父子元素之间的间距。
居中布局
- Centering in CSS: A Complete Guide:非常全面的居中定位博客,包括各种情况下的水平居中,垂直居中和水平垂直居中方案。有展示示例及相应的 HTML 和 CSS 代码
文章大致结构:
-
水平居中
- 对于行内元素(inline)/内部是文字的块级元素/行内块元素(inline-block):给父元素设置
text-align: center; - 对于块级元素(block):设置宽度且
marigin-left和margin-right是设成 auto - 对于多个块级元素:对父元素设置
text-align: center;,对子元素设置display: inline-block;;或者使用 flex 布局。 - 对于任何元素,父元素设置flex,自己设置margin:auto。或者父元素设置
justify-content: center;
- 对于行内元素(inline)/内部是文字的块级元素/行内块元素(inline-block):给父元素设置
-
垂直居中
-
对于行内元素(inline)
- 单行:设置上下 pandding 相等;或者设置
line-height和height相等 - 多行:设置上下 pandding 相等;或者设置
display: table-cell;和vertical-align: middle;;或者使用 flex 布局;或者使用伪元素
- 单行:设置上下 pandding 相等;或者设置
-
对于块级元素(block):下面前两种方案,父元素需使用相对布局
- 已知高度:子元素使用绝对布局
top: 50%;,再用负的margin-top把子元素往上拉一半的高度 - 未知高度:子元素使用绝对布局
position: absolute; top: 50%; transform: translateY(-50%); - 使用 Flexbox:选择方向,
justify-content: center;
- 已知高度:子元素使用绝对布局
-
-
水平垂直居中
-
定高定宽:
- 先用绝对布局
top: 50%; left: 50%;,再用和宽高的一半相等的负 margin 把子元素回拉; - 先用绝对布局四个方向的偏移量都设置为0,然后设置margin:auto;
- 先用绝对定位,设置偏移量
top: calc(50% - 自身宽度的一半px); left: calc(50% - 自身宽度的一半50px);
- 先用绝对布局
-
高度和宽度未知:
- 先用绝对布局
top: 50%; left: 50%;,再设置transform: translate(-50%, -50%); - 通过给父元素设置line-height等于height,
tex-aligin: center,子元素设置display:inline-block,由于text-aligin会被继承,所以需要将子元素设置text-aligin:left来改变其水平显示。
- 先用绝对布局
-
使用 Flexbox:
justify-content: center; align-items: center; -
使用子元素绝对定位并且规定宽高,父元素相对定位。并且设置left, right, top, bottom为0.margin设置为auto;
width: 100px; height: 100px; background: red; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto;
-
writing-mode 属性
文本水平或垂直排布以及在块级元素中文本的行进方向。
属性值:
- horizontal-tb:对于左对齐(ltr)脚本,内容从左到右水平流动。对于右对齐(rtr)脚本,内容从右到左水平流动。下一水平行位于上一行下方。
- vertical-rl: 对于左对齐(ltr)脚本,内容从上到下垂直流动,下一垂直行位于上一行右侧。对于右对齐(rtr)脚本,内容从下到上垂直流动,下一垂直行位于上一行左侧。
- vertical-lr:对于左对齐(ltr)脚本,内容从上到下垂直流动,下一垂直行位于上一行右侧。对于右对齐(rtr)脚本,内容从下到上垂直流动,下一垂直行位于上一行右侧。
sideways-rl:对于左对齐(ltr)脚本,内容从左到右水平流动。对于右对齐(rtr)脚本,内容从右到左水平流动。所有字形(即使是垂直脚本中的字形)都朝向右侧。sideways-lr:对于左对齐(ltr)脚本,内容从上到下垂直流动。对于右对齐(rtr)脚本,内容从下到上垂直流动。所有字形(即使是垂直脚本中的字形)都朝向左侧。
响应式布局
media属性
@media all and (min-width: 100px) and (max-width: 500px) {
选择器 {
符合条件的样式;
}
}
清除浮动
上下排列
-
直接clear:both;即可
嵌套排列(父元素高度塌陷,影响后面的元素布局)
-
在父元素内最后加上一个空子元素,样式位clear:both;
- 缺点: 多设置一个无用的标签
-
将父容器设置固定的高度
- 缺点: 高度设置死了,不利于以后维护
-
父元素浮动,后面的元素设置clear:both;
- 这样虽然可以,但是影响嵌套元素的布局
-
父元素设置overflow:hidden / auto / scroll
- 缺点:如果子元素想要溢出,会受到影响
-
父元素设置display: inline-block / flex / table-cell
- 会影响到后面的元素
-
使用after伪类
- 注意:clear: both只作用于块级元素,内联元素不起作用,行内块元素也不行
父:after { content: ""; display: block; clear: both; }
BFC
触发BFC的条件
- 根元素,即HTML元素
- float的值不为none
- overflow的值不为visible(hidden, scroll, auto)
- display的值为inline-block、table-cells、table-caption
- position的值为absolute或fixed
bfc的特性
- 内部box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定,在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。解决:margin的叠加。
- 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)
- 形成了BFC的区域不会与float box重叠。解决:实现 两栏布局。
<style>
.first {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
.second {
width: 100px;
height: 100px;
background-color: beige;
overflow: auto; /* 触发bfc,让元素不被覆盖 */
}
</style>
<div class="first">1</div>
<div class="second">2</div>
2. 计算BFC高度时,浮动元素也参与计算。解决:清除浮动。
作用
-
BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。
解决问题
-
在同一个bfc下元素margin的叠加问题
-
只将margin设置在一个元素上
-
将这两个元素分别放在不同的bfc下,利用以上条件触发bfc
添加省略号
-
width: 必须;
white-space: nowrap//不让内容折行
overflow: hidden;//溢出隐藏
text-overflow: ellipsis;//添加省略号
表格
display
-
table:指定对象作为块元素级的表格。类同于html标签
(CSS2)- 可以设置margin和padding
-
inline-table:指定对象作为内联元素级的表格。类同于html标签
- 可以设置margin和padding,margin负值也可以
-
table-caption:指定对象作为表格标题。类同于html标签
(CSS2)
- 不可设置margin和padding,border也不会显示
-
table-row-group:指定对象作为表格行组。类同于html标签
(CSS2)
-
table-column:指定对象作为表格列。类同于html标签
(CSS2)
-
table-column-group:指定对象作为表格列组显示。类同于html标签
(CSS2)
-
table-header-group:指定对象作为表格标题组。类同于html标签
(CSS2)
-
table-footer-group:指定对象作为表格脚注组。类同于html标签
(CSS2)
- 只作用于引入的背景图片,不作用于背景颜色
-
写在background-image: url()后面才生效
- ..px ..px(宽 高) /
- cover(覆盖)背景图片可能显示不完全,容器完全覆盖
- contain(包含)图片完整,容器可能有空隙
- 如果仅有一个数值被给定,这个数值将作为宽度值大小,高度值将被设定为
auto。 - 如果有两个数值被给定,第一个将作为宽度值大小,第二个作为高度值大小。
- 只作用于引入的背景图片,不作用于背景颜色
- padding-box(默认):即在padding区域填充
- border-box:在border处填充
- content-box:在content处填充
- 这里背景图片和颜色都会起效果
- border-box(默认):边框及边框以内都会有背景显示
- padding-box:padding区域即内容区域有背景显示
- content-box:只用内容区域有背景显示
- text(为测试api,不可以使用):表示剪贴在文字上。如果想要做出剪贴效果,我们需要设置文字颜色为**
transparent**
结构性伪类选择器
nth-of-type()表示同一类型的元素
nth-child()表示全部元素
()内数字,也可以是2n(表示偶数行),2n+1(表示奇数行)
css3背景样式
background-size:
当通过宽度和高度值来设定尺寸时,你可以提供一或者两个数值:
background-origin(背景图片填充的位置):
注意:当使用 background-attachment为fixed时,该属性将被忽略不起作用。
background-clip:(背景的截取位置)
background-position: 背景图片的位置
background-position: right 50px bottom 70px;//这个表示在右下方,然后距离右边50px,距离下边70px
如果不加right等单词,只写数字偏移,他的参考点是左上角。
一个 position 定义一组 x/y 坐标(相对于一个元素盒子模型的边缘),来放置这个项目 (原文为 item) 。它可以被定义为一个值或者两个值。如果被定义为两个值,那么第一个值代表水平位置,第二个代表垂直垂直位置。如果只指定一个值,那么第二个值默认为 center。
background-attachment:背景图片如何随从文本
- scroll:表示随着滚动条滚动。此关键属性值表示背景相对于元素本身固定, 而不是随着它的内容滚动(对元素边框是有效的)。
- fixed: 表示固定位置不变。此关键属性值表示背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。
- local:表示跟随文字滚动。此关键属性值表示背景相对于元素的内容固定。如果一个元素拥有滚动机制,背景将会随着元素的内容滚动, 并且背景的绘制区域和定位区域是相对于可滚动的区域而不是包含他们的边框。
background-repeat: 背景图片的重叠样式。
- space: 图像会尽可能得重复, 但是不会裁剪. 第一个和最后一个图像会被固定在元素(element)的相应的边上, 同时空白会均匀地分布在图像之间。即容器可能不会被全部覆盖。
- round:图像会被压缩或者扩展来填满整个容器。这一点需要看容器的大小。
background-image: 主要看css3渐变。可以设置多个背景图片,并且先设置的最贴近用户
注意
<style>
div {
width: 100px;
height: 100px;
/* 这样是错误的, 只能设置一个背景颜色, 并且只能是最后一个属性值 */
/* background: red, blue; */
/* background: red, url('https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/mirror-assets/171de8ad450b4f25c89~tplv-t2oaga2asx-image.image'); */
background: url('https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/mirror-assets/171de8ad450b4f25c89~tplv-t2oaga2asx-image.image'), red;
}
</style>
疑问:
为什么渐变可以通过background-size改变大小,他不是背景颜色吗?而且他还可以在background-image上面设置background-size呢?
- 笨,虽然是颜色,但是他的background-image的属性值,所以可以设置background-size,改变的是整体的渐变背景大小。
为什么可以利用background-position设置动态渐变?
- 因为我们可以结合完全平铺的方式,虽然改变了位置,还是会完全填充的。我当时忽略了背景完全平铺的方式,认为改变了位置,应该会空出一部分空间的。
<style>
div {
width: 500px;
height: 20px;
border: 1px solid black;
background-size: 16px 16px;
//这里的0表示两侧的渐变颜色是突变,而非平缓过度
background-image: linear-gradient(-45deg, #D9CFBB 25%, #C3B393 0, #C3B393 50%,
#D9CFBB 0, #D9CFBB 75%, #C3B393 0);
animation: panoramic 20s linear infinite;
}
@keyframes panoramic {
to {
background-position: 200% 0;
}
}
</style>
<div></div>
渐变
linear-gradirent线性渐变
-
渐变颜色后指定的值都是颜色结束的位置。但是颜色会从前一个颜色指定的位置过渡到后一个颜色指定的位置。
-
可以只指定位置而不指定颜色,也可以指定颜色而不指定位置。
-
默认渐变方向是从上到下
-
可以利用关键字left,bottom,top,right结合 to 来指明渐变方向,也可以使用角度指明渐变方向
-
0deg表示从下边开始,正值表示顺时针,负值表示逆时针
也就是说,
background-image: linear-gradient(to top, #7A88FF, #7AFFAF);等价于:
background-image:linear-gradient(0deg, #7A88FF, #7AFFAF);
-
-
颜色后的数字,表示过度的范围。每两种颜色设置的数值就是该范围,该范围是缓性的,不是突变的。
//表示0~20为#66CC99色,20~30为#6666CC,30~40,40~100都为#66cc99 background-image: linear-gradient(45deg, #66CC99 20px, #6666CC 30px, #66CC99 40px)
radial-gradirent 径向渐变
渐变形状(默认是椭圆) at 渐变开始的中心位置,颜色 颜色范围,...
<style>
div {
width: 200px;
height: 120px;
/* 注意这里20~22是缓性渐变,而不会立刻从20以后就开始是#b4a078 */
background-image: radial-gradient(circle at 100px -8px, transparent 20px, #b4a078 22px);
}
</style>
<div></div>
repeating-linear-gradient 重复渐变
div {
background: repeating-linear-gradient(-45deg, red 0 5px, blue 5px, 10px);
}
注意
要在渐变中包含一个实心的非过渡颜色区域,请包含颜色起止点的两个位置。颜色起止点可以有两个位置,这相当于两个连续颜色在不同位置具有相同的颜色起止点。颜色将在第一个颜色起止点时达到完全饱和,保持该饱和度到第二个颜色起止点,并通过相邻颜色起止点的第一个位置过渡到相邻颜色起止点的颜色。
.multiposition-stops {
// 方法一
background: linear-gradient(to left,
lime 20%, red 30%, red 45%, cyan 55%, cyan 70%, yellow 80% );
// 方法二
background: linear-gradient(to left,
lime 20%, red 30% 45%, cyan 55% 70%, yellow 80% );
}
动态渐变
只需要认真思考
<style>
div {
height: 600px;
width: 600px;
animation: gradientChange 2s infinite alternate;
background-image: linear-gradient(45deg, #FA8BFF 0%, #2BD2FF 52%, #2BFF88 95%);
/* background-repeat: no-repeat; */
/* 这里确实移动了,但是仔细想一想,如果不放大背景,他会出现平铺的背景,我们只需要视觉上感觉是颜色渐变,所以放大后,我们移动背景位置,视觉上感觉颜色在改变,其实是渐变颜色而已,只不过在不同位置显示颜色 */
background-size: 200% 200%;
}
@keyframes gradientChange {
0% {
background-position: 0 100%;
}
/* 50% {
background-position: 50% 50%;
} */
100% {
background-position: 100% 0;
}
}
</style>
<div></div>
outline(style,width,color的简写)
与border的区别
-
轮廓不占据空间,绘制于元素内容周围。
div { width: 100px; height: 100px; box-sizing: border-box; border: 5px solid black; outline: 2px solid red;//这里的2px不占空间 } <div></div> -
根据规范,轮廓通常是矩形,但也可以是非矩形的。
outline-color:轮廓的颜色
outline-style: 轮廓的样式
-
元素轮廓是绘制于元素周围的一条线,位于
border的外围,使元素突出 -
none 无轮廓 (
outline-width为0).dotted 轮廓为一系列点.
dashed 轮廓为一系列短线.
solid 轮廓为实线.
double 轮廓为两根有空隙的线.
outline-width为线与空间的总和.groove 轮廓呈凹下状.
ridge 与
groove相反: 轮廓呈凸起状.inset 轮廓呈嵌入状.
outset 与
inset相反: 轮廓呈突出状.
outline-width:轮廓的宽度
- ..px、rem / thin(细) / medium (中) / thick(密)
outline-offset 用于设置 outline 与一个元素边缘或边框之间的间隙。
- ..px(正负都可)
利用box-shadow做一些事情
-
box-shadow是会紧贴border-radius圆角边的,所以我们可以做一个内角盒子 -
描边
outline并不会与圆角边border-radius贴合<style> div { background: #fff; width: 100px; height: 100px; border-radius: 10px; outline: 5px solid black; box-shadow: 0 0 0 4px black; } </style> <div></div>
关于fixed和transform结合的小bug
我们知道position: fixed;偏移量是以整个浏览器窗口为参照的。
对于声明transfrom值非none元素,其子元素中若存在position: fixed将以声明transform的最近祖先作为基准而定位,这是因为transfrom值非none的元素定义了一个局部坐标系统,导致postion: fixed以此坐标系统计算布局。 目前这个bug仍未被解决,官方建议避免在transform元素下做fixed定位。
<style>
.parent {
transform: translate(100px, 0);
border: 1px solid black;
}
.son {
position: fixed;
left: 60px;
width: 50px;
height: 50px;
background: red;
}
</style>
<div class="parent">
<div class="son"></div>
</div>
如何通过css实现滚动进度条
body {
height: 2000px;
background-image: linear-gradient(to right top, #ffcc00 50%, #eee 50%);
background-size: 100% calc(100% - 100vh + 5px);
background-repeat: no-repeat;
}
//这里是为了覆盖body 5px一下的渐变颜色的。
body::after {
content: "";
position: fixed;
top: 5px;
left: 0;
bottom: 0;
right: 0;
background: #fff;
z-index: -1;
}
分辨率,像素,多倍图
同一个分辨率下,显示的像素格越多,图片越清晰。
分辨率是度量位图图像内数据量多少的一个参数。
像素密度描述的是一英寸斜边代表的范围内含有的物理像素块的数量。
设备无关像素:css中的像素。设备无关像素是一个抽象存在的像素。也就是说他可大可小。
图片像素就是虚拟像素。是因为他没有固定的尺寸,我们可以根据需要将图片拉伸成任意尺寸,相应的每个像素也会缩放。
设备像素比:DPR = 物理像素/设备无关像素
图片的分辨率就是指 图片 横向的色块数量 x 纵向的色块数量。
- 图片像素是构成图片的像素块,他们是没有实际尺寸的,你拉伸缩放图片他的像素块数量是不会变的。
- 设备像素是指设备屏幕被划分成的千千万万个小格子,是物理像素,你能够通过设备的长宽和分辨率计算出每个物理像素的尺寸。
- CSS像素又叫设备无关像素,是一个抽象的概念。不同设备上的1px用肉眼看是不一样长的。是我们编码时用到的单位。
一些文字样式
white-space:normal(默认值) | nowrap | pre | pre-wrap | pre-line
- nowrap: 表示永不换行。多个普通的空格被合并为一个。但是不会干扰
</br>的实现。 - pre: preserve的缩写,表示保存。就是现实在页面上的内容和写在html标签中的内容是一模一样的,包括普通的空格也会显示若干个。
- pre-wrap:preserve-wrap的缩写。表示保留和换行。是前两个属性的综合。
- pre-line: 多个普通空格被合并,而且会自动换行。
(CSS2)
table-row:指定对象作为表格行。类同于html标签 |
| 是否能发挥作用 | 换行符 | 普通空格 | 自动换行 | 、nbsp; |
|---|---|---|---|---|
| normal | × | ×(合并) | √ | √ |
| nowrap | × | ×(合并) | × | √ |
| pre | √ | √ | × | √ |
| pre-wrap | √ | √ | √ | √ |
| pre-line | √ | ×(合并) | √ | √ |
word-break: normal(默认值) | break-all | keep-all
break-all:非常强烈的折行。如果是一个很长的英文单词,可能将单词从中间截断。
keep-all: 只有空格可以触发自动换行,不然就会超出容器宽度。并且不会拆分很长的单词而换行。
word-wrap(overflow-wrap):normal | break-word
break-word:表示不那么强烈的折行。只有在一行显示不下的时候才会拆分单词。不然就是正常折行。
letter-spacing:设置每个字符之间的距离的。
如果是英文单词,他表示每个字母之间的距离,而不是每个单词之间的距离。
word-spacing:设置每个英文单词之间的距离。
css的层叠上下文
定义: MDN中的解释:我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。
产生层叠上下文的方式:
-
文档根元素(
HTML); -
position值为absolute(绝对定位)或relative(相对定位)且z-index值不为auto的元素; -
position值为fixed(固定定位)或sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持); -
父元素的display属性值为
flex|inline-flex,子元素z-index属性值不为auto的时候,子元素为层叠上下文元素; -
opacity属性值小于1的元素(参见 the specification for opacity); -
mix-blend-mode属性值不为normal的元素; -
以下任意属性值不为
none的元素: -
isolation属性值为isolate的元素; -
-webkit-overflow-scrolling属性值为touch的元素; -
will-change值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章); -
contain属性值为layout、paint或包含它们其中之一的合成值(比如contain: strict、contain: content)的元素。
层叠等级图
处于同一个层叠上下文中,比较的规则。
奇葩的测试:
当两个父元素,设置相同的z-index时,它们的层叠等级,层叠顺序是相同的, 此时比较的就是正常文档流中的dom顺序。
<style>
* {
margin: 0;
padding: 0;
}
.A {
position: relative;
z-index: 1;
}
.B {
position: relative;
z-index: 1;
}
.a {
position: absolute;
background: red;
width: 100px;
height: 100px;
z-index: 5;
}
.b {
position: absolute;
top: 100px;
background: blue;
width: 100px;
height: 100px;
margin-top: -50px;
}
</style>
<div class="A">
<p class="a">a</p>
</div>
<div class="B">
<p class="b">b</p>
</div>
层叠上下文元素的background/border的层叠等级小于z-index值小于0的元素的层叠等级。
<style>
.box {
display: flex;
}
.parent {
width: 200px;
height: 100px;
background: #168bf5;
/* 虽然设置了z-index,但是没有设置position,z-index无效,.parent还是普通元素,没有产生层叠上下文 */
z-index: 1;
}
.child {
width: 100px;
height: 200px;
background: #32d19c;
position: relative;
z-index: -1;
}
</style>
<div class="box">
<div class="parent">
parent
<div class="child">child</div>
</div>
</div>
总结:
- 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
- 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
- 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
- 比较元素的层叠等级时,都需要在同一个父级层叠上下文中。
- 不同父级层叠上下文中的子元素中的z-index不会进行比较。
学习自掘金
will-change
为web开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。 这种优化可以将一部分复杂的计算工作提前准备好,使页面的反应更为快速灵敏。
不要将 will-change 应用到太多元素上
给它足够的工作时间:使用时需要尝试去找到一些方法提前一定时间获知元素可能发生的变化,然后为它加上 will-change 属性。建议加在改变元素之前。比如如果想让移入时元素有边框阴影,我们可以将该样式加在移入和元素的时候加给子元素。
<style>
div {
position: relative;
padding: 1em;
background-color: #fff;
}
div:before {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* z-index: -1; */
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
opacity: 0;
will-change: opacity;
-webkit-transition: 0.2s;
transition: 0.2s;
}
div:hover:before {
opacity: 1;
}
</style>
<div>
<p>
dwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwd吧哒哒哒哒哒哒多地对地导弹对哒哒哒哒哒哒多多多多多多多多多
</p>
</div>
meta标签的作用
如果设置了 name 属性,meta 元素提供的是文档级别(document-level)的元数据,应用于整个页面。和content结合使用,以名-值对的方式给文档提供元数据,其中 name 作为元数据的名称,content 作为元数据的值。
-
常用的值: keywords,description, viewport
keywords: 设置关键字,content为要设置的关键字,利于搜索引擎的搜索。
description: 该网页的描述文字,content为描述文字,利于搜索引擎的搜索。
viewport: 它提供有关视口初始大小的提示,仅供移动设备使用。content表示对于移动端的一些设置。
Value 可能值 描述 width一个正整数或者字符串 device-width以pixels(像素)为单位, 定义viewport(视口)的宽度。 height一个正整数或者字符串 device-height以pixels(像素)为单位, 定义viewport(视口)的高度。 initial-scale一个0.0到10.0之间的正数定义设备宽度(纵向模式下的设备宽度或横向模式下的设备高度)与视口大小之间的缩放比率。 maximum-scale一个0.0到10.0之间的正数定义缩放的最大值;它必须大于或等于 minimum-scale的值,不然会导致不确定的行为发生。minimum-scale一个 0.0到10.0之间的正数定义缩放的最小值;它必须小于或等于 maximum-scale的值,不然会导致不确定的行为发生。user-scalable一个布尔值( yes或者no)如果设置为 no,用户将不能放大或缩小网页。默认值为yes。
如果设置了 http-equiv 属性,meta 元素则是编译指令,提供的信息与类似命名的HTTP头部相同。
-
常用的值:content-type,refresh(刷新),expires (期限)
content-type,设置的content为text/html;charset=utf-8
refresh, 让网页多长时间(秒)刷新自己,或在多长时间后让网页自动链接到其它网页。设置的content如果只有一个整数,则表示间隔多少秒刷新一次网页,如果还设置了url,则表示间隔多少秒跳转到指定的url处。
<meta http-equiv="refresh" content="2; url=http://39.97.212.45:3000/" >expires, 表示指定缓存文档的过期时间,一旦网页过期后,就必须从服务器中重新请求。content设置的是过期时间。格式必须是GMT
<meta http-equiv="expires" content="Wed, 17 Jun 2020 00:00:00 GMT" >
如果设置了 charset 属性,meta 元素是一个字符集声明,告诉文档使用哪种字符编码。
<meta charset="utf-8" > //表示网页编码为utf-8
参考
link标签
HTML外部资源链接元素,规定了当前文档与外部资源的关系。
rel: 表示链接方式与包含它的文档之间的关系。
- icon,表示引入文档图标
- stylesheet,表示引入css资源
- preload,表示浏览器应该预加载该资源 ,并且这个属性的使用必须得依赖as,as的值表示加载的内容的类型
href:引入的链接。
media:表示该链接在什么条件下生效。
disabled:表示禁用引入的链接。
dns-prefetch: 此属性标识下一个导航可能需要的资源,用户代理应检索该资源。 这允许用户代理在将来请求资源时更快地做出响应。
title:属性在元素上有特殊的语义。当用于stylesheet时,它定义了一个首选样式表或备用样式表。不正确地使用它可能会导致样式表被忽略。如果link标签都有title属性那么他只会加载第一个link引入的样式文件。如果有link标签没有title,则表示永久生效的样式文件,而且后引入的覆盖前面引入的。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--这个样式生效->
<link rel="stylesheet" href="./css/style3.css" title="base3">
<!-- 这里的样式覆盖了前面的样式。并且始终生效 -->
<link rel="stylesheet" href="./css/style1.css">
<!-- 这个样式不生效->
<link rel="stylesheet" href="./css/style2.css" title="base2">
<!-- <link rel="stylesheet" href="./css/style3.css" title="base3"> -->
<title>Document</title>
</head>
<body>
<div></div>
<span>测试文字</span>
</body>
参考至 MDN
CSS性能优化
内联首屏关键CSS(Critical CSS)
内联CSS能够使浏览器开始页面渲染的时间提前,因为在HTML下载完成之后就能渲染了。
不过内联CSS有一个缺点,内联之后的CSS不会进行缓存,每次都会重新下载。不过如上所说,如果我们将内联后的文件大小控制在了14.6kb以内,这似乎并不是什么大问题。
异步加载css
通过js动态添加标签。
// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );
去除无用CSS
通过Uncss库。
有效的使用css选择器
保持简单,不要使用嵌套过多过于复杂的选择器。
通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。
不要使用类选择器和ID选择器修饰元素标签,如p.a,这样多此一举,还会降低效率。
不要为了追求速度而放弃可读性与可维护性。
不要使用@import引入css文件
首先,使用@import引入CSS会影响浏览器的并行下载。使用@import引用的CSS文件只有在引用它的那个css文件被下载、解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析、构建render tree等一系列操作。这就导致浏览器无法并行下载所需的样式文件。
分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场
- display: none (不占空间,不能点击)(场景,显示出原来这里不存在的结构)
- visibility: hidden(占据空间,不能点击)(场景:显示不会导致页面结构发生变动,不会撑开)
- opacity: 0(占据空间,可以点击)(场景:可以跟transition搭配)
结构: display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击, visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击 opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
继承: display: none和opacity: 0:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。 visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。
性能: displaynone : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大 visibility:hidden: 修改元素只会造成本元素的重绘,性能消耗较少读屏器读取visibility: hidden元素内容 opacity: 0 : 修改元素会造成重绘,性能消耗较少
联系:它们都能让元素不可见
边框背景border-image
/* border-image: image-source image-height(如果是数值的话是边框宽度的倍数) image-width image-repeat */
<style>
.box1 {
border: 30px solid transparent;
padding: 20px;
border-image: url("https://mdn.mozillademos.org/files/4127/border.png") 30;
}
.box2 {
border: 30px solid transparent;
padding: 20px;
border-image: linear-gradient(red 49%, green 50%) 30;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
</body>
选择器的权重
CSS基本选择器包含ID选择器、类选择器、标签选择器、通配符选择器。 正常情况下,一般都能答出!important > 行内样式 > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器。
下三角
1.利用border
2.clip-path
.triangle {
width: 30px;
height: 30px;
background: red;
clip-path: polygon(0px 0px, 0px 30px, 30px 0px); // 将坐标(0,0),(0,30),(30,0)连成一个三角形
transform: rotate(225deg); // 旋转225,变成下三角
}
clip-path
/* 前面的四个值,指的是距离兄弟元素的距离。为上右下左 。后面的值表示插入的长方形四个角的弧度。*/
clip-path: inset(35% 35% 35% 35% round 0 70% 0 70%);
/* 半径以一个以百分比表示的值将以公式 sqrt(width^2+height^2)/sqrt(2)计算,其中width与height为相关盒模型的宽与高。 圆心位置是以相关盒模型的宽高决定的。x:宽度换算。y:高度换算。*/
clip-path: circle(25% at 50% 50%);
/* 半径和圆心位置以百分比表示的长度将把盒模型的宽与高作为参照,宽作为 rx 的参照值,高作为 ry 的参照值。 */
clip-path: ellipse(25% 25% at 50% 50%);
/* 百分比表示的值x坐标是以模型和的宽度为参考的。y坐标是以模型和的高度做参考的。 */
clip-path: polygon(50% 0, 25% 50%, 75% 50%);
1rem、1em、1vh、1px各自代表的含义?
rem
rem是全部的长度都相对于根元素元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
em
- 子元素字体大小的em是相对于父元素字体大小
- 元素的width/height/padding/margin用em的话是相对于该元素的font-size
vw/vh
全称是 Viewport Width 和 Viewport Height,视窗的宽度和高度,相当于 屏幕宽度和高度的 1%,不过,处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好。
px
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
一般电脑的分辨率有{1920*1024}等不同的分辨率
1920*1024 前者是屏幕宽度总共有1920个像素,后者则是高度为1024个像素
伪类和伪元素的区别
伪类:
- 就是选择普通选择器不能选择的元素状态。
- 由于状态的变化是⾮静态的,所以元素达到⼀个特定状态时,它可能得到⼀个伪类的样式;当状态改变时,它⼜会失去这个样式。
- 使用单引号表示
伪元素:
- 设置文档流不存在的内容,是虚拟容器。
- 核⼼就是需要创建通常不存在于⽂档中的元素。
- 以双引号来表示
相同之处:
- 伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。
不同之处:
- 伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。
- 伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。
CSS命名规范
BEM命名
其中,block表示的是独立的分块或组件;独立就意味着,把这一部分放到其他部分也可以正常展示与使用,它不会依赖其父元素或兄弟元素。element表示每个block中更细粒度的元素;modifier则通常会用来表示该block或者element不同的类型和状态。
.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
vertical-align
vertical-align 用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方。只能是inline和table-cell元素。不能是line-block。所以如果使图片居中,我们只能设置他的类型为table-cell。
div {
display: table-cell;
height: 500px;
width: 900px;
border: 1px solid black;
text-align: center;
/* CSS 的属性 vertical-align 用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方 */
vertical-align: middle;
}
text-align
text-align CSS属性定义行内内容(例如文字)如何相对它的块父元素对齐。text-align 并不控制块元素自己的对齐,只控制它的行内内容的对齐。
link和@import的区别
- @import中的样式优先级最低。内部样式也会覆盖他。
- Link 属于 html 标签,而@import 是 CSS 中提供的
- 在页面加载的时候,link 会同时被加载,而@import 引用的 CSS 会在页面加载完成后才会加 载引用的 CSS
- @import 只有在 ie5 以上才可以被识别,而 link 是 html 标签,不存在浏览器兼容性问题
- Link 引入样式的权重大于@import 的引用(@import 是将引用的样式导入到当前的页面中)
Doctype 的作用?严格模式与混杂模式的区别?
用于告知浏览器该以何种模式来渲染文档
严格模式下:页面排版及 JS 解析是以该浏览器支持的最高标准来执行。
混杂模式:不严格按照标准执行,主要用来兼容旧的浏览器,向后兼容。
轻松切换图片
img:hover{
content: url(path);
}
content 改变的仅仅是视觉呈现,当我们鼠标右键或其他形式保存这张图片时,所保存的还是原来 src 对应的图片。这种方法还可以用在官网标志上。
由于使用 conetnt 生成图片无法设置图片的尺寸,要想在移动端使用该技术,建议使用SVG图片。