读前须知
本次快文快答的主题是水平垂直居中。
在阅读本文之前,为了节约大家时间,可以先通过下方介绍了解一下鼠子的面试快问快答系列,如果觉得该系列不适合您或有什么不妥之处,欢迎给我留言。
鼠子的面试快问快答系列,是一个专门针对面试各种八股文的而开展的系列。
想要做这个系列的初衷,在于鼠子本人也是一名 22 届应届生,也了解到身边很多同学在面试时会对一些知识点表述不清或干脆照本宣科全文背诵。为了帮自己巩固知识,并能给各位在找工作的同学们尽一点绵薄之力,鼠子决定用自己的理解把考点嚼碎喂给大家。
这个系列适合谁?
- 还在上学的同学们,因为鼠子也是学生所以可能常用话术会更加贴近同学们。
- 已经毕业但在找工作的前辈们,鼠子能力有限,希望一点点小理解能够帮助前辈们加深印象。
- 纯粹想当成备忘录的大佬们(如果有),谢谢大佬们的抬爱。
最后,因为鼠子能力有限,很多地方可能会有争议,希望大家能及时提出!
Q:请用css实现一下水平垂直居中
题目分析
实现水平垂直居中在实习/校招中是一个很热门的题目,方法大家都会背,但是怎么在一道平平无奇的题目中让面试官看到你的独特之处才是你的竞争力所在。
本文不会详解每种方法的原理和代码,因此大家可以先阅读下面这个文章
文中给出了10种解决方案,但是我只想挑出常用的几点来放到面试中去说。
我选取了5种实现方式,分别是flex、absolute+负margin、absolute + margin auto、absolute + calc、absolute + transform
dom结构如下
<div id="container">
<div id="box">
</div>
</div>
具体css代码如下
-
flex
/* 1. flex */ #container { display:flex; justify-content:center; align-item:center; } -
absolute+负margin
/* 2. absolute+负margin */ #container { position:relative; } #box { position:absolute; top:50%; left:50%; width:100px; margin-left:-50px; height:100px; margin-top:-50px; } -
absolute + margin auto
/* 3. absolute + margin auto */ #container { position:relative; } #box { position:absolute; top:0; right:0; bottom:0; left:0; width:100px; height:100px; margin:auto; } -
absolute + calc
/* 4.absolute + calc */ #container { position:relative; } #box { position:absolute; height:100px top:calc(50%-50px); width:100px; left:calc(50%-50px); } -
absolute + transform
/* 5.absolute + transform */ #container { position:relative; } #box { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); }
加深理解
我们来对上面5种实现方式来进行分类:
| 兼容性较好 | 兼容性较差 | 居中元素定宽高 | 居中元素不定宽高 | |
|---|---|---|---|---|
| flex | √ | √ | ||
| absolute + 负margin | √ | √ | ||
| absolute + margin auto | √ | √ | ||
| absolute + calc | √ | √ | ||
| absolute + transform | √ | √ |
这里的兼容性好与差,是相对而言的,我将css3新增的属性看成是较差,css2看成是较好,在实际业务场景中支持css3的环境已经非常普及了,不用太纠结这个。
至于居中元素定宽高这个问题,在实际业务场景下还是非常重要的,如果需要预先给定宽高,那就意味着灵活性会大大地降低。
面试白话版
面试官:请用css实现一下水平垂直居中
鼠子答:
首先,flex布局可以通过指定它的主轴和交叉轴上的元素排列方式为居中(center)来实现。
也可以说明控制主轴和交叉轴的属性名为
justify-content和align-items
其次,我们也可以用绝对布局去实现。
父盒子给个relative布局
更准确地来说让父盒子变成一个
包含块(containing block),可提可不提,建议不提别挖坑
子盒子给个absolute布局,并让top=50%,left=50%,值得一提的是,这个百分比是相对于父盒子宽高的。这时候子盒子还没有完全居中,所以我们可以给子盒子一个负margin-top和负margin-left把它拉回中心,值的大小正好是子盒子宽高的一半。
这里我们也可以用transform来拉。transform里面有个translate的平移函数,我们在他的x轴和y轴平移负50%,注意一下这里的百分比是相对子盒子的宽高。
如果要用calc函数来做,那只要给定top和left的计算公式,50%减去子盒子宽高的一半。
当然,如果子盒子宽高给定的前提下我更推荐借助格式化宽高的计算公式去做。
这个方法在《css世界》里面也提到过。
它的做法是,top、right、bottom、left都给0,子盒子宽高给定,margin给个auto,这样的话,margin就会自动分配剩余的空间,实现垂直居中。这种做法简单且兼容性好。
为了防止面试官进一步问格式化宽度的事情,我们需要了解一下它的计算公式,父盒子宽=left+right+子盒子左右margin/padding/border+子盒子宽,当margin为auto时,剩下的所有空间会被margin平分,同样可以此类比高度的计算公式
关键词:flex、absolute、负margin、transform、translate、calc、格式化宽高
写在最后
本系列的主要内容都是手打的,难免会有疏漏。我们在面试时不力求最完美最全面的答案,而要集中精力在把提出的几个点说好,并在这几个点上做发散,不然就会给人一种只会背书的死板印象。知识并不是孤立的,同样每个面试题背后的知识也是相互联系的,从一个面试题去辐射到更大的知识网络,才是灵活应用八股文的关键。
如果有想看鼠子解析别的面试考点,欢迎随时留言!
关于我
喜欢聊天、喜欢分享、喜欢前沿的22届小菜鸡,初来乍到希望得到各位大佬的关注。能有实习/校招机会就更好啦!
个人公众号:鼠子的前端CodeLife