Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 52 题:怎么让一个 div 水平垂直居中 #92

Open
zeroone001 opened this issue Apr 10, 2019 · 26 comments
Open

第 52 题:怎么让一个 div 水平垂直居中 #92

zeroone001 opened this issue Apr 10, 2019 · 26 comments

Comments

@zeroone001
Copy link

zeroone001 commented Apr 10, 2019

<div class="parent">
  <div class="child"></div>
</div>
div.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}
div.parent {
    position: relative; 
}
div.child {
    position: absolute; 
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);  
}
/* 或者 */
div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -25px;
    margin-top: -5px;
}
/* 或 */
div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
div.parent {
    display: grid;
}
div.child {
    justify-self: center;
    align-self: center;
}
div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}
@Feather130
Copy link

Feather130 commented Apr 11, 2019

楼上总结的差不多了。再加一种

div.parent{
  display:flex;
}
div.child{
  margin:auto;
}

@cleverboy32
Copy link

cleverboy32 commented Apr 11, 2019

div.parent {
display: table;
}
div.child {
display: table-cell
vertical-align: middle;
text-align: center;
}

@mengsixing
Copy link

补充一个,使用 table-cell 的方式:

.parent {
        display: table-cell;
        height: 200px;
        width: 200px;
        background-color: orange;
        text-align: center;
        vertical-align: middle;
}
 .child {
        display: inline-block;
        width: 100px;
        height: 100px;
        background-color: blue;
}
<div class="parent">
      <div class="child"></div>
</div>

@Moriarty02
Copy link

水平垂直居中有好多种实现方式,主要就分为两类不定宽高和定宽高
以在body下插入一个div为例

  1. 定宽高
    使用定位+margin
element.style {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -250px;
    margin-top: -250px;
    width: 500px;
    height: 500px;
    background: yellow;
    z-index: 1;
}

使用定位+transfrom

element.style {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 500px;
    height: 500px;
    background: yellow;
    z-index: 1;
    transform: translate3d(-50%,-50%,0);
}
  1. 不定宽高
    不定宽高的方法基本都适用于定宽高的情况
    这里把div的宽高按照内容展开
    使用定位+transform同样是适用的
element.style {
    position: absolute;
    left: 50%;
    top: 50%;
    background: yellow;
    z-index: 1;
    transform: translate3d(-50%,-50%,0);
}

还有一些其他的方法比如使用父容器使用flex,grid,table
这两个楼上也提到了,是可以实现的,但是在实际应用中,
因为改变了父容器的display,在多个子节点反而不好用了

@cb3570594
Copy link

楼上总结的差不多了。再加一种

div.parent{
  display:flex;
}
div.child{
  margin:auto;
}

同理:
div.parent{ display:grid; } div.child{ margin:auto; }

@zeroone001
Copy link
Author

zeroone001 commented Apr 11, 2019

div.parent {
display: table;
}
div.child {
display: table-cell
vertical-align: middle;
text-align: center;
}

需要再补充一个@cleverboy32

div.grandson {
    display:inline-block;
    width: 10px;
    height: 10px;
}
<div class="parent"><div class="child"><div class="grandson"></div></div></div>

@sohoorc
Copy link

sohoorc commented Apr 11, 2019

1. 
div.parent {
     display:flex;
      justify-content:center;
     align-items:center;
}

2.
div.parent {
    position:relative;
}

div.child{
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
}

@hjskevin
Copy link

我总结的方法:https://juejin.im/post/5ca1a585f265da30dc7ac3f7

@yiqingfeng
Copy link

补充一个,使用 table-cell 的方式:

.parent {
        display: table-cell;
        height: 200px;
        width: 200px;
        background-color: orange;
        text-align: center;
        vertical-align: middle;
}
 .child {
        display: inline-block;
        width: 100px;
        height: 100px;
        background-color: blue;
}
<div class="parent">
      <div class="child"></div>
</div>

table-cell 是不支持设置 width: 100%; 想让 .parent 和 其容器宽度一致最好设置一个 dispaly: table; 父容器。

<div class="parent-fix">
  <div class="parent">
    <div class="child">DEMO</div>
  </div>
</div>
.parent-fix {
  display: table;
  width: 100%;
}
.parent {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
  height: 200px;
  background-color: #ccc;
}
.child {
  display: inline-block;
  background-color: #000;
  line-height: 50px;
  color: #fff;
}

@cleverboy32
Copy link

cleverboy32 commented Apr 12, 2019

@zeroone001 在 parent 有宽高的时候, child 已经垂直居中了

@zeroone001
Copy link
Author

@zeroone001 在 parent 有宽高的时候, child 已经垂直居中了

不行
display: table-cell; 这个居中不了,必须要第三个元素在child里面

@XinChou16
Copy link

100%高度的 after 加上 inline-block

<div class="box">
    <div class="center">
</div>
.box {
  width: 500px;
  height: 500px;
  text-align: center; /*center*/
}
.box::after {
  content: '';
  display: inline-block;
  width: 0;
  height: 100%;
  vertical-align: middle;
}
.center {
  display: inline-block;
  width: 100px;
  height: 100px;
  vertical-align: middle;/*center*/
}

@Caitingwei
Copy link

// 1. line-height + text-algin
.parent {
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.child {
}

// 2. text-align + vertail-align
.parent {
  text-align: center;
}
.child {
  display: inline-block;
  vertical-align: middle;
}

// 3. table-cell + vertail-align
.parent {
  display: table-cell;
  vertical-align: middle;
}
.child {
}

// 4. position + margin
.parent {
  position: relative;
}
.child {
  width: 100px;
  height: 100px;
  position: absolute;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
}

// 5.position + transform 
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

// 6. flex
.parent {
  display: flex;
}
.child {
  align-items: center;
  justify-content: center;
}

@huijingL
Copy link

楼上大神们指出的很全了,

我指出一点:
使用 margin-left 和 margin-top, 相对的是父元素,
transform: translate 相对的自身,
这是他们的一点区别,实际上我是想问一下,他们还有没有其他的区别 ,望后续大神指出;

前端小白,有错勿怪,感谢指正

@luichooy
Copy link

// 1. line-height + text-algin
.parent {
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.child {
}

// 2. text-align + vertail-align
.parent {
  text-align: center;
}
.child {
  display: inline-block;
  vertical-align: middle;
}

// 3. table-cell + vertail-align
.parent {
  display: table-cell;
  vertical-align: middle;
}
.child {
}

// 4. position + margin
.parent {
  position: relative;
}
.child {
  width: 100px;
  height: 100px;
  position: absolute;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
}

// 5.position + transform 
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

// 6. flex
.parent {
  display: flex;
}
.child {
  align-items: center;
  justify-content: center;
}

方法2 只能水平居中,方法3导致div.parent宽度和div.parent宽度一样,且设置width样式无效

@banli17
Copy link

banli17 commented Sep 2, 2019

div.parent {
display: table;
}
div.child {
display: table-cell
vertical-align: middle;
text-align: center;
}

这个设置table-cell 的盒子会占满父盒子,里面的文字才能居中。

@CatherineYF
Copy link

div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}

能说一下这种实现方式的原理吗

@MarshallShady
Copy link

MarshallShady commented Oct 8, 2019

div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}

能说一下这种实现方式的原理吗

这个我前几天刚在张鑫旭的《CSS世界》里面第一次看到,原理就是(基于我个人的理解):设置inline-block和vertical-align:middle后,里面的元素会基于中间的文字准线居中对齐(学生时代的英语本子里面写字母,都是4条线形成三个空白区域,文字的对齐就是根据这几条线的)vertical-align更多信息可以看看张鑫旭博文
然后,由于伪类是position:static(默认)的,那么伪类撑开了父元素的基准线(高度是100%),使得此时文字的基准线就是整个div.parent的中心了,另外vertical-align只影响inline或者inline-block的,所以div.child设置vertical-align就能居中了。
以上是我个人的理解,有很多表达不清楚的地方,更详细的内容还是推荐张鑫旭的博文。

@awesomezao
Copy link

awesomezao commented Nov 12, 2019

可以用calc来计算,这样代码少一点

 .parent {
  border: 1px solid;
  width: 1000px;
  height: 1000px;
  }
.child {
  position: relative;
  border: 1px solid;
  width: 100px;
  height: 100px;
  top: calc(50% - 50px);
  left: calc(50% - 50px);
  }

@BowenXiao1999
Copy link

<div class="parent">
  <div class="child"></div>
</div>
div.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}
div.parent {
    position: relative; 
}
div.child {
    position: absolute; 
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);  
}
/* 或者 */
div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -25px;
    margin-top: -5px;
}
/* 或 */
div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
div.parent {
    display: grid;
}
div.child {
    justify-self: center;
    align-self: center;
}
div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}

提个建议,可以在每一种实现上写一下思想和场景

@huwenkang99
Copy link

楼上大神们指出的很全了,

我指出一点:
使用 margin-left 和 margin-top, 相对的是父元素,
transform: translate 相对的自身,
这是他们的一点区别,实际上我是想问一下,他们还有没有其他的区别 ,望后续大神指出;

前端小白,有错勿怪,感谢指正

margin是给自己加个外边框,是相对自身原来的位置来变化吧

@leohongbing
Copy link

学无止境~
div.parent {
position: relative;
}

div.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}

@ciming
Copy link

ciming commented Jan 20, 2021

div.parent{
   display:grid;
   place-items: center;
}

@babel1995
Copy link

div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}

能说一下这种实现方式的原理吗

在73题的IFC中有人提到了IFC的应用场景:垂直居中项应该就是这种方式的实现原理

@shifengdiy
Copy link

shifengdiy commented Jul 25, 2021

1、使用绝对定位

       <div
          style={{
            position: "absolute",
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            backgroundColor: "seagreen"
          }}
        >
          居中元素
        </div>

2、不使用绝对定位,使用flex

      <div
        style={{
          display: "flex",
          width: 300,
          height: 300,
          margin: "20px auto",
          border: "2px solid #333"
        }}
      >
        <div
          style={{
            width: 40,
            height: 40,
            margin: "auto",
            backgroundColor: "seagreen"
          }}
        >
          居中元素
        </div>
      </div>

3、使用table-cell,display为table-cell同时使用verticalAlign: middle会让元素垂直居中

      <div
        style={{
          display: "table-cell",
          verticalAlign: "middle",
          width: 300,
          height: 300,
          margin: "20px auto",
          border: "2px solid #333"
        }}
      >
        <div
          style={{
            width: 40,
            height: 60,
            display: "inline-block",
            backgroundColor: "seagreen"
          }}
        >
          居中元素
        </div>
      </div>

@fishear
Copy link

fishear commented Dec 6, 2021

居中的几种方式:https://css-tricks.com/centering-css-complete-guide/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests