先来一常见的案例、一张图片と下方文字行居中:
直接text-align を使用するだけです:
<style> .container{ text-align: center; }</style><div class="container"> <img src="Mars.png"> <p>火星</p></div>
実際の効果は次のとおりです:
Mars
これの問題は、最も外側のコンテナに text-align 属性を直接設定すると、すべてのサブ画像のタイトルの下にテキストの説明がある場合、以下に示すように、このテキストの説明も中央に配置されます。
火星
火星は、太陽系の 8 つの惑星の 1 つであり、その天文学的な位置にあります。シンボルは♂♂
的的。。。それ自体が悪い考えであるため、他の方法はここで使用されます。表示される画像が変化し、幅と高さが可変であるため、画像には幅と高さを明示的に設定するのが一般的です。幅がわかっている場合は、margin: 0 auto メソッド
を使用して、左右のマージン値を auto に設定できます。これにより、ブラウザーは自動的に左右のマージン値を残りの幅の半分に設定します。コンテナの:
Mars
Mars (火星) は、太陽系の 8 つの惑星の 1 つです。天文記号は次のとおりです。
<style> figure{<strong> width: 100px; margin</strong>:<strong> 0 auto</strong>; } figcaption{ text-align: center; }</style> <div class="container"> <figure> <img src="Mars.png"> <figcaption>火星</figcaption> </figure> <p class="desc">火星(Mars)是太阳系八大行星之一,天文符号是♂</p> </div>
である必要があります。この方法は上下のセンタリングには適用されないことに注意してください。
Use margin: 0 auto は最も一般的な左右の中央揃え方法と言え、ブロック要素だけでなくインライン要素にも適しています。多くのウェブページのレイアウトは、メインコンテンツが固定幅で中央に表示されます。たとえば、淘宝網 PC 側:
ただし、メインコンテンツは固定幅で中央に表示できます。問題は垂直方向のセンタリングです。ただし、垂直方向のセンタリングには、テーブルセルの垂直方向のセンタリングを使用する、より一般的な方法があります。この方法では、次の属性を親コンテナに追加します:
.container{ display: table-cell; vertical-align: middle;}
効果は次のとおりです:
Mars
table-cell を使用する欠点は、コンテナの gin 属性マージンはテーブル レイアウトに適用されないため、無効です。したがって、コンテナを中央に配置したい場合、margin: 0 auto を使用しても機能しません。解決策は、コンテナの外層に別のコンテナを追加し、そのコンテナを block margin: 0 auto として表示させることです。
もう 1 つの欠点は、テーブル セル要素の幅と高さをパーセンテージに設定すると機能しないことです。一般的なシナリオは、幅を外側のコンテナの幅の 100% に設定することです。コンテナの値を 3000px などの非常に大きな値に設定すると、100% が達成されます。もう1つの問題はIE6/7に対応していないことだが、現在本番環境は基本的にIE6/7に対応する必要はない。
このメソッドが失敗する場合があります。それは、コンテナーが位置を絶対に設定する必要がある場合です。なぜなら、
position:Absoluteを設定すると、
(non-flex)
要素の表示が強制的にブロックされるからです。解決策は、上記を真似して、外側のレイヤーに別のコンテナを追加し、このコンテナに絶対を適用することです。副作用として、内側のコンテナの高さと幅をパーセンテージに設定すると失敗します (位置も絶対に設定しない限り)。 )。このため、表セルの垂直方向のセンタリング表示が使用できない状況が発生します。 - 通常、このボックスの位置を絶対に設定する必要があり、このボックスの位置は、外側にさらに2つのレイヤーを追加しても、左、右、上部、および下部を中心にする必要があります。 、最外層は絶対層であり、内層は表セルですが、内層は高さを外層の 100% に設定できないため、つまり、高さが画面全体を正確に占めることができないため、設定できません。仕事。解决办法是使用relative定位,设置top为50%,再设置margin-top为元素高度的负的一半。一开始设置top 50%,将弹框的起始位置放到页面中间,然后再设置margin-top为弹框高度的一半取负,这样使得弹框在页面中间位置再往上移一半自身的高度,这样就刚好在正中间了,左右居中也可类似处理:
<style> .mask{ position: absolute; width: 100%; height: 100%; } .outer{<strong> position</strong>: relative;<strong> top</strong>: 50%;<strong> left</strong>: 50%;<strong> margin-top</strong>: -100px;<strong> margin-left</strong>: -100px; } .container{ width: 200px; height: 200px; display: table-cell; vertical-align: middle; }</style><div class="mask"> <div class="outer"> <div class="container"> </div> </div></div>
效果如下:
火星
这种办法的缺点是需要知道高度,无法根据内容长短自适应。所以就有了transform的方法,将margin-top一个具体的负值改成transform: translate(0, -50%),由于translate里面的面百分比是根据元素本身的高度计算的,于是就可以达到自适应的效果。将上面outer样式改为:
.outer{ position: relative; top: 50%; left: 50%;<br /> width: 200px;<strong> transform: translate(-50%, -50%);</strong> }
这个办法十分地方便,为了提高兼容性,需要添加-ms-和-webkit-前缀,缺点是IE8不支持。
上面的两种办法:margin-top一个负值和translate -50%都有一个潜在的弊端, 就是如果设置left为50%是借助position为absolute的话,可能会导致换行:
<style> .container{ position: relative; } .nav{ position:absolute; left: 50%; transform: translate(-50%, 0); bottom: 0; }</style><div class="container"> <figure> <img src="Mars.png"> </figure> <p class="nav"><span>地形</span><span>气候</span><span>运动</span></p> </div>
效果如下:
地形气候运动
可以看到,本来应该在一行显示的p元素却换行了,这是因为在一个relative元素里面absolute定位的子元素会尽可能地不超过容器的边界,通过把行内元素换行的方式。由于设置left为50%,导致p元素超了边界,所以就换行了,即使再translate -50%但已经晚了。即使是交换下两者的位置也是一样的效果,看得出浏览器执行的顺序始终是以absolute的定位优先。所以这种方法还是有不适合的场景,主要是用于左右居中定位为absolute的的情况。
另外一个CSS3居中的办法是使用flex布局,flex布局居中十分容易和方便,只需要在父容器添加三行代码,例如上面的居中情况,可将.nav的样式改为:
.nav{ position:absolute; bottom: 0;<strong> display</strong>: flex;<strong> align-items</strong>: center;<strong> justify-content</strong>: center; width: 100%; }
效果如下:
地形气候运动
flex布局在自适应领域的功能真的是非常强大,不过IE的兼容性不好,所以说可能的话,不要太去照顾IE了。
上面讨论的都是一些复合元素的居中,接下来分析单纯的行内元素的垂直居中。
主要是要借助vertical-align: middle。如下,有一张图片和文字:
<div class="container"> <img src="Mars.png"> <span>photo</span> </div>
如果不做任何处理,那么默认的垂直居中是以baseline为基准:
photo
为了让它们能够垂直居中,需要改变它们的居中方式:
.container img, .container span{ vertical-align: middle; }
注意每个元素都需要设置,效果:
photo
如果container的高度比图片还要高:
photo
为了让中间的内容能够在container里上下居中,可以设置文字的line-height为container的高度,那么文字就上下居中了,由于照片是和文字是垂直居中的,所以照片在container里也上下居中了,代码:
.container span{ vertical-align: middle; line-height: 150px; }
效果:
photo
这也就给了一个启示,如果需要垂直居中一个div里的比div高度小的照片,可以添加一个元素,让它的line-height等于div的高度,如下:
<style> .container{ width: 150px; height: 150px; text-align: center; } .container img{ vertical-align: middle; }<strong> .container:before</strong>{ content: ""; vertical-align: middle; line-height: 150px; }</style><div class="container"> <img style="vertical-align:middle;" src="Mars.png"></div>
或者是弄一个inline-block的元素,设置height为100%,这种的兼容性更好:
.container:before{ content: ""; display: inline-block; vertical-align: middle; height: 100%; }
上下居中效果:
还有另外一种方法借助absolute定位和margin: auto:
.container{ position: relative; } .container img{ position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; }
这个方法的神奇之处在于最后的margin: auto,这种方法也适用于div,但是需要给div显式指定一个height,不然div的height会达到外层容器的100%。
如果图片比container大,这种方法就不适用了。因为有一种比较常见的场景是:照片有一边和container一样高,另外一边按照片的比例缩放,照片居中显示,超出的截断,这种应该叫“占满”(occupy)布局。这种情况,只需要把left/right/top/bottom/设成一个很大的负值即可:
.container img{ position: absolute; left: -9999px; top: -9999px; right: -9999px; bottom: -9999px; margin: auto; } .container{ overflow: hidden; }
效果:
综合上面的讨论,左右居中常用text-align和margin: 0 auto,上下居中一种办法是借助table-cell,另外一种是设置top: 50%和margin-top/translate(0, -50%)结合的办法,还有就是使用flex布局,对于行内元素设置vertical-align: middle,同时借助一个高度为100%的元素达到垂直居中的效果。最后是position: absolute和margin: auto结合使用的办法。可以说没有一个方法可以100%适用,可以根据不同的情况合理结合使用。
如果上文有不妥的地方,或者读者有其它的居中方式,还请指出
参考:
1. How to vertically align an image inside div StackOverflow
2. A Complete Guide to Flexbox