$
标识原生DOM
元素let $white = document.querySelector('.white')
要先将该元素设置position
属性,absolute
或者relative
等javascript
三类基础选择器:css
ID
选择器;class
选择器;tag
;如下为延伸的选择器:html
.container div{ }
这里选择的是class = "container"
的HTML
元素内的全部div
元素,可是不包括container
这个元素;vue
.container > div{ }
选择的是container
里面第一层的全部div
:java
.container + div{ }
选择的是与container
位于同一层的紧挨着的下一个div
:git
注意了,container
同一层紧挨着的下一个元素若是不是div
,那么该选择器就选择不到任何元素:
浏览器
.container ~ div{ }
选择的是与container
处于同一层级下的全部div
:app
即便同一层下的div
元素中有其余元素隔开,也不影响;框架
*{ }
选择的是全部的HTML
元素;dom
能够与其余选择器配合使用,好比:
.container ~ *{ }
表示选取与container
同一层下的全部元素;
<a href="https://www.apple.com" title="Apple">Apple</a> <a href="https://www.google.com">Google</a> <a href="https://www.facebook.com">Facebook</a> //1.假如上面有三个超连接,给Apple添加一个title属性,那么就能够经过该属性选取它 a[title]{ //这样能够匹配到全部有title属性的a标签 } //2.还能够经过属性值进行匹配 a[href="https://www.apple.com"]{ //能够选择到href为苹果官网的a连接 } //这相似于匹配 a[href^="https"]{ //选择href属性值中以https为开头的a标签 } a[href$="com"]{ //选择href属性值中以com为结尾的a标签 } a[href*="book"]{ //*号会将属性值book做为关键词匹配,即选择href属性值中有book字符的a标签 }
a:visited //浏览过该a连接后的状态 a:hover //鼠标移上a标签后的状态 .container div:nth-child(3n+0/n/even) //选择container下的特定一组div元素;
注意:
.card-container:hover .cover{ transform:rotateY(180deg) } //这种状况表示,当悬停在card-container标签上时,改变.cover的样式;而不是仅仅局限于选择card-container这个标签
要选择.back
和.cover
两个标签不能这样写呀:.cover .back
,要这样写.cover, .back;
中间要用逗号隔开;
.cover, .back{ width: 100%; height: 100%; position: absolute; backface-visibility: hidden; //这里写transition表示以后对.cover和.back标签样式所作的修改(如hover)添加一个过渡过程 transition: transform .25s ease-in-out; }
绝对单位,1px
表明一个像素点,一般修改段落中文字大小时,除了修改font-size
,还要修改line-height
;
相对大小;1em=多少px
,是基于目前这个容器中的font-size
大小设定的,取决于使用em
单位的标签的父标签(直系),的font-size
;以下图所示:
上图中,每一层div
中的1em
值,都取决于上一层div
中的font-size
值;
在用em
单位设置文字段落的字体大小时,只须要修改父元素的font-size
,那么使用em
单位的font-size
和line-height
就不须要更改了,会自动等比例缩放;
也就是root em
。它与em
类似,惟一的不一样是它是基于html
元素的font-size
大小来计算的,不受上一级的父标签影响;
好比上面第一个例子,将em
改成rem
,则不一样层(框)内的字体大小不会受到父元素的影响:
优点为,更容易计算,只须要更改html
标签中的font-size
便可统一修改全部rem
单位。能够避免元素被多层嵌套后难以预测它的实际大小。
全写为viewport width
和viewport height
;它们的取值范围为:1~100
;
当width:100vw
;height:100vh
时,该元素会占满整个屏幕,当将父元素这样设置后,就可以很好地将子元素进行居中处理;
vmin
表明屏幕较短的一边,vmax
表明屏幕较长的一边,取值也是1~100
;在移动端实现屏幕旋转显示。好比:一张正方形的图片:
<img src="demo.jpg"> img{ width:100vmin; //width:100vmax; }
当宽设为100vmin
时,就会以屏幕较短的一边的总长度做为图片的边长,即便旋转屏幕后,边长也不会改变;
当宽设为100vmax
时,就会以屏幕较长的一边的总长度做为图片的边长,旋转屏幕后,边长也不会改变,不能显示的区域将会出现滚动轴;
其余的布局如table
,float
等都不是设计来作网页布局的,而Flexbox
是第一套专门为了网页布局而设计的方法。
flex
布局的预设值为block
,因此一开始设置了flex
布局(display:flex
)的元素都会独占一行。
Flex
布局主要能够分为两部分:flex-container
(整个弹性盒容器)和flex-items
(弹性盒中的元素);
flex
全属性实时预览:http://flexbox.help/
这些属性写在设定为flex-container
的标签中;经过给标签添加:display:flex
;可使该标签成为一个flex-container
。
设置flex-container
内的items
的排序方向,默认值为row
(行/水平排序),其余属性值有:
column
:列/竖直排序;row-reverse
:反向水平排序;column-reverse
:反向竖直排序;不一样的排序方向,主轴与交叉轴不同:
决定主轴的排序方向;有如下属性值:
center
:主轴上居中;flex-start
:主轴起始方向开始排列(默认表示左);flex-end
:主轴结束方向开始排列(默认表示右);space-around
:空白环绕;space-between
:与around
类似,只不过没有了最左和最右的空白;space-evenly
:空白平分;决定交叉轴的排序方向;有如下属性值:
center
:交叉轴上居中;flex-start
:交叉轴起始方向开始排列(当flex-direction
为默认值row
时,表示上);flex-end
:交叉轴结束方向开始排列;(默认表示下)space-around
:空白环绕;space-between
:与around
类似,只不过没有了最左和最右的空白;space-evenly
:空白平分;justify-content:center
与align-item:center
配合使用可使flex-container
(弹性盒)内的items
水平和垂直方向上居中。
当弹性盒内的item
过多时,该属性能够控制,是压缩每一个item
宽度不换行,仍是保持每一个item
宽度换行;
nowrap:压缩
item`宽度,不换行;
wrap
:不改变item
宽度,换行;(换行后,会将弹性盒一分为二,因此两行item
并非挨在一块儿的)
该属性为flex-direction
和flex-wrap
组合的缩写;如:
flex-flow:row wrap;
等效于flex-direction:row;flex-wrap:wrap;
这个属性的前提条件为flex-wrap
为wrap
时,即有多行flex items
时才会生效;用于设定多行flex-items
间行与行间的对齐方式,属性值有:
flex-start
:在交叉轴开始方向上排列:
flex-end
:交叉轴结束方向上排列:
center
:交叉轴中间:
initial
:默认值,保持原来的样子:
space-around
:与上面同样:
space-between
:(上下)平均分空白,与around
类似,不过消除了最左和最右的空白:
space-evenly
:平分空白区域:
用于调整flex item
(盒内元素)的排序顺序,根据order
的值按照主轴方向由小到大排序,默认值为0
;好比C
的order
设置为1
,由于它最大,因此C
排到最后:
该属性用于复写flex container
的align-items
属性;也就是说align-items
是对于全体的flex items
作出规划,而align-self
则是设置个别flex items
的排序方向:
如上图所示,因为align-items:center;
因此总体的flex items
是居中的,可是,设置了align-self
的C
和D
会按照align-self
的值进行从新排列;
该属性用于设定flex-item
在主轴方向上的大小;好比,当主轴为row
时,能够经过设定该属性的值来修改每个flex-item
的宽,这样flex-item
原来的宽就失效了。
同理,当flex-direction:column;
即主轴为竖直方向时,flex-basis
设定的属性值将是每个flex-item
的高;
若是设置为0
的话,至关于将width/height
设置为0
,这样每一个flex-item
在没有设置overflow:hidden;
的状况下,大小都由内容撑开;
设定为auto
时,则按照原来设定的宽度来计算:
也就是图中的60px
。
该属性是指在flex-container
主轴方向上有剩余空间的时候,flex item
沿主轴方向扩大的设定。
好比,原来的布局以下图所示:
将flex-grow:1;
时:
可见flex-item
自动平分了主轴的空白空间。1
的意思是每个flex-item
都占有主轴空白空间的一份,也就是1/3
。
设定A
的flex-grow:0;
则A
保持原样,不扩大;将B
的flex-grow:4;
表示先将空白区域分为(4+1+0=6
份)而B
占其中的4
份,C
占1
份也就是:
与flex-grow
效果相反,即当flex-item
超过了主轴长度,沿主轴方向怎样缩小的设定。默认值为1
,即为了避免使flex-item
突出整个flex-box
会自动缩小每一个flex-item
。
如图:当设定每一个flex-item
的flex-shrink:0;
时即保持每一个flex-item
原来的大小,此时会超出主轴90px
:
若是这样设定:
.A{flex-shrink: 1} .B{flex-shrink: 1} .C{flex-shrink: 1}
即三个flex-item
平分突出的部分,即A
、B
、C
各缩小30px
:
若是这样设定:
.A{flex-shrink: 1}//share 1/5 .B{flex-shrink: 3}//share 3/5 .C{flex-shrink: 1}//share 1/5
则B
承担3/5
的突出部分,也就是要缩小90x3/5=54px
,其他两个flex-item
只须要缩小1/5
,也就是18px
:
这个属性为flex-grow
,flex-shrink
和flex-basis
组合起来的缩写;
当这样设定时:
flex:1 1 auto; //至关于 flex-grow: 1; flex-shrink: 1; flex-basis: auto;
也就是说flex-item
会按照flex-container
(弹性盒)的主轴长度平均分配空间去放大或缩小。
当flex-container
有空白空间的时候,同步扩大:
当flex-container
没有空白空间时的时候,同步缩小:
再如:
flex: 0 1 150px
此时,flex-grow:0;
即有空白空间时保持原样,不扩大;总体来说就是只有在flex-container
空间不足时同步缩小,而且固定每一个flex-item
在主轴上的长度为150px
。
再如:
flex:0 0 200px
即固定每一个flex-item
主轴方向上的长度为200px
,不管flex-container
有无空白空间都不扩大或缩小:
当 flex
取值为 none
,则计算值为 0 0 auto
,以下是等同的:
.item {flex: none;} .item { flex-grow: 0; flex-shrink: 0; flex-basis: auto; }
当 flex
取值为 auto
,则计算值为 1 1 auto
,以下是等同的:
.item {flex: auto;} .item { flex-grow: 1; flex-shrink: 1; flex-basis: auto; }
这就是flex:1的真面目
当 flex
取值为一个非负数字,则该数字为 flex-grow
值,flex-shrink
取 1
,flex-basis
取 0%
,以下是等同的:
.item {flex: 1;} .item { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; }
当 flex
取值为一个长度或百分比,则视为 flex-basis
值,flex-grow
取 1
,flex-shrink
取 1
,有以下等同状况(注意 0%
是一个百分比而不是一个非负数字):
.item-1 {flex: 0%;} .item-1 { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; } .item-2 {flex: 24px;} .item-1 { flex-grow: 1; flex-shrink: 1; flex-basis: 24px; }
当 flex
取值为两个非负数字,则分别视为 flex-grow
和 flex-shrink
的值,flex-basis
取 0%
,以下是等同的:
.item {flex: 2 3;} .item { flex-grow: 2; flex-shrink: 3; flex-basis: 0%; }
当 flex
取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow
和 flex-basis
的值,flex-shrink
取 1
,以下是等同的:
.item {flex: 2333 3222px;} .item { flex-grow: 2333; flex-shrink: 1; flex-basis: 3222px; }
flex
的默认值是以上三个属性值的组合。假设以上三个属性一样取默认值,则 flex
的默认值是 0 1 auto
。同理,以下是等同的:
.item {flex: 2333 3222 234px;} .item { flex-grow: 2333; flex-shrink: 3222; flex-basis: 234px; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } ul{ list-style: none; /* 此时ul成为了flex-container */ display: flex; justify-content: space-around; background-color: #eee; padding: 8px 0; } ul > li a{ display: block; padding: 4px 8px; } </style> <style> </style> </head> <body> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Products</a></li> <li><a href="#">Protfolio</a></li> <li><a href="#">Contact</a></li> </ul> </body> </html>
效果图:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .post .thumbnail img{ display: block; width: 100%; height: auto; border-radius: 100%; } .post .thumbnail{ flex: 0 1 350px; min-width: 200px; } .post{ display: flex; flex-direction: row; padding: 2em; border-bottom: 1px solid #eee; } .content{ display: flex; flex-direction: column; margin-left: 1.2em; flex: 1 1 auto; } .content h4{ font-weight: bold; } .content .excerpt{ font-size: .8em; color: #666; } </style> </head> <body> <div class="post"> <div class="thumbnail"> <img src="http://ahuntsun.gitee.io/blogimagebed/img/vuepress/home/1.jpg" alt=""> </div> <div class="content"> <h4 class="title"> Flexbox Example</h4> <div class="excerpt"> The economic downturn in the US triggered by the pandemic has been officially declared a recession.Meanwhile, US markets continued their rebound on Monday, as investors remained optimistic that the downturn will be short-lived. </div> </div> </div> </body> </html>
效果图:
布局方式大体有四种:Table
、Float
、Flexbox
、Grid
;
Table
布局是最古老的布局,如今已不多使用。Float
曾经盛行一时,被称为“DIV + CSS
布局”;而Flexbox
和Grid
才是真正为了网页布局而设计的;
Flexbox
属于一维(1-Dimension
)的排版方式,而Grid
则是二维(2-Dimensions
)的排版方式。也就是说一个Flexbox
容器只能控制一个方向,即水平方向或者垂直方向,若是要控制另外一方向则须要再添加一层Flexbox
容器;Grid
容器则能够一次过控制两个方向,这样就能够直接定义容器中元素的位置了。
经过如下代码,设置一下布局,经过一张带标尺的背景图片能够更直观地对比:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid</title> <style> #grid-container{ /* 将父容器(div)设置为grid布局 */ display: grid; width: 500px; height: 500px; background-color: #eee; /* 将整个grid-container分割成5x5的方格,每格100 x 100 */ /* 该属性将grid-container分割为五行,每行高100px */ grid-template-rows: 100px 100px 100px 100px 100px; /* 该属性将grid-container分割为五列,每列宽100px */ grid-template-columns: 100px 100px 100px 100px 100px; } body{ margin: 40px; } #ruler{ position: absolute; top: 0; left: 0; width: 580px; height: 580px; background-image: url('https://codingstartup.com/assets/grid/grid-ruler.png'); background-size: 580px 580px; } .cell-1{ background-color: blue; } .cell-2{ background-color: yellow; } </style> </head> <body> <div id="ruler"></div> <div id="grid-container"> <div class="cell-1"></div> <div class="cell-2"></div> </div> </body> </html>
能够看到预设状况下grid-container
中的元素是这样排列的;
若是咱们想让蓝色的cell-1
占据左上方的四格的话,从图中可看出,目标范围为row
方向的1~3
;column
方向的1-3
;能够这样设置样式:
.cell-1{ background-color: blue; grid-row: 1 / 3; grid-column: 1 / 3; }
效果为:
若是想让黄色的cell-2
占据row
方向的4-6
,column
方向的1-3
,则须要这样设置:
.cell-2{ background-color: yellow; grid-row: 4 / 6; grid-column: 1 / 3; }
效果为:
该属性为grid-row
和grid-column
的简写,以黄色的cell-2
为例:
.cell-2{ background-color: yellow; grid-row: 4 / 6; grid-column: 1 / 3; //等同于 //grid-area: 4 / 1 / 6 / 3; }
能够看到,grid-area
的值至关于元素的左上角和右下角的,以(ROW, COLUMN)为形式的坐标。即左上角:(4,1)、右下角:(6,3)。
实际开发时并无一把尺来参考,以蓝色方块为例,能够采起下列写法:
.cell-1{ background-color: yellow; grid-row: 1 / 4; grid-column: 2 / span 3; }
意思为ROW
方向从1~4
,COLUMN
方向上从2
开始,span 3
表示从2开始往COLUMN
方向延伸3格,效果以下:
如上图所示,grid-container
中水平和垂直方向上各有6
条线,将整个grid-container
空间分割成了25
份;这些线在CSS Grid
中被称为Grid Line
。这些Grid Line
是能够命名的。首先给ruler
换一个背景:
#ruler{ position: absolute; top: 0; left: 0; width: 580px; height: 580px; background-image: url('https://codingstartup.com/assets/grid/grid-ruler-xy.png'); background-size: 580px 580px; }
效果为:
也就是将水平方向的Grid Line
命名为X1~X6
;垂直方向的Grid Line
命名为Y1~Y6
;
能够在grid-container
中这样设置:
#grid-container{ grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6]; grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6]; }
设置好Grid Line
名字后,就能够这样来设置了,以蓝色的cell-1
为例:
.cell-1{ grid-row: Y1 / Y4; grid-column: X2 / X6; }
上面的代码表示,ROW
方向范围为Y1~Y4
之间,COLUMN
方向范围为X2-X6
之间。
效果为:
grid-container
中的线被称为grid line
,而方格则称为Grid Area
;咱们也能够直接给特定的格子命名;
在grid-container
中添加多两个格子cell-3
和cell-4
,分别为橙色和黑色;重置cell-1
,cell-2
的布局,将ruler
换回原来的背景:
//html结果 <div id="grid-container"> <div class="cell-1"></div> <div class="cell-2"></div> <div class="cell-3"></div> <div class="cell-4"></div> </div> //css样式 .cell-1{ background-color: blue; } .cell-2{ background-color: yellow; } .cell-3{ background-color: orange; } .cell-4{ background-color: black; }
随后咱们能够在grid-container
中添加grid-template-ares
属性,该属性的值与grid-container
中的每个格子一一对应:
#grid-container{ grid-template-areas: "header header header header header" "nav main main main main" "nav main main main main" "nav main main main main" ". footer footer footer ."; }
上面的点表示不给左下角和右下角的格子命名。此时就定义了四个grid-area
分别是:header
、nav
、main
和footer
;
使用方法也很简单,以蓝色的cell-1
为例,在该格子中添加grid-area
属性,值设置为header
:
.cell-1{ background-color: blue; grid-area: header; }
那么cell-1
就占据了grid-area
中名字为header
的区域,也就是第一行:
随后再分别将cell-2
的grid-area
设置为nav
、cell-3
设置为main
、cell-4
设值为footer
:
.cell-2{ background-color: yellow; grid-area: nav; } .cell-3{ background-color: orange; grid-area: main; } .cell-4{ background-color: black; grid-area: footer; }
效果为:
这样全部的元素都定位到设定好的位置上了;
将ruler
中做为尺的背景图去掉,就出现了熟悉的布局了:
还能够在grid-container
中经过row-gap
设置行距,column-gap
设置列距;好比都设置为10px
:
#grid-container{ row-gap: 10px; columns: 10px; }
效果为:
因为上下左右都多了40px
,随后将grid-container
的长宽增长40px
就能够了。
Fr
为Grid
中的比例单位,表示占一份的意思。好比:
#grid-container{ grid-template-rows: 300px 100px 100px 100px 100px; grid-template-columns: 100px 100px 100px 100px 100px; } //可改写为 #grid-container{ grid-template-rows: 3fr 1fr 1fr 1fr 1fr; grid-template-colmn: 1fr 1fr 1fr 1fr 1fr; }
第二种写法表示,将grid-container
的row
方向上分为7
份,第一行占3
份,其他四行各占1
份;在column
方向上分红5
份,五列每列占一份。
还能够经过repeat
函数简写,该函数第一个参数表示重复几回,第二个参数表示重复什么,可是该函数不适用于grid-template-areas
。以上设置可改写为
#grid-container{ grid-template-rows: 3fr repeat(4, 1fr); grid-template-colmn: repeat(5, 1fr); }
将父元素(容器)设定text-align:center
,就能够左右置中了;
将元素自己的margin-left
与margin-right
设置为auto
,也就是一般的:margin: 0, auto;
就能够左右居中了;
#block{ position:absolute;//使元素浮动,脱离文档流 top: 50%; left: 50%;//这样设置了top和left后,block的左上角就对齐了画面的中心点 //要将block的中心点与画面的中心点重合,须要将block向上和左偏移block尺寸的一半,能够采用transform transform:translateX(-50%) translateY(-50%); } //一样能够采用下列写法 #block{ position: absolute; bottom: 50%; right: 50%; transform: translate(50%, 50%); }
能够这样设置,使body
的内容,上下左右居中:
body{ min-height: 100vh; display: flex; //将body设置为flex-container justify-content: center; //将主轴上的flex-item居中 align-items: center; //将交叉轴上的flex-item居中 }
原理为将父元素设置为表格布局(display:table
),里面要居中的元素设置为表格的一个格子(display: table-cell
),这样vertical-align
属性就能对这个格子生效了;这样设置:
<body> <div class="cell"></div> </body> body{ display: table; width: 100%; min-height: 100vh; } .cell{ display: tabel-cell;//此时.cell就会成为表格的一个储存格 vertical-align: middle;//此时vertical-align属性就生效了,达到上下居中 text-align: center; //设置左右置中 }
总结:以上三种方法中:
Position:absolute
;对齐的是元素自己,只须要调整须要居中的元素自己便可;Flexbox
)和第三种(Table
)方法,对齐的是元素内容。都须要先将父容器调整成与画面相同的大小(这就是min-height: 100vh;
的做用),而后再设定它的内容(子元素)的对齐方式。position
有五个设定值,分别是:static
、absolute
、relative
、fixed
和sticky
。
HTML
里面全部元素的Position
默认值都是static
,设定了该属性的元素,不会脱离文档流,会随着HTML
文档排版的流程(flow
)而发生变化。
首先,搭建如下的HTML
和CSS
样式:
效果为:
为了方便说明,事先为
static
类添加了样式(下同);
随后在html
样式中新增一句"Hello World"
:
Hello World <div class="static"></div>
能够看到这个static
的div
就会由于这一行文字而向下移动了一点:
再次改写HTML
和CSS
样式:
//HTML结构 <div class="height"></div> <div class="static"></div> //CSS结构 .static{ position: static; width: 360px; height: 360px; } .height{ width: 750px; height:120px; }
效果以下:
能够看到,height
div高为120px
,因此static
的div就要相应下移120px
;
注意:position
值为static
的元素对于top
、left
、right
、bottom
的设定值都是不会生效的;
以下改写HTML
和CSS
结构:
//HTML结构 <div class="height"></div> <div class="absolute"></div> //CSS结构 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
效果为:
如图所示,right
的设定值是将元素定位到与HTML
文档右边相距80px
的位置;bottom
则是将元素定位到与HTML
文档底部相距60px
的位置。
absolute
元素会固定在所设定的位置,不会随着HTML文档排版的流程移动,即脱离文档流。
更改样式,加多几个高度为120px
的蓝色height
div:
//HTML结构 <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="absolute"></div> //CSS结构 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
效果:
能够看到并无影响到absolute
元素所在的位置的。可是若是absolute
元素所在的容器有滚动轴的话,它就会随着滚动轴移动:
再次更改样式,添加多一个absolute
div:
//HTML结构 <div class="height"></div> <div class="absolute"></div> <div class="absolute"></div> //CSS结构 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
乍一看页面没有发生变化:
可是,实际上两个absolute
元素是重叠到一块儿了。能够经过将其中一个absolute
元素的right
设定为100px
,证实:
<div class="absolute" style="right: 100px"></div>
能够看到这两个absolute
元素确实是重叠在一块儿的:
再次更改样式,将absolute
元素放在absolute
元素内,结果会如何呢?
//HTML结构 <div class="height"></div> <div class="absolute"> <div class="absolute"></div> </div> //CSS结构 .height{ width: 750px; height:120px; } .absolute{ position: absolute; width: 240px; height: 240px; right: 80px; bottom: 60px; }
结果是里面的absolute
元素的right
与bottom
是根据外面那层的absolute
元素的位置去定位的。因此会再向左偏移80px
,向上多偏移60px
:
新增一个relative
div并改写样式:
//HTML结构 <div class="height"></div> <div class="relative"></div> //CSS结构 .height{ width: 750px; height:120px; } .relative{ position: relative; width: 360px; height: 360px; top: 60px; left: 150px; }
效果如图所示:
可见,relative
与static
是很类似的,都是会跟随HTML
的排版流程(文档流)移动。可是它比Static
多了top
、left
、right
、bottom
的设定。也就是说,它在跟随HTML
排版流程去定位之余,还能够经过这四个值进一步调整位置。
好比在上面增长一个height
div:
//HTML结构 <div class="height"></div> <div class="height"></div> <div class="relative"></div>
relative
元素就会因上方增长的内容而向下移动:
除此以外,relative
最重要的一个功能是:在它里面的absolute
元素会根据relative
的位置去定位;好比在它里面加一个absolute
div:
//HTML结构 <div class="height"></div> <div class="height"></div> <div class="relative"> <div class="absolute"></div> </div>
会发现absolute
元素的right
与bottom
是根据relative
元素的位置去定位的:
有人可能会认为这不是很正常嘛,咱们将relative
改为static
:
//HTML结构 <div class="height"></div> <div class="height"></div> <div class="static"> <div class="absolute"></div> </div>
能够看到,absolute
元素会直接无视包含它的static
元素:
总结:relative
相对于static
,主要增长了两大功能:
第一:relative
具有了top
、left
、right
、bottom
的设定;
第二:可使absolute
子元素根据它的位置去定位,也就是子绝父相;
新增一个fixed
div:
//HTML结构 <div class="height"></div> <div class="height"></div> <div class="fixed"></div> //CSS结构 .height{ width: 750px; height:120px; } .fixed{ position: fixed; width: 240px; height: 240px; bottom: 60px; left: 80px; }
效果为:
fixed
与absolute
是很类似的,不一样的地方有两点:
第一:fixed
会固定到荧幕中的固定位置,即便滚动页面,它的位置也不会发生改变;
增添多个height
div,能够发现即便滚动页面,fixed
div位置也不变:
第二:若是fixed
div设定了top
、left
、bottom
、right
的值,即便将它放入relative
div中,fixed
div 依旧会根据页面,也就是body
去定位,而不会根据relative
div去定位。
改写样式,在relative
div 中添加一个fixed
div:
//HTML结构 <div class="height"></div> <div class="relative"> <div class="fixed" style="position: fixed; width: 50px; height: 50px; background-color: #000"></div> </div>
在fixed
div不添加top
、left
、bottom
、right
属性时,fixed
div 会相对于包裹它的relative
div 定位:
当设定了top
、left
、right
、bottom
其中一些属性以后:
//HTML结构 <div class="height"></div> <div class="relative"> <div class="fixed" style="position: fixed; width: 50px; height: 50px; background-color: #000; top: 50px"></div> </div>
fixed
div 就会脱离包裹它的relative
div 的束缚,而根据body
进行定位:
添加sticky
div 改写样式:
//HTML结构 <div class="height"></div> <div class="sticky"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> <div class="height"></div> //CSS结构 .height{ width: 750px; height:120px; } .sticky{ position: sticky; width: 240px; height: 90px; top: 0; }
能够看到,页面出现了滚动轴:
随后滚动页面:
能够发现,sticky
div 在滚动的过程当中,当贴到页面顶部的时候,就会固定在页面顶部,也就是"粘住了";之因此会粘住是由于咱们设置了sticky
div 的top
为0
,当它距离页面顶部0px
的时候,就会触发top:0px;
这一属性。
HTML
元素大体上默认分为两种形态,一种为Block
,另外一种为Inline
。Block
为区块的意思,Inline
为内联的意思。
Block
元素会独占一行,好比两个段落,即便源码中没有空格,显示的两段文字也会隔开(由于p
标签是块元素):
因为块元素是独占一行的,因此,即便一行中有空间也不容许两个块元素左右排列,以下图所示将p
标签的宽度设置为50%
后,两个P
标签也不会左右排列。
HTML
源码中会将多个空格合并为一个空格进行显示,若要加多个空格能够添加: (no-break-space)
Block
元素的特色为:
Block
元素之间只能上下排列;width
和height
设定;常见默认为Block
的标签有:div
、p
、h1
到h6
、ul
等。
以下图所示,在p
标签中加入 strong
标签,并设置样式:
这里的 strong
就是inline
内联元素。它的特色为:
Inline
标签之间能够左右排列;inline
元素的大小由所包含的内容决定,不受width
和height
影响;常见默认为inline
的标签有 a
、 strong
、 span
等。
它结合了Inline
和Block
二者的特性,既能够设定宽度和高度,又能够与其余Inline
元素并排。
好比在段落的最后面加一个超连接按钮,就能够采用Inline-Block
:
样式为:
//HTML <p> //some words <a href="#">More...</a> </p> //CSS a{ display: inline-block; width: 80px; height: 40px; line-height: 40px; text-align: center; background-color: black; color: white; border-radius: 4px; text-decoration: none; }
效果以下,这样就能够赋予自己为内联标签的a
标签以块级标签特性了:
全部HTML
元素均可以经过更改display
属性将它设置为Blcok
、Inline
、Inline-Block
;
改写以下样式:
//HTML <div>Block</div> <span>Inline</span> <br> <strong>Inline-block</strong> //CSS div{ width: 50%; } span{ } strong{ display: inline-block; } div, span, strong{ background-color: black; color: white; }
效果以下:
随后给body添加样式:
body{ text-align: center }
能够看到Inline
与Inline-Blick
元素都水平居中了,而block
元素只是将里面的文字居中了,block
元素自己并无居中:
这是由于Inline与Inline-Blick两者的容器的大小都是由内容决定,因此text-align:center
对整个元素都有效;而对Block
元素无效,只对该元素内部的文字有效。要想让block
元素和其中内容都居中,须要设置block
元素的margin
样式:
div{ width: 50%; margin-left: auto; margin-right: auto; }
此时就能达到水平居中了:
总结:居中方法:
Inline与Inline-Blick:
body{ text-align: center }
Block:
body{ text-align: center } div{ width: 50%; margin-left: auto; margin-right: auto; }
CSS Box Model
一共包括了四种属性:Content
、Padding
、Border
和Margin
。
它们的结构和排序顺序是这样的:
由内往外分别是:content
、padding
、border
、margin
。
关于margin
与padding
:
在标准盒子模型中,Width = content
;
也就是说只要改变了content
、padding
、border
、margin
中的任一个值,都会撑大整个盒子。
在怪异盒子模型中,Width = content + padding + border + margin
;
一旦设置了元素的width
大小后,至关于固定了整个盒子的大小。再去改变上面的四个属性,盒子总体的大小不变,四个属性自动调整。
利用这一特性,就能够随便更改盒子的margin
、content
、padding
、border
属性值而不用担忧撑大盒子了。
盒子默认为标准盒子模型,即box-sizing:content-box;
能够经过:box-sizing:border-box
,来将它设置为怪异盒子模型。
margin
时:只会左右生效,上下会失效:使用padding
时:上下左右都生效,只不过只有左右隔开了,改变了布局;上下没有改变布局,只是覆盖了:
能够这样记忆,inline
元素的margin
和padding
属性都不会影响垂直方向上的布局。
inline-block
元素的margin
和paddind
属性在上下左右四个方向上都会生效:
上下排列的两个块级元素,分别设置margin-bottom
和margin-top
;总体的空隔取两者的最大值,而不会叠加;解决方法为:在中间加入一个有高度的元素,好比1px
的border
(一般经过为元素::after
添加);
先来看看采用瀑布流布局的典型例子:Pinterest
:世界上最大的图片社交分享网站。
最简单实现的方法是使用别人写好的插件好比:
Masonry.js
lsotope.js
它们实现的原理是经过javascript
计算一共有多少个方格,在计算每个方格的宽度和高度,因容器的宽度能够放置多少列等等要求。将所有方格的position
都设置为absolute
,逐一计算它们的top
和left
实现定位。
因为全部方格的位置是计算出来的,当页面宽度变化时能够实现动态地从新排列。
下面介绍使用纯CSS
实现瀑布流的两种方法,并分析它们的限制:
方法一:仅适用column-count
和column-gap
两个属性实现
代码为:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Column 实现瀑布流布局</title> <style> body{ margin: 4px; font-family: Helvetical; } .masonry{ column-count: 4; column-gap: 0; } .item{ padding: 2px; position: relative; /*给每张图片加上编号*/ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /*给每张图片加上编号*/ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) } </style> </head> <body> <!-- 方法一:仅适用column-count和column-gap两个属性实现 --> <div class="masonry"> <!-- 经过picsum获取随机图片,并随机设置一下每张图片的尺寸 --> <div class="item"> <img src="https://picsum.photos/360/460?random=1" alt=""> </div> <div class="item"> <img src="https://picsum.photos/320/260?random=2" alt=""> </div> <div class="item"> <img src="https://picsum.photos/100/160?random=3" alt=""> </div> <div class="item"> <img src="https://picsum.photos/310/400?random=4" alt=""> </div> <div class="item"> <img src="https://picsum.photos/260/360?random=5" alt=""> </div> <div class="item"> <img src="https://picsum.photos/370/480?random=6" alt=""> </div> <div class="item"> <img src="https://picsum.photos/320/260?random=7" alt=""> </div> <div class="item"> <img src="https://picsum.photos/330/440?random=8" alt=""> </div> <div class="item"> <img src="https://picsum.photos/150/220?random=9" alt=""> </div> <div class="item"> <img src="https://picsum.photos/230/230?random=10" alt=""> </div> </div> </body> </html>
效果为:
优势:代码简单,只须要使用column-count
和column-gap
两个属性便可;
缺点:图片的排列顺序是从第一列的上到下,再到下一行的上到下;
沿用第一种方法的HTML
结构,更改样式以下:
body{ margin: 4px; font-family: Helvetical; } .masonry{ /* 这样设置后,图片组成的flex-item高度超过1000px就会换一列,向右排列 */ display: flex; flex-direction: column; flex-wrap: wrap; height: 1000px; } .item{ position: relative; width: 20%; padding: 2px; box-sizing: border-box; /* 为每一个item加上编号 */ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /* 为每一个item加上编号 */ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) }
此时效果与第一种方法一致:
不过,能够经过flex
布局中的order
属性,更改它的排序顺序。添加以下样式:
body{ margin: 4px; font-family: Helvetical; } .masonry{ /* 这样设置后,图片组成的flex-item高度超过1000px就会换一列,向右排列 */ display: flex; flex-direction: column; flex-wrap: wrap; height: 1000px; } .item{ position: relative; width: 25%; padding: 2px; box-sizing: border-box; /* 为每一个item加上编号 */ counter-increment: item-counter; } .item img{ display: block; width: 100%; height: auto; } /* 为每一个item加上编号 */ .item::after{ position: absolute; display: block; top: 2px; left: 2px; width: 24px; height: 24px; text-align: center; line-height: 24px; background-color: #000; color: white; content:counter(item-counter) } /* 选取第一行的item,当n=0~3时,能够选取到一、五、九、13 */ .item:nth-child(4n+1){ order: 1; } /* 选取第二行的item,当n=0~3时,能够选取到二、六、十、14 */ .item:nth-child(4n+2){ order: 2; } /* 选取第三行的item,当n=0~3时,能够选取到三、七、十一、15 */ .item:nth-child(4n+3){ order: 3; } /* 选取第四行的item,当n=0~3时,能够选取到四、八、十二、16 */ .item:nth-child(4n){ order: 4; }
效果为:
这种方法主要使用了Flex
中的order
属性;
存在的问题:须要设置Flex
容器的高度。因此咱们须要知道内容加起来的高度是多少。还要考虑要分为多少个竖行。去为Flex
容器计算一个合理的高度。好比改变页面的宽度,会出现只须要三个竖行就能容纳图片的状况:
而这种状况咱们是不但愿看到的;
综上所述:要实现瀑布流简单时可使用column,完美实现时还需采用js套件。
元老级的布局属性,几乎不存在兼容性问题,连IE6
也支持。
Float
最初是为了解决"绕图排文"问题设计的。不使用Float
时:
<img src="https://picsum.photos/200/200"/> <p>一段文字</p>
效果为:
为加上
float
属性就能够实现"绕图排文"了:
img{ float:left;// 脱离文档流 display: block;// join文档流 margin-right:20px; }
设置样式:
//HTML <div class="container"> <div class="left">一段文字</div> <div class="middle">一段文字</div> <div class="right">一段文字</div> </div> <p> 一段文字 </p> //CSS .left .middle .right{ background-color:yellow; } .right{ float:left; width:33.3%; } .left{ float:left; width:33.3%; } .right{ float:left; width:33.3%; }
此时的效果为(大体):
三个浮动的div
并无由于被container
div 包裹着而与p
标签隔开,这是由于,三个div
都浮动起来了,与container
div 不在一个平面上。就好像橡胶圈同样container
捆不住这些浮动的div
,因此会出现这样的状况,即container
div 出现了元素坍塌;
为了恢复正常就须要清除父容器container
div 中子元素的浮动了,有如下三种方法:
第一:clearfix
这个类的做用为结束float
继续影响后续内容的排版;使用方法为在父容器container
div 同一层加上一个块级元素,再添加以下的样式:
//HTML <div class="container"> </div> <div class="clearfix"></div> //CSS .clearfix{ clear:both; }
如今,排版就正确了:
这种方式并不优雅,不经过添加HTML
块级标签,而是经过伪类after
的方式添加,样式以下:
//HTML <div class="container"> </div> //CSS .container::after{ content: ''; clear:both; display:block; }
第二:overflow
只须要将父容器container
div 的overflow
属性设置为visible
之外的任何一个值,好比auto
或hidden
。
//HTML <div class="container"> </div> //CSS .container{ overflow:auto; }
此时这个container
div 就会变成一个BFC
(Block Formatting Context
:块级可视化上下文),BFC
会造成一个局部的块级,达到"隔断"的效果。
第三:display
为父容器container
div 添加display:flow-root;
便可将其变成一个BFC
。
//HTML <div class="container"> </div> //CSS .container{ display: flow-root; }
不过这个属性较新,而且全部的IE版本都不支持:
响应式布局指的是网页会因不一样设别的屏幕大小,例如电脑、手机、平板等设备。自动调整版面布局,图片及字体大小等。使网页适应在不一样大小的荧幕下显示。
分别有如下几个方面:
能够经过设置Media Query
的Breakpoint
(断点),而且设置当符合这个Breakpoint
的时候,改变CSS
样式。
例如:
@media screen and (max-width: 360px){ }
在上面的设定中,screen
指有屏幕的设备;max-width: 360px
表示Query
或是叫Breakpoint
,指屏幕最大宽度为360px
;经过and
组合起来就是:当设备有屏幕,而且最大宽度为360px
如下的状况下,触发花括号内的CSS
样式。
还能够设置屏幕宽度较宽时的样式:
@media screen and (min-width: 960px){ }
上述设置指的是,屏幕宽度大于960px
的状况下触发花括号内的CSS
。
至于Breakpoint
应该如何设定,各个CSS
框架有本身的规定:
tailwindcss
// tailwind.config.js module.exports = { theme: { screens: { 'sm': '640px', // => @media (min-width: 640px) { ... } 'md': '768px', // => @media (min-width: 768px) { ... } 'lg': '1024px', // => @media (min-width: 1024px) { ... } 'xl': '1280px', // => @media (min-width: 1280px) { ... } } } }
tailwindcss
将Breakpoint
设置为了640px
、768px
、1024px
、1280px
;
Bootstrap
/* 超小屏幕(手机,小于 768px) */ /* 没有任何媒体查询相关的代码,由于这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */ /* 小屏幕(平板,大于等于 768px) */ @media (min-width: @screen-sm-min) { ... } /* 中等屏幕(桌面显示器,大于等于 992px) */ @media (min-width: @screen-md-min) { ... } /* 大屏幕(大桌面显示器,大于等于 1200px) */ @media (min-width: @screen-lg-min) { ... }
Bootrap
将Breakpoint
设置为了768px
、 992px
、1200px
;
它是一个写在HTML
head 标签里面的 meta
标签。这个设定是为了告诉手机浏览器,将网页的宽度设定为手机屏幕的宽度。
<head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head>
这个标签是告诉手机浏览器,这个网页是支持响应式的。只有加上了这个标签媒体查询(Media Query
)对于小屏幕宽度的设定才会生效;
若是你的显示器不是高清的,解像度设置为1920 x 1080
;则表示屏幕横向由1920
个点组成,纵向由1080
个点组成。
而若是是高清屏幕,一个单位解像度就是有多个点组成的。
为了在屏幕中显示足够清晰的图片,就须要将图片的尺寸放大两倍到三倍;
如何作到在屏幕中显示高清图像?最简单的作法就是将600px * 600px
的图片以300px * 300px
的大小显示。
为了显示高清图像,咱们能够提供同一张图片的三种尺寸(1x
、2x
、3x
)。好比显示图片的框大小为300px * 300px
:
<picture> <source srcset="https://placehold.it/600x600 2x, https://placehold.it/900x900 3x"> <img src="https://placehold.it/300x300"> </picture>
这样设备就会根据高清支持程度加载对应的尺寸的图片了,如支持2x
高清显示的就加载尺寸为600px * 600px
的图片;
当屏幕大小发生变化时,字体大小也应该跟着变化。因此推荐使用相对单位rem
和vh/vw
;
部分参考自CodingStartup起码课