写样式时,经常遇到一些bug或者某些属性值忘了,然后去查去解决,下次又忘了,又继续,挺烦人的,每次查的结果还参差不齐,痛定思痛,干脆自己整合一篇,希望能帮到你!
一、层叠与继承
很多属性都是默认继承的,比如font-size,color,text-align等等,也有些属性不是默认继承的比如width,padding,maring,border
1、控制继承的四个属性
- inherit:用于开启属性继承,继承直接父元素样式
- initial:设置属性值为浏览器默认值,若浏览器默认值为空则自动便为inherit
- unset:重置属性,若属性原本为默认继承则为inherit,否则为initial
- revert:如果用户设置了样式,则为用户设置的样式,否则为浏览器默认样式(若为空则为unset)
2、重置属性 all
可以设定为(inherit,initial,unset,revert),则样式则会回到指定的位置;如给一个buttom设置all为revert,会将其还原成默认的buttom样式
3、优先级计算
内联样式>ID选择器>类选择器>元素选择器或伪类选择器
用数字计算的话,它们分别是代表千位、百位、十位、个位
4、!important
优先级高于上述所有,该属性原本是用于阅读他人代码时知道有什么用而设置,非必要情况不建议设置
5、各种样式表?
相信大家都看到过用户代理样式表,用户样式表这类词,初见还是有点蒙圈的;
- 用户样式表:网页浏览者自己写的(一般是通过按照一些插件浏览器样式)
- 用户代理样式表:就是浏览器默认样式表
- 作者样式表:开发人员写的样式
优先级:
浏览器默认样式<用户样式表<作者样式表<作者样式表中!important<用户样式表中!important
二、css选择器
1、属性选择器
/*基于一个元素自身是否存在某个属性,或者基于属性值的某些特性*/
a[title] {} /*选择有title属性的 a元素 */
a[href="a.com"] { }/*选择href值为 a.com 的 a元素 */
a[href*="example"] {}/*herf属性值中包含字符串example的a元素*/
a[class~="txt"] { }/*选择有class属性,且至少有一个值为txt的a元素*/
a[class^="box-"]/*匹配class以box-开头的a元素*/
a[href$=".org"] {}/* 存在href属性并且属性值结尾是".org"的a元素 */
li[class^="a" i]/*a或者A开头,不区分大小写*/
li[class^="a" s]/*区分大小写*/
复制代码
详见属性选择器
2、伪类与伪元素
伪类是一种选择器,用于选择处于特定状态的元素,如鼠标悬浮在其上,仿佛给该元素添加一个类一样,故名伪类;用 : 表示
伪元素即仿佛添加了HTML元素一样,用 :: 表示
a:hover {}
p:first-child {}/*第一个子元素*/
:only-child {}/*没有兄弟的元素*/
:invalid {}/*表示任意内容未通过验证的input或其他form元素*/
:nth-child(2n){}/*匹配当前元素开始的偶数序兄弟元素,从1开始计数*/
acticle p:first-child::first-line {}/*acticle中第一个段第一行*/
/*常见的伪元素 ::berofer ::after*/
.box::after {
content: " ➥";
display: inline-block;
width: 10px;
height: 10px;
}
复制代码
3、其他选择器
*{}/*通配选择器,选择所有*/
body p em{}/*后代选择器,用空格隔开*/
.txt {}/*类选择器*/
#child{}/*ID选择器*/
article>p {}/*只会匹配直接子元素*/
h1+p{}/*邻接兄弟, 匹配紧跟h1后的p元素*/
h1 ~ p{}/*通用兄弟, 匹配h1后的所有p元素*/
复制代码
三、盒模型
1、块级盒模型
- 会在内联的方向上扩展,并占据父容器在该方向的所有可用空间,所以一般情况下与父容器宽度一致
- 会换行
- width和height属性可以发挥作用
- 设置内边距,外边距,边框会推开其他元素
2、内联盒模型
- 不会换行
- width和height属性不起作用
- 内边距和边框,上下左右都生效
- 垂直方向的外边距会被应用但是不会把其他处于 inline 状态的盒子推开(和没有差不多)
- 水平方向的外边距会被应用且会把其他处于 inline状态的盒子推开。
3、内部和外部显示类型
- display:(block,inline,inline-block)控制盒子外部显示类型
- display:flex/grid;控制盒子内部显示类型
4、盒子的类型
- 标准盒模型
默认时标准盒模型,计算大小时考虑内边距和边框
盒子宽度=内容区宽度(width)+内边距宽度+加边框宽度
- 替代盒模型
通过设置box-sizing:border-box 来实现倘若没有设置内边距或边框
内容区宽度=width。
如果设置了边框和内边距以及width:
内容区宽度 = width – 内边距宽度 – 边框宽度
5、边距
- 值
- 为外边距或者是内边距设置百分比值时,相对的是最近的块级父元素的width;
- 外边距可以设置为负值而内边距不可以;
- 外边距可以设置auto值而内边距不行,(边框也不行哈)
为什么是相对宽度而非高度呢?
因为这可能造成一个死循环,如果外边距增加导致父元素高度增加,那么外边距继续增加…无限循环
- auto值
盒模型中,能够设置auto值的是width和margin,实际上也只有width和margin-left和margin-right有效,margin-top和margin-bottom设置auto则为0;
相信大家都用过margin:auto来设置水平居中,而能够水平居中的具体原因呢?
原因在于一个块级盒子它会占据父容器宽度,而padding、border默认值为零;
此时 margin-left + margin-right + width = 包含它的元素的宽度;
- 默认情况下(啥都不设置或者都设置为auto):此时width会水平延伸至,而margin-left和ringht,auto值为0;
- 如果设置了宽度为固定大小:那么浏览器会将margin-right强制设置为auto,占据剩余空间;
- 而设置了宽度且设置margin:auto,则左右margin平分剩余空间,达到水平居中效果;
也可以用margin-top和bottom的auto值来设置垂直居中,整个过程是类似水平居中的,它模拟了块级盒模型再内联方向上的延展性。
设置垂直居中需要设置top,bottom为0,它会拉伸整个盒子的高度和父元素等高(这就和块级盒子它会占据父容器宽度的特性有点类似了)再通过设置heigh为固定值,同时设置margin: auto 0;就可以实现垂直居中(是不是有那味了)
-
外边距为负值
- margin-top和margin-left为负值时
会造成元素自身向上或者向左移动;
原因:margin属性有两类参考线,top和left是以外元素为参考(紧邻本元素的上方或者左方元素),这就导致上/左移
- margin-bottom和margin-right为负值时
会导致下方或者右方元素上移或者左移;
原因:maring-bottom和right是以自身为参考(相当于给下面或者右面元素的margin-top或者margin-left设置为负值,因为下方/或者右方元素是以它为参照的)
-
外边距折叠
- 相邻块级兄弟元素垂直外边距折叠(这种就不说了)
- 父子外边距折叠
父子外边距也会折叠?
先看看外部折叠的形成条件:
-
相邻块级元素外边距:即没有被padding、border、行内内容隔开
-
垂直方向上
只要满足这两个条件,都可能产生外边距折叠
因此,盒子的margin-top和它的第一个块级子元素的margin-top以及盒子的margin-bottom和它最后一个块级子元素的margin-bottom可能会发生外边距折叠
- 解决外边距折叠
-
float元素,absolute定位元素,inline-block不和任何元素发生外边距折叠;
-
BFC(格式化块级上下文,后文会提及)不与子元素发生外边距折叠
四、背景
1、background
总共8个属性值
background-color,background-image,background-repeat,background-attachment,background-position,background-size,background-origin,background-clip
缩写规则:
background-color只能在逗号之后指定
background-size只能包含在背景位置之后,用 ‘/’隔开
2、background-attachment
用于指定背景的滚动,有三个值
scroll:背景随页面滚动,但元素内容滚动时则不会滚动
fixed:不随页面滚动,也不随元素滚动
local:随滚动元素滚动
可以看看MDN的demo分别滚动内容区和页面的滚动条就可以看到它们的区别了
五、书写模式
1、wirtting-mode的三个值
- horizontal-tb:我们习惯的书写模式,块从上自下流
- vertical-rl:块从右自左流,对应文本为纵向
- vertical-lr:块从左自右流,对应文本为纵向
2、逻辑属性和逻辑值
随着书写模式的改变,很多属性不再适用,比如宽高
此时应换成对应的逻辑属性,width成了inner-size而heigh成了block-size
此处不细谈了,了解有这个东西存在即可,国内几乎用不到这些,如果遇到外国书写习惯不同再深入了解即可
六、相对值
常常遇到相对单位,如百分比,em,rem,那么它们都是相对什么来去确定大小的呢?
- em
如果用于font-size则时相对父元素的字体大小;用于其他属性则相对的是自身的字体大小
- rem
相对根元素的字体大小
- vw,vh
相对视口的宽度以及高度
- 百分比
一般来说,设置百分比是相对父元素相同属性的值,比如 font-size:50%,相对父元素字体的50%;但是内外边距相对的直接块级父元素的宽度
七、替换元素
顾名思义,内容可以被替代的元素;浏览器根据元素的标签和属性来决定其具体显示内容;本身一般具有固定宽高以及宽高比
特点:
内容外观不受页面上的CSS的影响,外观渲染独立于css;css可以影响它的位置,但不会影响其内容
常见的可替换元素有img,input,video
- img
默认display值为:inline
这时候可能就有人会问了,明明说好的给内联元素设置width和height无效的,为什么我可以改变图片的宽高呢?
这当然是和可替换元素有关啦:
1、如果没有设置宽高,且元素有固定宽/高值,则为固定宽高值
2、如果设置了宽度/高度,且元素有固定宽/高值,则按比例进行换算
- object-fit属性
img {
height: 100%;
width: 100%;
object-fit: contain
}
/*上述代码会使得图片覆盖整个盒子,但是如果与盒子长宽比例与图片不同,则造成图片比例变化,图象效果差*/
img {
height: 100%;
width: 100%;
object-fit: cover;
}
/*上述代码会图片覆盖整个盒子,图片按照长宽比放大或者缩小,如果与盒子比例不同,会对图片进行裁剪*/
复制代码
八、文本样式
1、字体样式
常见比如font-size,color,font-weight,font-style,font-family,text-decoration,text-shadow等
- text-decoration
设置文字的划线,比如删除线:text-through
特点:如果祖先规定了text-decoration,子类不能将其删除;
<p text-decoration:underline>
<em text-decoration:none></em>
</p>
<!--em中的样式将不会生效-->
复制代码
2、文本布局风格
- 对齐:text-align
- 行高:line-height,可以使用大多数单位,若没有单位则乘以字体大小
- 字母和单词间距:lettter-spacing,word-spacing
3、样式化列表
- 列表特定样式
- list-style-type :设置列表项目符号类型如无序列表的圆点
- list-style-position: 项目符号出现在列表内还是外面
- list-style-image:项目符号使用自定义图片
- 管理列表计数
<ol start="4">
<li>Toast pitta, leave to cool, then slice down the edge.</li>
<li>Fry the halloumi in a shallow, non-stick pan, until browned on both sides.</li>
<li>Wash and chop the salad.</li>
</ol>
<!--从4开始为序号,还可以设置reversed倒数,也可以在li中给value单独赋值-->
复制代码
4、样式化链接
- 链接的状态
- link,默认状态
- visited,被访问过了,存在于浏览器历史之中
- hover,鼠标悬浮于其上
- focus,键盘tab选中该链接或者被focus()选中
- active,链接被激活时,比如被点击时
- 上述状态均可用伪类选中,用的时候稍微注意以下顺序,比如active和hover会有重叠的时候
- 链接常用属性
- color,改变链接颜色
- cursor,悬浮时鼠标样式
- outline,focus时链接的轮廓(类似边框,不过不占用盒模型空间)
九、css布局
1、正常流布局
不进行任何布局设置或定位操作时的默认布局
- display属性
- 值有inline,block,inline-block
- inline和block特性在之前盒模型处提过了
- inline-block:提供块级和内联的中间状态,可以理解为不换行的block
- inline-block的问题
inline-block常用用于水平布局,相较float有很多好处;但是也不是没有瑕疵:
相邻inline-block直接可能存在间隙问题,看个例子:
p {
margin: 0;
display: inline-block;
width: 40px;
height: 40px;
background-color: rgb(226, 144, 144);
}
复制代码
<div class="container">
<p>hello</p>
<p>你好</p>
</div>
复制代码
结果:
<!--将html代码改成这样再来看看-->
<div class="container">
<p>hello</p><p>你好</p>
</div>
复制代码
结果:
是不是突然想到那个头上有问号的猫猫表情包?这代码有变化吗?
其实间隙的原因就在于换行不换行了,换行的话会留下一个回车符。
如何去除间隙呢?总不能把标签挨在一块这种方式吧。
可以给父元素设置font-size:0
2、flex布局
display:flex 用于创建横向或者纵向的一维布局,用 flex-direction控制,默认值为row(可定义为row-reverse,column,column-reverse),所有子元素高度会被拉伸到和最高元素相同。
如果子元素超出父容器宽度会溢出,可以用 flex-wrap: wrap来换行;可以把flex-direction 和 flex-wrap缩写为flex-flow。
-
主轴和交叉轴
- 主轴(main axis)由flex-direction定义,如果为row和row-reverse,则沿inline方向延伸(正常书写模式为横向)
- 交叉轴(cross axis)垂直于主轴
-
flex项的动态尺寸
- flex可以设定最小值,如flex-basis:200px,这意味着每个元素宽度至少为200px
- 也可以设置为无单位数字如flex-grow:1,这是一个比例值,若将每个flex项设置为相同的数字,则均等分父容器
- 还可以混用最小值和比例值,如 flex:1 200px,即先分配200px空间,剩余空间再按照比例分
- flex-shrink,用于溢出时按比例收缩子元素,可以这么来理解,所有子元素超出父容器宽度的部分按比例分摊收缩;flex:1时等比收缩,flex:0则不收缩
-
水平和垂直对齐
1、align-items 属性,用于控制flex项在交叉轴上的位置(就简单理解为纵轴吧,一般情况下)
- 默认值是stretch,沿交叉轴方向拉伸以填充父容器,如果父容器没有固定高度则所有flex项变得和最长的flex项一样长
- 设置为center,保持flex项宽度,并在交叉轴居中(简单理解为垂直居中)
- 设置为flex-start或flex-end则在交叉轴开始或结束位置对齐
2、justify-content,控制flex项在主轴的位置
- 默认值是flex-start,让所有flex项位于主轴开始处
- space-around,使得所有flex项沿着主轴均匀分布,在任意一段都留有一点空间
- space-between,和space-around类似,但是不会在两端留下空间
- center:(简单理解为水平居中)
-
排序
设置flex项的order属性,按照order值的大小排序,小的在前面,可以为负值。
3、grid布局
用于创建二维布局,将原始行列排列整齐;
- 使用grid-template-rows和grid-template-colunms来定义行和列
- fr 是==可用空间==的比例值(按比例分配)
- gird-gap用于定义行、列间隙
- repeat 用于重复构建宽度一致的行和列
- grid-template-areas
可以为网格命名;如果留空需要用 . 占位
所有相同名字必须构成连续区域,且为矩形
/*
container网格呈3行2列
第一行是header,占据横向两格
sidebar和content占据一格
footer占据两格
*/
.container {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 1fr 3fr;/*列宽比1:3*/
grid-gap: 20px;
}
/*为命名区填充内容*/
header {
grid-area: header;
}
article {
grid-area: content;
}
aside {
grid-area: sidebar;
}
footer {
grid-area: footer;
}
/* grid-template-columns:repeat(2,1fr,2fr)
将会生成1fr,2fr,1fr,2fr四列
上述参数可以增加
*/
复制代码
- grid-column和 grid-row
grid-colunm是grid-colunm-start和grid-colunm-end的缩写,两个值用/隔开;grid-row也一样
.wrapper {
display: grid;
grid-template-columns: 300px 1fr 1fr; /*第一列为300px,剩余空间按照比例分配*/
grid-template-rows: 100px 100px;
grid-gap: 10px;
}
.box1 {
grid-column: 2 / 4;
grid-row: 1;
/*摆在第一行,占据从2,3两列*/
}
.box2 {
grid-column: 1;
grid-row: 1 / 3;
/*摆在第一列,占据从1,2两行*/
}
复制代码
- 隐式网格
当没有显示定义网格轨道或者没有足够空间来设置网格项目时,网格项目就会自动创建隐式网格。可通过grid-auto-rows和grid-auto-columns属性设置隐式生成的网格行高和列宽;一般与minmax函数一块用(设置范围)
grid布局是一种很强大的布局方式,本文说的还是十分浅薄,只提及了一些常见的属性,详情可参照:
4、float布局
在上面两种布局方法出现之前,浮动曾被广泛用于简单的网页布局,可以把浮动视为一种传统的布局方式;
-
特点
- 浮动元素可以形成块,即行内元素也可以设置高宽了
- 非浮动元素的外边距不能用于自身和其它浮动元素之间来拉开距离,如果需要的话可以在它们之间再加一个空的 非浮动元素
- 浮动元素会尽量靠上
-
浮动布局的问题
- 浮动元素在父容器所占的有效高度为0(父元素高度塌陷)
解决办法:
1、末尾增加一个空的dom节点清除浮动
2、利用::after元素,并且设置display为block(和1思想类似)
3、父元素触发BFC(见后文)
4、将父元素设置为float或者display:table也能解决该问题
- 遮挡兄弟元素
浮动元素脱离标准流且浮动着标准流之上,兄弟元素上移,导致遮挡现象产生;
解决办法:clear清除浮动
- left:该元素下移,清除所有之前的左浮动
- right:该元素下移,清除所有之前的右浮动
- both:该元素下移,清除所有之前的浮动
记住:对被遮挡元素使用才生效
5、定位
- static:元素默认定位属性
- relative: 相对于原本位置进行移动
- absolue: 移出正常流,相对于该元素最近的非static元素定位或html
- 一般使用规则:子元素绝对定位,则父元素用相对定位
- fixed: 移出正常流,相对于视口定位
- sticky: 元素先保持static定位,到达视口预设值时变成fixed
十、BFC
block formatting context:块级格式化上下文,通俗理解就是一个完全独立的隔离容器,它保证内部元素不影响到外面,也保证外面元素对内部无影响。
- 特点
- 内部的盒子会在垂直方向上一个接一个放置
- 垂直方向上的距离由margin决定,属于同一个BFC的两个相邻盒子会发生外边距折叠
- BFC的区域不会与浮动元素发生重叠(因此也可以设置BFC来清除浮动)
- 计算BFC高度时,浮动子元素也参与计算(可以解决父元素高度塌陷问题)
- 每个盒子的左边框紧挨着包含块的左边框,浮动元素也如此。 (如果加上了padding还是不会挨着,说实话这个属性我个人一直不知道是什么作用)
- 触发BFC的方法
- float:(非none即可)
- position:(absolute或者fixed)
- display: (inline-block、table、flex、grid)
- overflow:(非visible即可)
看到有文章说如果元素发生外边距折叠,可以用BFC包含该元素来解决,但私以为大可不必,你用一个普通块级盒模型包裹该元素同样可以做到这一点(有点画蛇添足的感觉,当然也可能是鄙人认识浅薄,还望斧正);个人认为BFC主要还是用于解决浮动和高度塌陷问题较好;其实前文提及的一些特性都和BFC紧密相关
终于写完了!感觉不像是写了一篇博客,更像是做笔记,(其实就是在整理自己的笔记)。之前笔记写的太凌乱了,还有很多细节不完善的地方,为了讲清楚这些,又重新查阅了一些资料,写一篇博客还真的不容易,看到一些大佬动不动就是大长篇,可知背后花费之间之多。小萌新瑟瑟发抖。花费一两天的时间去整理这些说实话不知道值不值,假如能够对你有所帮助的话,那我觉得就是值得,喜欢的话给我点个赞吧!
给大家再推荐几篇CSS相关的文章吧:
参考文献: