学习布局的各种方式
外边距折叠:块级元素的上外边距和下外边距有时会合并(或折叠)为一个外边距,其大小取其中的最大者。注意浮动元素和绝对定位元素的外边距不会折叠。会发生外边距折叠的三种情况:
box-sizing
:当你设置一个元素为box-sizing: border-box;
时,此元素的内边距和边框不再会增加它的宽度。这个属性支持IE8+
position:static;
position: relative;
:与静态定位相似,占据在正常的文档流中,可以修改它的最终位置,让它与页面上的其他元素重叠。修改元素的位置:使用top
,bottom
,left
,right
。在使用相对定位时,就算元素被偏移了,但是他仍然占据着它没偏移前的空间。position: absolute;
:绝对定位的元素不再存在于正常文档布局流中。z-index
:网页上有一个Z轴——一条从屏幕表面到你的脸的虚线。z-index
值影响定位元素位于该轴上的位置——正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。z-index只接受无单位索引值。fixed
,不会保留它原本页面应有的空隙(脱离文档流)。与绝对定位的工作方式完全相同,只有一个区别——绝对定位固定元素是相对于
元素或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。position: sticky;
相对位置和固定位置之间的混合,其允许定位的元件像它被相对定位一样动作,直到其滚动到某一阀值点,之后它变得固定。所谓的“单页应用”正在变得非常流行,尤其是移动网页UI,因为把一切的服务放在一个单独的文件上可以减少HTTP请求的数量来浏览所有内容,从而提高性能。
checkbox hack
技术:可以提供无JS的方法来控制一个元素,通过一个按钮的联系。
// 核心代码,将表单元素的状态与其他标签绑定在一起
input[type="checkbox"]:checked + aside {
}
display
属性的值为inline-flex
flex模型
display: flex
的父元素被称之为flex容器(flex container)。flex-direction
:指定主轴的方向(弹性盒子子类放置的地方),默认值是row
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
flex-wrap
:如果一条轴线排不下,如何换行
.box {
flex-wrap: nowrap (默认,不换行) | wrap (换行,第一行在上方) | wrap-reverse (换行,第一行在下方)
flex-flow
:是flex-direction
属性和flex-wrap
属性的简写flex: 1;
:这是一个无单位的比例值,表示每个flex项沿主轴的可用空间大小flex: 1 200px;
表示每个flex项将首先给出200px的可用空间,然后,剩余的可用空间将根据分配的比例共享。flex-grow
:无单位比例,定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大,如果所有的flex-grow
属性都为1,则它们将等分剩余空间。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。flex-shrink
:无单位比例,定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink
属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。flex-basis
:定义了在分配多余空间之前,项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。align-items
:定义项目在交叉轴上如何对齐 stretch
:默认,是所有flex项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有flex项将变得与最长的flex项一样长(即高度保持一致)。flex-start
:交叉轴的起点对齐flex-end
:交叉轴的终点对齐center
:交叉轴的中点对齐baseline
:项目的第一行文字的基线对齐align-self
:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承align-items
属性,如果没有父元素,则等同于stretch
justify-content
:定义项目在主轴上的对齐方式 flex-start
:默认值,左对齐flex-end
:右对齐center
:居中space-between
:两端对齐,项目之间的间隔都相等,不会在两端留空间。space-around
:每个项目两侧的间隔相等。会在两端留空间。order
:定义项目的排序顺序,数值越小,排列越靠前,默认为0。相同order值的flex项按源顺序显示。block
:块级元素inline
:行内元素none
:一些特殊元素的默认display值是它,例如script
。display: none
通常被JS用来在不删除元素的情况下隐藏或显示元素。它和visibility
属性不一样。把display
设置成none
元素不会占据它本来应该显示的空间,但是设置成visibility: hidden
还会占据空间inline-block
vertical-align
属性会影响到inline-block
元素,你可能会把他的值设置为top
清除浮动
overflow: auto;
想支持IE6,加上zoom: 1;
overflow: hidden;
:这样父元素就有高度了,父元素的高度便不会被破坏。clear: both;
:通过在所有浮动元素下方添加一个clear: both;
的元素,可以消除float的破坏性clearfix
:定义一个.clearfix
类,然后对float元素的父元素应用这一样式即可
.clearfix:after {
content: '';
display: block;
clear: both;
}
.clearfix {
*zoom: 1;
}
BFC全称“Block Formatting Context”,中文为“块级格式化上下文”。BFC元素特性表现原则就是,内部子元素再怎么翻江倒海,翻云覆雨都不会影响外部的元素。
什么时候会触发BFC呢?常见的如下:
float
的值不为none
。overflow
的值为auto
,scroll
或hidden
。display
的值为table-cell
,table-caption
,inline-block
中的任何一个。position
的值不为relative
和static
。“响应式设计”是一种让网站针对不同的浏览器和设备“呈现”不同显示效果的策略
媒体查询就是做此事所需的最强大的工具。
块级元素
定宽
margin: 0 auto;
唯一的问题是:当浏览器窗口比元素的宽度还要窄时,浏览器会显示一个水平滚动条来容纳页面
改进方案:使用max-width
替代width
可以使浏览器更好地处理小窗口的情况。所有的主流浏览器包括IE7+在内都支持max-width
、、)。
- 为这个table设置“左右margin居中”(这个和定宽块状元素的方法一样)。
- 设置display:inline:改变块级元素的display为inline类型(设置为行内元素显示),然后使用
text-align:center
来实现居中效果。
- 设置position:relative和left:50%:利用相对定位的方式,将元素向左偏移50%,即达到居中的目的
- 行内元素:如果被设置元素为文本、图片等行内元素时,在父元素中设置
text-align: center;
实现行内元素水平居中
垂直居中设置
- 父元素高度确定的单行文本
通过设置父元素的height和line-height高度一致来实现的。(height:该元素的高度,line-height:顾名思义,行高(行间距),指在文本中,行与行之间的基线间的距离)。
弊端:当文字内容的长度大于块的宽时,就有内容脱离了块。
- 父元素高度确定的多行文本
- 方法一:使用插入table(包括tbody、tr、td)标签,同时设置vertical:middle
- 方法二:在chrome、firefox及IE8以上的浏览器下可以设置块级元素的display为table-cell(设置为表格单元显示),激活vertical-align属性,但注意IE6、7并不支持这个样式,兼容性比较差。
不知道自己高度和父容器高度的情况,利用绝对定位只需要以下三行:
parentElement {
position: reletive;
}
childElement {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
若父容器下只有一个元素,且父元素设置了高度,则只需要使用相对定位即可
prentElement {
height: xxx;
}
childElement {
position: reletive;
top: 50%;
transform: translateY(-50%);
}
不考虑兼容老式浏览器的话,用Flex布局简单直观一劳永逸:
parentElement{
display:flex;/*Flex布局*/
display: -webkit-flex; /* Safari */
align-items:center;/*指定垂直居中*/
}
水平垂直居中
单行文本
text-align: center;
line-height: 100px;
子元素是div
Smile
// text-align + vertical-align
.parent {
border: 1px solid black;
display: table-cell;
text-align: center;
vertical-align: middle;
height: 100px;
width: 200px;
}
.child {
display: inline-block;
}
// 相对 + 绝对定位
.parent {
position: relative;
width: 200px;
height: 100px;
}
.child {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 50px;
width: 80px;
margin: auto;
}
- 子元素是图像:可不是用
table-cell
,而是其父元素用行高代替高度,且font-size: 0;
。子元素本身设置vertical-align: middle;
- 如果要居中的元素的宽/高是不变的或者说是确定的,比如width/height=100px,那么设置absolute的top/left=50%,然后margin-left/margin-top=-50px即可
如果要居中的元素的宽/高是不确定的,这时margin负值就不能使用具体的px了,可以使用百分比。但由于margin的百分比都是相对于包含块的宽度,所以这里限制了只能设置宽高相同的居中元素。包含块的宽度如何获得呢?利用absolute的包裹性,在需要居中的元素外面套一个空的元素即可。或者: .parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
如果可以使用flexbox
.parent {
display: flex;
justify-content: center;
align-items: center;
}
如果可以使用grid
body, html {
height: 100%;
display: grid;
}
span { /* thing to center */
margin: auto;
}
布局模型
- 流动模型(Flow)默认
- 浮动模型(Float)
- 层模型(Layer)
- 相对定位
- 绝对定位
- 固定定位
常见的布局
- 一列布局:一般都是固定的宽高,设置
margin: 0 auto
来水平居中,用于界面显著标题的展示等
两列布局:左侧固定,右侧自适应。常用的宽度自适应的方法通常是利用了block
水平的元素宽度能随父容器调节的流动特性。另外一种思路是利用CSS中的calc()
方法来动态设定宽度。还有一种思路是,利用CSS中的新型布局flex layout
与grid layout
。
基本的HTML布局
左边固定宽度,高度不固定。高度可能很小,也可能很大。
这里的内容可能比左侧高,也可能比左侧低。宽度需要自适应
基本的样式:两个盒子相距20px,左侧盒子宽120px,右侧盒子宽度自适应
双inline-block
方案:通过width: calc(100% - 140px)
来动态计算右侧盒子的宽度。需要知道左侧盒子的宽度,两个盒子的距离,还要设置各个元素的box-sizing
;需要消除空格字符的影响;需要设置vertical-align: top;
满足顶端对齐
.wrapper-inline-block {
box-sizing: content-box;
font-size: 0; // 消除空格的影响
}
.wrapper-inline-block .left,
.wrapper-inline-block .right {
display: inline-block;
vertical-align: top; // 顶端对齐
font-size: 14px;
box-sizing: border-box;
}
.wrapper-inline-block .right {
width: calc(100% - 140px);
}
双float
方案:浮动的block
元素在有空间的情况下会依次紧贴,排列在一行
.wrapper-double-float {
overflow: auto; // 清除浮动
box-sizing: content-box;
}
.wrapper-double-float .left,
.wrapper-double-float .right {
float: left;
box-sizing: border-box;
}
.wrapper-double-float .right {
width: calc(100% - 140px);
}
float + margin-left
方案:block
级别的元素会认为浮动的元素不存在,但是inline
级别的元素能识别到浮动的元素。这样,block
级别的元素就可以和浮动的元素同处在一行了。
.wrapper-float {
overflow: hidden; // 清除浮动
}
.wrapper-float .left {
float: left;
}
.wrapper-float .right {
margin-left: 150px;
}
使用absolute + margin-left
方法:使用了绝对定位,若是用在某个div中,需要更改父容器的position
;没有清除浮动的方法,若左侧盒子高于右侧盒子,就会超出父容器的高度。因此只能通过设置父容器的min-height
来放置这种情况
.wrapper-absolute .left {
position: absolute;
}
.wrapper-absolute .right {
margin-left: 150px;
}
使用float + BFC
方法:左侧浮动,右侧盒子通过overflow: auto;
形成了BFC,因此右侧盒子不会与浮动的元素重叠,父元素需要清除浮动
.wrapper-float-bfc {
overflow: auto;
}
.wrapper-float-bfc .left {
float: left;
margin-right: 20px;
}
.wrapper-float-bfc .right {
margin-left: 0;
overflow: auto;
}
flex
方案:可以说是最好的方案了,flex
容器的一个默认属性值:align-items: stretch;
,这个属性导致了列等高的效果,为了让两个盒子高度自动,需要设置align-items: flex-start;
.wrapper-flex {
display: flex;
align-items: flex-start;
}
.wrapper-flex .left {
flex: 0 0 auto;
}
.wrapper-flex .right {
flex: 1 1 auto;
}
grid
方案:可以满足需且,但这并不是它发挥用处的真正地方。注意:grid
布局也有列等高的默认效果,需要设置align-items: start;
.wrapper-grid {
display: grid;
grid-template-columns: 120px 1fr;
align-items: start;
}
.wrapper-grid .left,
.wrapper-grid .right {
box-sizing: border-box;
}
.wrapper-grid .left {
grid-column: 1;
}
.wrapper-grid .right {
grid-column: 2;
}
- 极限情况:
- 动态计算宽度的情况:两种方案:双
inline-block
方案和双float
方案。宽度极限小时,右侧的div宽度会非常小,由于遵循流动布局,所以右侧div会移动到下一行
- 动态计算右侧
margin-left
的情况:两种方案:float + margin-left
方案和absolute + margin-left
方案。宽度极限小时,由于右侧的div忽略了文档流中左侧div的存在,所以其依旧会存在于这一行,并被隐藏
float + BFC
方案的情况下:由于BFC与float的特殊关系,右侧div在宽度减小到最小后,也会掉落到下一行
flex
和grid
情况:默认两种布局方式都不会放下div移动到下一行,不过flex
布局可以通过flex-flow: wrap;
来设置多余的div移动到下一行。grid
布局暂不支持。
三列布局:两侧定宽中间自适应
- 首先设置父级元素的宽度,可以左左右设置浮动,然后中间设置margin调整间距,也可以都设置左浮动,设置margin,调整间距。同样注意清除浮动的影响。
绝对定位法:左右两栏采用绝对定位,分别固定于页面的左右两侧,中间的主体栏用左右margin
值撑开距离。
代码:
// HTML
// CSS