绪论
盒模型
层叠 优先级 继承
层叠
层叠指规则冲突时,如何选择规则。规则冲突解决顺序:
样式表来源
用户代理样式
用户代理样式:浏览器默认样式
作者样式表:你自己写的css样式
作者样式表会覆盖用户代理样式,因为浏览器先加载用户代理样式,再加载作者样式,所以作者样式会覆盖用户代理样式
例子:
重要声明
在css行末加! important,该行即表示重要声明
总结当前优先级:! important > 作者样式 > 用户代理样式
理解优先级
如果浏览器无法通过来源解决优先顺序,则会检查他们的优先级。浏览器将优先级分为两部分:html行内样式和选择器样式
行内样式
即在元素内手动给属性style赋值,行内样式会覆盖样式表的样式,行内样式没有选择器,因为直接作用于元素。如果样式表的样式带了! important,则行内样式同样带! important的样式声明无法覆盖样式表的样式
选择器优先级
选择器优先级类似操作符优先级 有一定顺序 比如两个类名选择器的优先级高于一个类名选择器
规则:选择器如果存在多个相同id,则id最多的选择器优先;如果id数量一致,则类名最多的选择器优先;如果id和类名数量都相同,有最多标签名的选择器优先。例如下图,数字越大越优先
其他规则:伪类选择器和属性选择器优先级作用和类选择器作用相同;通用选择器和组合选择器对优先级没有影响
应用:有时候你的样式没有生效,可能是选择器呗更高优先级的选择器覆盖了
优先级标记
可以用linux三位数文件权限理解css选择器优先级,三位数从高到底依次为id选择器数量,类选择器数量,标签选择器数量。计算每个选择器的优先级标记值,值高的优先级越高,越优先
源码顺序
即当样式表来源和选择器优先级都相同时,根据css声明顺序决定哪个样式起作用,也即最后声明的会覆盖
其他经验
不要使用id选择器,因为id选择器优先级过高
尽量不要使用! important ,因为选择器多了,优先级很难搞
继承
如果元素没有设置样式,则会继承父元素的样式
特殊值
inherit
让属性继承父类的属性
initial
让属性使用初始默认值
比如color: initial等于color: black, dispkay: initial等于display:inline,
简写属性
比如font,background,border,padding等属性
需要注意简写属性会覆盖其他省略的属性
简写顺序
有的属性简写顺序模糊,比如border: 1px solid可以无序 有的比如padding就有顺序
需要注意
padding,margin这类属性,如果属性写满,顺序是上右下左,如果三个属性,左属性为4%3=1,用第二个属性,如果是两个属性,上下用第一个,左右用第二个属性
还有一部分属性顺序不遵从上右下左,比如background-position,box-shadow,text-shadow属性,这些属性后如果根两个属性,则先是左右属性,再是上下属性
相对单位
相对单位好处
灵活
px:像素,1/96英寸
pt:点,印刷术语,1/72英寸
pc:派卡,等于12pt
mm:毫米
cm:厘米
in:英寸
em和rem
em:相对单位,当前元素字号(font-size)大小
好处是当字号大小变化,em单位也会放缩
如果对字号font-size使用em单位,则字号会用父元素的字号绝对值来计算em
浏览器默认字号大小为16px
例如一个选择器font-size:1.2em; padding: 1.2em,则边距目测会比字号大一些,大多少?大1.2em
例子:当多个嵌套元素使用em声明font-size属性时,font-size计算值会不断缩小,或是不断放大
可通过修改选择器解决问题,但办法不够好。em适用于边距这些,不太适用于字体这些属性
rem:是root em的缩写,表示相当于根节点的em,而不是父类的属性
经验:用rem设置字号,用px设置边框,用em设置其他属性
停止像素思维
默认字号可以直接给root根元素font-size属性设置目标值调整字号大小。比如浏览器默认字号16px,你想设置14px,则可以设置 14/16=0.875em
使用@media可以创建响应式,即不同窗口尺寸下会自动使用不同的选择器,在不同选择器里定义自己的样式达到响应式
视口相对单位
vh:视口高度的1%
vw:视口宽度的1%
vmin,vmax:视口宽高中较大/较小的1%
也可以使用相对视口单位定义字号大小
字号定义还可以使用calc函数计算,参数可以是不同相对单位的运算,比如calc(1em + 5px),注意运算符两边必须留空格。一个值得尝试的值是calc(0.5em + 1vw),0.5em定义了最小字号,1vw可以让字号随窗口大小流畅放缩
无单位数值和行高
支持无单位的属性有 line-height, z-index, font-weight。任何属性都可以用无单位的0,因为无论什么单位效果都一样
属性被继承时可以考虑用无单位数值,如下例
自定义属性(css变量)
需要在样式里定义变量,加两个--表示变量,调用时用var括号起来,例如
变量的出现可以让我们每次修改时只改变量,而变量的引用无需修改
var接收第二个参数,意义是当第一个参数未定义时使用第二个参数
如果var算出的结果是一个非法值,则会将该属性的值置为默认值
变量可以在root伪类样式中声明,伪类用冒号开头定义
看一个例子,值得注意的是,在一个样式里重新定义了两个变量,变量会被元素继承,展现不同的效果。注意同名变量的重新定义类似作用域,不会覆盖父作用域的同名变量,仅会覆盖当前作用域的变量
盒模型
元素宽度问题
目标
1.0代码
<html>
<head>
<style>
body {
background-color: #eee;
font-family: Helvetica, Arial, sans-serif;
}
header {
color: #fff;
background-color: #0072b0;
border-radius: .5em;
}
main {display: block;}
.main {
float: left;
width: 70%;
background-color: #fff;
border-radius: .5em;
}
.sidebar {
float: left;
width: 30%;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
</style>
</head>
<body>
<header>TJH 666</header>
<div class="container">
<main class="main">
<h2>join me</h2>
<p> this is a paragraph</p>
</main>
<aside class="sidebar">
<div class="widget"></div>
<div class="widget"></div>
</aside>
</div>
</body>
</html>
效果
缩小宽度,尝试让两个白色缩到一行
.main {
float: left;
width: 70%;
background-color: #fff;
border-radius: .5em;
}
.sidebar {
float: left;
width: 30%;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
没达到预期,是因为一行太窄装不下,虽然宽度加和的100,但还有边距,宽度声明是对应内容,需要结合盒模型看
一种方法
直接缩小某列的宽度,使其缩到一行,不推荐
调整盒模型
如果宽高定义是基于边框,则可以满足需求,可通过修改属性box-sizing修改宽高定义的基准为边框,内边距或内容。取值有content-box,border-box,inherit。content-box仅包含内容,border-box包含内容,边距和边框宽度,试一下
.main {
box-sizing: border-box;
float: left;
width: 70%;
background-color: #fff;
border-radius: .5em;
}
.sidebar {
box-sizing: border-box;
float: left;
width: 30%;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
发现两个元素合并到了一行显示
全局设置border-box
使用全局元素选择器可以给所有元素设置样式,在样式表开头添加如下选择器(这是比较常用的手段)
*,
::before,
::after {
box-sizing: border-box;
}
效果也是一样的,两个元素会缩到一行
注意点,当使用第三方样式时,三方样式可能没使用盒模型,即默认content-box,如果全局设置border-box,则会和三方样式的box-sizing冲突,一种方法是强制继承盒模型,这样第三方元素会继承其顶层容器,可以解决全局组件和三方组件的box-sizing冲突,代码如下
:root {
box-sizing: border-box;
}
*,
::before,
::after {
box-sizing: inherit;
}
给列之间加上间隔
两列之间没有间隔紧挨着不太好看,尝试在两列间加上间隔
方案1:给其中一列加上边距,再将该列宽度减小边距的宽度,保持元素总宽度不变
.sidebar {
float: left;
width: 29%;
margin-left: 1%;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
方案1耦合比较大 来一种更好方案
方案2:用calc计算元素宽度,意图更明显,calc中每个数字之间一定要加空格,不然计算结果有问题
.sidebar {
float: left;
width: calc(30% - 2em);
margin-left: 2em;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
元素高度问题
高度和宽度处理逻辑不同,宽度一般是固定,高度一般无限
目标:将主列和次列高度设为一样,通过两种方式
控制溢出问题
overflow属性可以控制溢出时的策略,overflow属性有如下值:
visible 默认值,即溢出内容仍可见不被遮盖
hidden 溢出的内容不可见
scroll 无论内容是否溢出,都会有滚动条
auto 仅当内容溢出时才有滚动条,没溢出时不出现滚动条
效果
overflow属性也可以单独控制水平或竖直方向溢出效果,可通过执行属性名overflow-x overflow-y实现
百分比高度备选方案
浮动布局
即float: left,float只能处理宽度问题 高度问题用css布局或flexbox布局
css表格布局
给容器设置display: table,给每一列设置display: display: table-cell
.container {
display: table;
width: 100%;
}
main {display: block;}
.main {
display: table-cell;
float: left;
width: 70%;
background-color: #fff;
border-radius: .5em;
}
.sidebar {
display: table-cell;
float: left;
width: calc(30% - 2em);
margin-left: 2em; /* table-cell下外边距不生效 */
padding: 1.5em;
background-color: #fff;
border-radius: .5em;
}
和block元素不同,宽度默认不会一定显示为100%,需要手动设置。上述代码需要再考虑边距,因为边距不会作用于table-cell元素
可以用表格元素的属性border-spacing定义单元格间距,该属性接收两个值,分别为水平间距和垂直间距。该属性还会作用表格边缘,到时元素无法对齐。这个属性需要在容器里定义
对容器使用border-spacing并在外面裹一层负外边距,效果大体好了
<head>
<style>
:root {box-sizing: border-box;}
*,
::before,
::after {
box-sizing: inherit;}
.wrapper {
margin-left: -1.5em;
margin-right: -1.5em;}
body {
background-color: #eee;
font-family: Helvetica, Arial, sans-serif;}
header {
color: #fff;
background-color: #0072b0;
border-radius: .5em;}
main {
display: block;}
.main {
display: table-cell;
width: 70%;
background-color: #fff;
border-radius: .5em;}
.sidebar {
display: table-cell;
width: 30%;
margin-left: 1em;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;}
.container {
border-spacing: 1.5em 0;
display: table;
width: 100%;}
</style>
</head>
flexbox布局
flexbox不需要外边再裹一个元素,也不需要负边距
flex只需要给容器指定display: flex,容器的元素无需像表格布局一样设置table-cell
.main {
width: 70%;
background-color: #fff;
border-radius: .5em;}
.sidebar {
width: 30%;
margin-left: 1em;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;}
.container {display: flex;}
注意到宽度加起来即使超过100%,但flexbox仍可以妥善处理
使用min-height和max-height
min-height可解决容器内容溢出问题。当内容高度超过容器高度,容器高度会自行扩展。而使用固定高度,则可能溢出
内容垂直居中
有很多方案
vertical-align只对表格布局的table-cell生效,还对行内元素生效
方案1
指定容器上下内边距相等,让容器和内容自行决定内容高度
方案2 使用表格布局和vertical-align: middle
方案3 flex垂直居中
负外边距
外边距折叠
当两个元素外边距相邻时,外边距会重叠,变成一个外边距。多个外边距相邻时,也是取最大的一个外边距
文字折叠
元素p默认有1em的上下外边距,但当两个p元素相邻时,上下外边距会重叠为1em而不是2em。两个外边距如果不相等,取最大的外边距
容器外部折叠
当容器没有外边距,而元素有外边距,则容器会元素的外边距撑起来
当容器是flex布局时,会禁止元素外边距溢出到容器外部
当给容器添加内边距时,也可以防止容器内元素外边距折叠
对容器使用overflow: auto也可以防止内元素外边距折叠
容器加边框或内边距防止折叠
flex布局和表格布局的元素不会发生外边距折叠
容器内元素间距
给侧边栏加两个链接来解释
<style>
.button-link {
display: block;
padding: .5em;
color: #fff;
background-color: #0090c9;
text-align: center;
text-decoration: none;
text-transform: uppercase;}
</style>
<aside class="sidebar">
<a href="/twitter" class="button-link">follow us on twitter</a>
<a href="/facebook" class="button-link"> follow us on facebook</a>
</aside>
猫头鹰选择器
即(body) * + *
*指任意元素,+指任意元素紧挨着的下一个兄弟元素,猫头鹰选择器就是选择某个元素下所有的非第一个兄弟节点,可以用这个选择器设置外边距
<html>
<head>
<style>
body * + * {margin-top: 1em;}
:root {box-sizing: border-box;}
*,
::before,
::after {
box-sizing: inherit;}
body {
background-color: #eee;
font-family: Helvetica, Arial, sans-serif;}
header {
color: #fff;
background-color: #0072b0;
border-radius: .5em;}
main {
display: block;}
.main {
width: 70%;
background-color: #fff;
padding: 1em 1.5em;
border-radius: .5em;}
.sidebar {
width: 30%;
margin-left: 1em;
margin-top: 0;
padding: 1.5em;
background-color: #fff;
border-radius: .5em;}
.container {display: flex;}
.button-link {
display: block;
padding: .5em;
color: #fff;
background-color: #0090c9;
text-align: center;
text-decoration: none;
text-transform: uppercase;}
</style>
</head>
<body>
<header>
<h1>tjh club</h1>
</header>
<div class="container">
<main class="main">
<h2>come join us</h2>
<p>one paragraph</p>
</main>
<aside class="sidebar">
<a href="/twitter" class="button-link">follow us on twitter</a>
<a href="/facebook" class="button-link"> follow us on facebook</a>
</aside>
</div>
</body>
</html>