如何实现一个元素垂直水平居中
确定问题背景
题目中只说实现一个元素垂直水平居中,但是问题来了
此元素的宽高是已知还是未知?
此元素相对于谁居中?
- 相对于浏览器窗口
- 相对于其父元素垂直水平居中
以上情况不同,所能给出的方案也不同,下面依次进行介绍
此元素宽高已知
相对于浏览器窗口居中
相对于浏览器居中的情况下又有两种情况,一种是首屏居中,使用absolute即可 另一种是一直固定在窗口居中,使用fixed即可。
首屏居中
若是只要求在首屏垂直居中,使用absolute
<head>
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
position: absolute;
margin: auto;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
p{
width: 300px;
height: 300px;
background: yellow;
position: absolute;
top: 100px;
right: 100px;
}
</style>
</head>
<body>
<div>
<p>首屏居中</p>
</div>
</body>
关于div的居中也可以使用left+margin-left top+margin-top来解决,代码如下
div{
width: 500px;
height: 500px;
background: pink;
position: absolute;
left: 50%;
top: 50%;
margin-left: -250px;
margin-top: -250px;
}
固定居中
若要针对于窗口水平居中且固定不动,那么就只能使用固定定位fixed,将div的定位改为fixed即可
相对于父元素居中
在宽高已知的情况下,实现子元素相对于父元素水平垂直居中的方法有很多
一,给子元素用margin
父元素500px 子元素300px 经过计算可以轻易得知 给子元素添加margin 100 px即可实现垂直水平居中
<style>
body,p{
margin: 0; padding: 0;}
.box{
width: 500px;
height: 500px;
background: pink;
margin: 20px;
}
p{
width: 300px;
height: 300px;
background: yellow;
margin: 100px;
}
</style>
</head>
<body>
<div class="box">
<p>margin实现</p>
</div>
</body>
margin-top兼容问题
但是情况和我们预想的有点出入,我们发现p的上边距100px似乎没有生效,看效果图的效果像是给父元素div加了100px的上边距。左右下边距显示正常。
不是我们代码写错了,而是margin-top存在的兼容问题,详细原因可以查看CSS 外边距合并
解决这个问题的办法可以用以下三种:
- 给子元素或者父元素添加浮动(看布局情况)
- 给最近的父元素添加上边框(透明最好)
- 给父元素添加overflow:hidden
选择一种解决margin-top兼容即可。
二,给父元素用padding
根据已知宽高计算出父元素的padding值很简单,但是这里要注意的是,在标准盒模型下父元素加padding是要增加父元素所占的空间,在这种情况下就有两种解决方法
方案1
既然padding将父元素的宽高撑开,那么在原本的宽高中减去padding即可,本案例中父元素原本宽高500px,padding100px,因此将宽高都减去100*2即可 即300
<style>
body,p{
margin: 0; padding: 0;}
.box{
width: 300px;
height: 300px;
background: pink;
padding: 100px;
}
p{
width: 300px;
height: 300px;
background: yellow;
}
</style>
<body>
<div class="box">
<p>padding实现</p>
</div>
</body>
方案2
既然加padding会使得元素撑开额外的距离,使用怪异盒子模型即可解决。 给父元素div加上box-sizing属性即可
.box{
box-sizing: border-box;
width: 500px;
height: 500px;
background: pink;
padding: 100px;
}
三,vertical-align+text-align解决
方案1
我们知道line-height=height可以使得单行文本垂直居中,text-align可以使得文本水平居中 因为p是块级元素,而vertical-align只能作用在行内块元素上,因此我们先将其转为行内快,再进行垂直居中操作。
line-height具有继承性,因此在div中设置的行高500px会继承到p上面,行高>自升高度,会导致p中的文字向下跑,给p再加上行高300px与自身高度相等,即可实现文字在p中的垂直居中(水平居中也会继承与div的text-align属性 不用再额外添加)
<style>
body,p{
margin: 0; padding: 0;}
.box{
width: 500px;
height: 500px;
background: pink;
line-height: 500px;
text-align: center;
}
p{
width: 300px;
height: 300px;
background: yellow;
display: inline-block;
vertical-align: middle;
line-height: 300px;
}
</style>
...
<body>
<div class="box">
<p>vertical-align+text-align</p>
</div>
</body>
方案2
不在父元素中添加line-height属性也可以达到效果,但是要借助新元素来完成。
我们在p标签后面添加一个span标签 html结构如下
<body>
<div>
<p>padding实现</p><span>黑中介</span>
</div>
</body>
这种办法的思想是我们找一个span 让span和div的高度一致,然后让p相对于span垂直居中,已到达p相对于div垂直居中的目的。当然水平居中依然使用text-align:center
来实现
span是行内元素,是不能设置宽高的,想要设置宽高第一步就是将span转为行内块元素,高度设为百分之百
p是块元素,我们也转为行内块元素已达到p和span同行排列。另外vertical-align也只能作用与行内块元素
代码如下
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
text-align: center;
}
p{
width: 300px;
height: 300px;
background: yellow;
display: inline-block; /*使p和span在同一行*/
vertical-align: middle; /*只给一个不能居中*/
}
span{
display: inline-block;
height: 100%;
/* 转行内快 设置高 */
background: green;
vertical-align: middle;
}
</style>
</head>
<body>
<div>
<p>padding实现</p><span>黑中介</span>
</div>
</body>
这里要注意的是,当只给p设置vertical-align属性以想达到垂直居中的时候,p和我们预想的不一样,p没有动,动的反而是span标签。这时给span也同时设置vertical-align属性即可解决问题。
此时页面呈现如下
我们将span背景色去掉 内容去掉让其视觉消失,即可实现垂直水平居中效果
四,定位方法实现
1.父子都是相对定位
代码没什么好说的,如下
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
margin: 40px;
background: pink;
position: relative;
}
p{
width: 300px;
height: 300px;
background: yellow;
position: relative;
top: 100px;
left: 100px; /*margin: 0 auto;实现水平的居中也可以*/
}
</style>
</head>
<body>
<div>
<p>父子相对定位</p>
</div>
</body>
p元素同时也可以使用百分比写法,再加上外边距的负偏移量即可
但是有margin-top的兼容性问题还是会导致父元素div的margin-left发生偏移而不是p,因此我们上面解决margin兼容问题的三种办法之一,给父元素添加overflow:hidden即可实现预期效果。
2.父相对子绝对
我们把上面的两种父子都相对的写法改一下,子元素p的定位都改成absolute绝对定位,发现也都可以。
并且第二种使用外边距偏移回去的情况下,margin-top的兼容问题并没有出现(在父元素不添加overflow:hidden的情况下) 原因是因为子元素的定位设置为绝对定位,触发BFC机制,导致p元素独立形成一个BFC,所以问题自己就解决了。
在父相子绝的情况下,想要子元素水平垂直快速居中,可以使用margin: auto; left: 0; top: 0; bottom: 0; right: 0;
的办法
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
margin: 40px;
background: pink;
position: relative;
}
p{
width: 300px;
height: 300px;
background: yellow;
position: absolute;
margin: auto;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
</style>
</head>
<body>
<div>
<p>父相对子绝对3</p>
</div>
</body>
此元素的宽高未知
一,vertical-align
方案1
对于上面margin和padding相关的需要用已知宽高来调整位置的方法显然是不可用的。那我们试试vertical-align的方法可不可以
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
line-height: 500px;
text-align: center;
}
p{
background: yellow;
display: inline-block;
vertical-align: middle;
}
</style>
</head>
<body>
<div>
<p>子元素宽高未知</p>
</div>
</body>
效果如下:
我们可以看到由于子元素宽高未知,导致撑满整个高度,但是也算勉强实现了题目要求,但是仔细会发现在这种情况下也会出现一像素的偏差。所以这种方法仅做了解即可
方案2
前面介绍vertical-align+text-align的时候介绍了第二种“黑中介”的方案,试一下在宽高未知的情况下表现如何
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
text-align: center;
}
p{
background: yellow;
display: inline-block;
vertical-align: middle;
}
span{
display: inline-block;
height: 100%;
vertical-align: middle;
}
</style>
</head>
<body>
<div>
<p>子元素宽高未知</p><span></span>
</div>
</body>
效果如下,可以看到达到预期效果
二,定位+transform
在宽高未知的情况下使用定位的方法来实现预期效果可以使用transform
属性来解决,最主要的原因是因为transform
属性的偏倚量是相对于自身的。
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
position: relative;
}
p{
position: absolute;
background: yellow;
left: 50%;
top:50%;
transform: translate(-50%,-50%);
}
</style>
...
<body>
<div>
<p>子元素宽高未知</p>
</div>
</body>
三,弹性盒子实现
方案1
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
display: flex;
}
p{
margin: auto;
background: yellow;
}
</style>
</head>
<body>
<div>
<p>子元素宽高未知</p>
</div>
</body>
方案2
<style>
body,p{
margin: 0; padding: 0;}
div{
width: 500px;
height: 500px;
background: pink;
display: flex;
justify-content: center;
align-items: center;
}
p{
background: yellow;
}
</style>
</head>
<body>
<div>
<p>子元素宽高未知</p>
</div>
</body>
可以看到 在已知和未知宽高都可以达到效果的是
- vertical-align中介法
- 弹性盒模型的两种方案
今天的文章高度不定垂直居中_你真的能写好CSS垂直水平居中吗?分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/40139.html