阅读 3896

可食用的「css布局干货」,纯Html示例,可调试 | 水平、垂直、多列

你们都不看的总集篇: 从零开始的大前端筑基之旅(深入浅出,持续更新~)
觉得不错就顺手点个赞吧

本篇文章仅整理常用的水平居中、垂直居中及多列等布局,不求全部涉及,只考虑常用并且可以顺手拿来使用。若有其他精妙的方案,欢迎在评论中指出,我会及时补充至文档内。

本文中所有示例均为 html 渲染构成,没有图片及外链demo,所以可以直接选中示例在控制台调试,推荐自己动手试试文章中列举的小提示,有助于加深理解 。

最后,1个赞顶100阅读量,告诉我你曾来过、看过,并在这里不虚此行吧!!

水平居中

text-align: center;

适用于行内内容(文字、行内元素、行内块级元素)

<div class="container">
  this is inner text
  <div classs="ele1">
    this is a block element
  </div>
  <div classs="ele2">
      this is another block element
  </div>
</div>
复制代码
.container{
  width: 300px;
  border: 1px solid grey;
  text-align: center;
}
.ele2{
  border: 1px solid grey;
  width: 200px;
}
复制代码
this is inner text
this is a block element
this is another block element

属性会被继承,影响到后代元素行内内容;

  • ele1的块级元素显示文字居中是因为其宽度默认100%,与container一致,
  • Ele2内部文字居中是因为继承了container的属性,若想要ele2本身居中,设置 display: inline-block 转为行内块或设置 margin: 0 auto

如果子元素宽度大于父元素宽度则无效

margin: 0 auto;

要求目标元素宽度固定,并且与父元素左右margin有空余。

适用于父元素内有多个块级元素上下排列的情况

<div class="container">
  this is inner text
  <div classs="ele2">
      this is another block element
  </div>
</div>
复制代码
.container{
  width: 300px;
  border: 1px solid grey;
  text-align: center;
}
.ele2{
  border: 1px solid grey;
  width: 200px;
  margin:0 auto;
}
复制代码
this is inner text
this is another block element

如果上下的margin设置了auto,其计算值为0

绝对定位

绝对定位会导致元素不在文档流中,需要处理父元素的高度,防止高度塌陷

top、right、bottom、left的值是相对于父元素尺寸的,

absolute + transform

transform设置百分比参数是相对于自身尺寸的

<div class="container">
   this is inner text
  <div class="ele1">
    this is a block element
  </div>
</div>
复制代码
.container{
    height: 100px;
    width: 200px;
    position: relative;
    border: 1px solid grey;
  	text-align: center;
}
.ele1{
    position: absolute;
    left: 50%;
    transform: translateX(-50%);  
    width: 100px; // 此处可以不设置,默认为父元素一半宽度
    border: 1px solid #888;
}
复制代码
this is inner text
this is a block element

ele1可以不设定width的值,此时ele1的宽度会被计算为 父元素的一半 - 左右边框的宽度

absolute + margin

margin设置百分比参数是相对于父元素的,所以,此方法需要子元素固定宽度,并且值设为自身宽度的一半;

html代码同上,替换 ele1 元素样式中 transform: translateX(-50%)margin-left: -50px;

.ele1{
    position: absolute;
    left: 50%;
    margin-left: -50px; // 负值,设为元素自身宽度的一半
    width: 100px; // 此处必须设置
    border: 1px solid #888;
}
复制代码
this is inner text
this is a block element

flex

flex默认水平轴为主轴,设置当前主轴对齐方式为居中

<div class="container">
  <div class="ele1">
    this is a block element
  </div>
</div>
复制代码
.container{
    height: 200px;
    width: 220px;
    display: flex;
    justify-content: center;
    border: 1px solid grey;
}
.ele1{
    width: 100px;
    height: 100px;
    border: 1px solid #888;
}
复制代码
this is a block element

ele1未设置宽高时,子元素宽度会自动适配内容的大小,高度会填满父元素

垂直居中

vertical-align

  • 使行内元素盒模型与其行内元素容器垂直对齐。例如,用于垂直对齐一行文本内的图片
  • 垂直对齐表格单元内容

仅用于同一行 内的元素水平对齐,不用于相对父元素的垂直居中,如下面示例

 <div class="container">
  <div class="ele1">this is inner text</div>
  <div class="ele">inline-block</div>
</div>
复制代码
.container{
    width: 220px;
    height: 50px;
    vertical-align: middle;
    border: 1px solid grey;
}
.ele{
   border: 1px solid grey;
   height :30px;
   display: inline-block;
}
.ele1{
  vertical-align: middle;
  display: inline-block;
}
复制代码
this is inner text
inline-block

ele1 通过设置高度撑起了一行,ele 元素设置 vertical-align: middle 来与 ele1 对齐 。但是整行元素并未相对父元素对齐。

如果父元素未设置高度或高度与行内最高元素高度一致,则会表现为本行与父元素相对垂直居中。

也可以设置父元素 display: table-cell来使用 vertical-align 作用于表格对齐的特性,但是并不推荐此方法

line-height

适用于 单行文本、行内元素、行内块级元素

多行文本建议使用span包裹成一个子元素

<div class="container">
    this is inner text
</div>
复制代码
.container{
    width: 220px;
    height: 50px;
    line-height: 50px;
    border: 1px solid grey;
}
复制代码
this is inner text

小贴士:

通常情况下,如果一个未设置高度的div内部有文字,div的高度就会是文字的高度,可能有人会跟认为是:文字撑开的!文字占据空间,自然将div撑开。但实际上,根本不是文字撑开了div的高度,而是line-height!

如果一个标签没有定义height属性(包括百分比高度),那么其最终表现的高度一定是由line-height起作用

换种理解方式,如果一个有文字的div,不设置高度,并将其行高设置0,div将不会被撑开。

<div class="container">
  <div class="ele">
    this is inner text
  </div>
  <div class="ele1">
    this is inner text
  </div>
</div>
复制代码
.container{
    width: 220px;
    height:100px;
    border: 1px solid grey;
}
div{
   margin-top: 20px;
   border: 1px solid grey;
}
.ele{
 line-height:0;
}
复制代码
this is inner text
this is inner text

因此,对于本节最开始的栗子,去掉 containerheight属性,不会产生任何影响。可以打开控制台自己尝试一下。

绝对定位

绝对定位会导致元素不在文档流中,需要处理父元素的高度,防止高度塌陷

top、right、bottom、left的值是相对于父元素尺寸的,

absolute + transform

transform设置百分比参数是相对于自身尺寸的 代码同水平居中,css替换为

top: 50%;
transform: translateY(-50%);  
复制代码

absolute + margin

同水平居中,css替换为

top: 50%;
margin-top: -50px; // 负值,设为元素自身宽度的一半
复制代码

absolute + margin: auto

前面说过,如果上下的margin设置了auto,其计算值为0。这是子元素未设置绝对定位的情况。

将子元素设置绝对定位,top、right、bottom、left都设为0

 <div class="container">
  <div class="ele">
    this is block element<
  /div>
</div>
复制代码
.container{
    width: 200px;
    height: 120px;
    position: absolute;
    border: 1px solid grey;
}
.ele{
    width: 70px;
    height: 80px;
    border: 1px solid grey;
    position: absolute;;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
复制代码
this is block element

子元素必须定高定宽

flex

flex默认水平轴为主轴,设置当前纵轴对齐方式为居中

<div class="container">
  <div class="ele1">
    this is a block element
  </div>
</div>
复制代码
.container{
    height: 200px;
    width: 220px;
    display: flex;
    align-items: center;
    border: 1px solid grey;
}
.ele1{
    width: 100px;
    height: 100px;
    border: 1px solid #888;
}
复制代码
this is a block element
> 若ele1未设置宽高,子元素宽度与高度会自动适配内容的大小,可以直接打开控制台试试

writing-mode

定义了文本水平或垂直排布以及在块级元素中文本的行进方向。

通过writing-mode让文字的显示变为垂直方向,可以使水平方向上的css属性,变为垂直方向上的属性

<div class="container">
  <div class="ele1">
   block element
  </div>
</div>
复制代码
.container{
    height: 200px;
    width: 200px;
    writing-mode: vertical-lr;
    border: 1px solid grey;
    text-align: center;
}
.ele1{
    display: inline-block;
    border: 1px solid #888;
}
复制代码
block element

水平垂直居中

这个就不用讲了吧

多列布局

仿window文件夹布局

适用于内部item定宽,多个item平铺于父元素。

  • 内部子元素宽度固定
  • 超出自动换行
  • 自适应父元素宽度
<div class="parent">
  <div class="container">
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
    <div class="ele">
     element
    </div>
  </div>
</div>
复制代码
.parent{
  box-sizing: border-box;
  border: 1px solid grey;
  width: 392px;
}
.container{
    box-sizing: border-box;
    display: flex;  
    flex-wrap: wrap;
    margin-right: -10px;
}
.ele{
    box-sizing: border-box;
    background: #ccc;
    width: 90px;
    height: 40px;
    line-height: 40px;
    margin-right: 10px;
    margin-bottom: 10px;
}

复制代码
element
element
element
element
element
element
element
element
element

上面示例中,多个ele水平排列,每一行显示个数与parent的宽度有关,增加或减少parent的宽度,每行显示个数会自动改变。可以选中元素打开控制台试试。

解释:

  1. container使用flex布局,设置 flex-wrap: wrap; 超出折行显示
  2. parent宽度为 (ele.width + ele.marginRight) * 4 - ele.marginRight 时,每行刚好显示4个子元素。
  3. 上一条的参数可以实现 justify-content: space-between 效果,但又不会导致某一行不够4个时的样式错位
  4. container 本身不设置宽度,利用内部元素撑开,同时设置 margin-right: -10px 会使 container在原有宽度的基础上增加10px的大小,刚好包容每行最后一个 elemarginRight

小知识:

  1. margin的left、right为负值时,若元素本身没有宽度,则会增加元素宽度
  2. 元素本身有宽度,会产生位移
  3. margin-top 为负值,不管是否设置高度,都不会增加高度,而是会产生向上的位移
  4. margin-bottom 为负值的时候不会位移,而是会减少自身供css读取的高度
  • 若需要两列或多列布局,可以视具体情况通过改变 parentele 的宽度来调整

其他布局待补充:

如果你收获了新知识,或者收获了左侧精美图片,请点个吧~

相关系列: 从零开始的大前端筑基之旅(深入浅出,持续更新~)

推荐阅读

参考文章:

  1. CSS实现水平垂直居中的1010种方式(史上最全)
  2. 干货!各种常见布局实现+知名网站实例分析
  3. css行高line-height的一些深入理解及应用