chenshuhong / fullstack

我的全栈路线思维导图以及日常知识记录
MIT License
0 stars 0 forks source link

CSS布局 #13

Open chenshuhong opened 5 years ago

chenshuhong commented 5 years ago

水平居中

文本/行内元素/行内块级元素

原理:text-align只控制行内内容(文字、行内元素、行内块级元素)如何相对他的块父元素对齐

#parent{
    text-align:center;
}

若是多个块级元素,需要改为行内或者行内块级元素

.son{
    display:inline-block;
}

优点:简单快捷,容易理解,兼容性非常好 缺点:只对行内元素有效;属性会继承影响到后代行内内容;如果子元素宽度大于父元素宽度则无效,但是后代行内内容中宽度小于设置text-align属性的元素宽度的时候,也会继承水平居中,块级改为inline-block换行、空格会产生元素间隔

单个块级元素

有这么一种情况:在margin有节余的同时如果左右margin设置了auto,将会均分剩余空间。另外,如果上下的margin设置了auto,其计算值为0

#son{
    width:100px;/*必须定宽*/
    margin:0 auto;
}

优点: 简单,兼容性好 缺点: 必须定宽,宽度要小于父元素,否则无效

使用绝对定位实现

子绝父相,top、right、bottom、left的值是相对于父元素尺寸的,然后margin或者transform是相对于自身尺寸的,组合使用达到水平居中的目的

#parent{
    height: 200px;
    width: 200px;  /*定宽,不定宽都可以*/
    position: relative;  /*父相*/
    background-color: #f00;
}
#son1{
    position: absolute;  /*子绝*/
    left: 50%;  /*父元素宽度一半,这里等同于left:100px*/
    transform: translateX(-50%);  /*自身宽度一半,等同于margin-left: -50px;*/
    width: 100px;  /*可以不定宽*/
    height: 100px;
    background-color: #00ff00;
}
#son2{
    position: absolute;  /*子绝*/
    left: 50%;  /*父元素宽度一半,这里等同于left:100px*/
    margin-left: -50px;  /*自身宽度一半,等同于margin-left: -50px;*/
    width: 100px;  /*一定要定宽*/
    height: 100px;
    background-color: #00ff00;
}

优点:使用margin-left兼容性好;不管是块级还是行内元素都可以实现 缺点:代码较多;脱离文档流;使用margin-left需要知道宽度值;使用transform兼容性不好(ie9+)

flex实现

原理:就是设置当前主轴对齐方式为居中

#parent{
    display: flex;
    justify-content: center;
}

优点:功能强大;简单方便;容易理解 缺点: PC端兼容性不好,移动端(Android4.0+)

小结

chenshuhong commented 5 years ago

垂直居中

单行文本/行内元素/行内块级元素

原理:line-height的最终表现是通过inline box实现的,而无论inline box所占据的高度是多少(无论比文字大还是比文字小),其占据的空间都是与文字内容公用水平中垂线的。

#parent{
    height:150px;
    line-height:150px;
}

优点:简单;兼容性好 缺点: 只能用于单行行内内容;要知道高度的值

图片

#parent{
    height: 150px;
    line-height: 150px;
    font-size: 0;
}
img#son{
    vertical-align: middle;
} /*默认是基线对齐,改为middle*/

优点:简单;兼容性好; 缺点: 需要添加font-size: 0; 才可以完全的垂直居中;html#parent包裹img之间需要有换行或空格

单个块级元素

子绝父相实现

类似水平居中的一个实现不过left改为top,margin-left改为margin-top,translateX改为translateY,此外,还可以这样实现,当top、bottom为0时,margin-top&bottom会无限延伸占满空间并且平分

#parent{position: relative;}
#son{
    position: absolute;
    margin: auto 0;
    top: 0;
    bottom: 0;
    height: 50px;/*需要定高*/
}

flex实现单行或者多行

#parent{
    display: flex;
    align-items: center;
}
/*或*/
#parent{
    display: flex;
    flex-direction: column;
    justify-content: center;
}
/*或*/
#parent{display: flex;}
#son{align-self: center;}
/*或
原理:这个尚未搞清楚,应该是flex使margin上下边界无限延伸至剩余空间并平分了,只适合单行
*/
#parent{display: flex;}
#son{margin: auto 0;}

小结

chenshuhong commented 5 years ago

两列布局

左列定宽,右列自适应

利用float+margin/overflow实现

<div id="left">左列定宽</div>
<div id="right">右列自适应</div>
#left {
    background-color: #f00;
    float: left;
    width: 100px;
    height: 500px;
}
#right {
    background-color: #0f0;
    height: 500px;
    margin-left: 100px; /*或者overflow: hidden*/
}

绝对定位实现

<div id="parent">
    <div id="left">左列定宽</div>
    <div id="right">右列自适应</div>
</div>
#parent{position: relative;}  /*父相*/
#left {
    position: absolute;  /*子绝*/
    top: 0;
    left: 0;
    background-color: #f00;
    width: 100px;
    height: 500px;
}
#right {
    position: absolute;  /*子绝*/
    top: 0;
    left: 100px;  /*值大于等于#left的宽度*/
    right: 0;
    background-color: #0f0;
    height: 500px;
}

flex

html同上

#parent{
    width: 100%;
    height: 500px;
    display: flex;
}
#left {
    width: 100px;
    background-color: #f00;
}
#right {
    flex: 1; /*均分了父元素剩余空间*/
    background-color: #0f0;
}

Grid

html同上

#parent {
    width: 100%;
    height: 500px;
    display: grid;
    grid-template-columns: 100px auto;  /*设定2列就ok了,auto换成1fr也行*/
}
#left {background-color: #f00;}
#right {background-color: #0f0;}

左列自适应,右列定宽

float+margin

html同上

#parent{
    height: 500px;
    padding-left: 100px;  /*抵消#left的margin-left以达到#parent水平居中*/
}
#left {
    width: 100%;
    height: 500px;
    float: left;
    margin-left: -100px; /*正值等于#right的宽度*/
    background-color: #f00;
}
#right {
    height: 500px;
    width: 100px;
    float: right;
    background-color: #0f0;
}

float + overflow

<div id="parent">
    <div id="right">右列定宽</div>
    <div id="left">左列自适应</div>   <!--顺序要换一下-->
</div>
#left {
    overflow: hidden;  /*触发bfc*/
    height: 500px;
    background-color: #f00;
}
#right {
    margin-left: 10px;  /*margin需要定义在#right中*/
    float: right;
    width: 100px;
    height: 500px;
    background-color: #0f0;
}

优点:代码简单,容易理解,无需关注定宽的宽度,利用bfc达到自适应效果 缺点: 浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;不支持ie6

绝对定位

类似上面的左固定右不定

flex

类似上面的左固定右不定

Grid

类似上面的左固定右不定

一列不定,一列自适应(盒子宽度随着内容增加或减少发生变化,另一个盒子自适应)

float+overflow

类似上面

flex

类似上面

Grid

#parent{
    display: grid;
    grid-template-columns: auto 1fr;  /*auto和1fr换一下顺序就是左列自适应,右列不定宽了*/
}
chenshuhong commented 5 years ago

三列布局

两列定宽,一列自适应

利用float+margin/overflow实现

同上

flex

同上

Grid

也基本同上

grid-template-columns: 100px 200px auto; /*设置3列,固定第一第二列的宽度,第三列auto或者1fr*/

两侧定宽,中间适应

双飞翼布局方法

<div class="center">
  <div class="center_inbox">center</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
.left{
  float:left;
  width:100px;
  background:pink;
  height:100px;
  margin-left:-100%;/*关键,使其同一行*/
}
.center{
  float:left;
  height:200px;
  width:100%;
  background:orange;
}
.right{
  float:left;
  background:gray;
  height:150px;
  width:150px;
  margin-left:-150px;/*关键,使其同一行*/
}
.center_inbox{
  height:80%;
  background:blue;
  margin:0 150px 0 100px;/*关键,使其左右间隔*/
}

圣杯布局方法

<div class="box">
  <div class="center">
    center
  </div>
  <div class="left">
    left
  </div>
  <div class="right">
    right
  </div>
</div>
.box {
  box-sizing: border-box;/*关键,使其设置padding不影响宽度*/
  height: 200px;
  background: orange;
  padding: 0 150px 0 100px;/*关键,设置padding实现左右*/
}

.left {
  float: left;
  width: 100px;
  background: pink;
  height: 200px;
  margin-left:-100%;
  position:relative;
  left:-100px;/*关键,使其设置靠左*/
}

.right {
  float: left;
  background: gray;
  height: 150px;
  width: 150px;
  margin-left: -150px;
  position:relative;
  right:-150px;/*关键,使其设置靠右*/
}
.center{
  float:left;
  width:100%;
  height:100px;
  background:blue;
}

flex,很简单,中间flex-grow设置为1即可

子绝父相,很简单

chenshuhong commented 5 years ago

多列布局

等宽布局

1.float
<div id="parent">
    <div class="column">1</div>
    <div class="column">2</div>
    <div class="column">3</div>
    <div class="column">4</div>
</div>
#parent{
  background:gray;
}
#parent:after{
  content:'';
  display:block;
  clear:both;
}
.column{
  float:left;
  width:25%;
  background:pink;
  box-sizing:border-box;
  border:1px solid blue;
  padding-left:10px;
  background-clip:content-box;
}

2.flex,设置flex-grow为1即可

九宫格布局

1.display:table

2.flex

3.grid