マージンまたはパディングを親コンテナの高さのパーセンテージとして設定するにはどうすればよいですか?


236

私はCSSで垂直方向の配置を作成することに頭を悩ませていました

.base{
        background-color:green;
	    width:200px;
	    height:200px;
	    overflow:auto;
	    position:relative;
	}

    .vert-align{
		padding-top:50%;
		height:50%;
	}
<!-- and used the following div structure. -->

    <div class="base">
       <div class="vert-align">
    	   Content Here
       </div>
    </div>

これはこのケースでは機能しているように見えましたが、ベースdivの幅を拡大または縮小すると、垂直方向の配置がスナップすることに驚きました。padding-topプロパティを設定すると、パディングは親コンテナの高さのパーセンテージとして取得されると予想していましたが、これはこの場合のベースですが、上記の50%の値は、幅。:(

JavaScriptを使用せずに、パディングやマージンを高さのパーセンテージとして設定する方法はありますか?

回答:


223

修正は、はい、垂直パディングとマージンの幅を基準にしていますが、ということであるtopbottom されません。

したがって、divを別のdivの内部に配置し、内部のdivで次のようなものを使用しますtop:50%positionそれでも機能しない場合は重要です)


3
topブラウザ/ウィンドウの高さに基づくサイズ変更に最適です。そのdivの下にdivがあるのはどうですか?どのようにしてclear、2番目のdivをaだけ下にシフトされたdivの下に置くことができますtop:50%か?
フェデリコ

新しい学習。垂直パディングとマージンが以前の幅に関連していることを知りませんでした。ありがとうございました。
shaosh 2014

5
高さをパーセントで設定した「スペーサー」divを追加することもできます。少し汚れているようですが、動作します。この回答を参照してください。
WCByrne 2015

4
永遠の@%!^?なぜ垂直マージンとパディングはに対して相対的なのですか?何?なぜ地球上でその決定がなされたのですか?
temporary_user_name

あなたの回答は、以下のalainの回答と比較して非常に不釣り合いに賛成票を投じられています。これは一般的な解決策を提供します。私はそれが非常に役に立ち、ほとんど見ていませんでした。top: 50%独自の中心でコンテンツを揃える必要がある場合は、あまり役に立ちません。
okovko

35

少し異なる質問への回答:vhユニットを使用して、要素をビューポートの中央に埋め込むことができます。

.centerme {
    margin-top: 50vh;
    background: red;
}

<div class="centerme">middle</div>

なぜこの回答は高く投票されないのですか?vhの使用に問題がありますか?
AlanH 16

3
それは元の質問に合わせた答えではないためです。いくつかの関連する場合にのみ機能する便利なトリックです。
willoller 2016

使用vhはパーセンテージとほぼ同じです...場合によってはさらに悪いこともあります。この回答は質問には関係ありません
vsync

33

必要な動作をエミュレートする2つのオプションを次に示します。一般的な解決策ではありませんが、場合によっては役立つことがあります。ここでの垂直方向の間隔は、親ではなく外部要素のサイズに基づいて計算されますが、このサイズ自体は親に相対的であり、このようにして間隔も相対的になります。

<div id="outer">
    <div id="inner">
        content
    </div>
</div>

最初のオプション:疑似要素を使用します。ここで、垂直方向と水平方向の間隔は、外側を基準にしています。デモ

#outer::before, #outer::after {
    display: block;
    content: "";
    height: 10%;
}
#inner {
    height: 80%;
    margin-left: 10%;
    margin-right: 10%;
}

水平方向の間隔を外側の要素に移動すると、外側の親に対して相対的になります。デモ

#outer {
    padding-left: 10%;
    padding-right: 10%;
}

2番目のオプション:絶対配置を使用します。デモ

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}

10

子要素を親要素から絶対的に配置するには、親要素の相対位置と子要素の絶対位置を設定する必要があります。

次に、子要素の 'top'は親の高さを基準にします。したがって、子供を自分の身長の50%上方に「平行移動」する必要もあります。

.base{
    background-color: green;
    width: 200px;
    height: 200px;
    overflow: auto;
    position: relative;
}
    
.vert-align {
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
    <div class="base">
        <div class="vert-align">
            Content Here
        </div>
    </div>

フレックスボックスを使用する別のソリューションがあります。

.base{
    background-color:green;
    width: 200px;
    height: 200px;
    overflow: auto;
    display: flex;
    align-items: center;
}
<div class="base">
    <div class="vert-align">
        Content Here
    </div>
</div>

あなたは両方の利点/欠点を見つけるでしょう。


1
変換を使用することは、要素をそれ自体のサイズに対して垂直に移動する唯一の実際の方法です。
Eran Goldin 2017

これをありがとう。これが選ばれた答えであるべきです。
Wessam El Mahdy

6

これはwriting-modeプロパティで実現できます。要素writing-modeをなどの縦書きモードに設定するとvertical-lr、その子孫のパディングとマージンのパーセント値は、両方の次元で、幅ではなく高さに相対的になります。

仕様から:

。。。マージンとパディングプロパティのパーセンテージは、常にCSS2.1の包含ブロックの幅を基準にして計算されますが、CSS3の包含ブロックのインラインサイズを基準にして計算されます。

インラインサイズの定義:

インライン寸法の測定値:横書きモードの物理的な幅(水平寸法)、および縦書きモードの物理的な高さ(垂直寸法)を指します。

例:サイズ変更可能な要素で、水平マージンは幅を基準とし、垂直マージンは高さを基準とします。

.resize {
  width: 400px;
  height: 200px;
  resize: both;
  overflow: hidden;
}

.outer {
  height: 100%;
  background-color: red;
}

.middle {
  writing-mode: vertical-lr;
  margin: 0 10%;
  width: 80%;
  height: 100%;
  background-color: yellow;
}

.inner {
  writing-mode: horizontal-tb;
  margin: 10% 0;
  width: 100%;
  height: 80%;
  background-color: blue;
}
<div class="resize">
  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>
</div>

縦書きモードの使用は、要素の縦横比を一定にしたいが、幅ではなく高さに応じてサイズを拡大したい場合に特に役立ちます。


これはIMOの方がエレガントなソリューションですが、(2018-05-05現在)縦書きモードは十分にサポートされていません。うまくいけば、すぐに変更されます。
-zanerock

1
@zanerock MDN compat tableが古いことは確かです。たとえば、Safariには-webkit-プレフィックスが必要であると記載されていますが、Caniuseによると、Safari 11以降、プレフィックスは必要ありませんでした。
James T

1
いいえ、私は、それが自動化されていても、それが良かったと思っていたと認めなければなりません。
zanerock

4

1行のテキストを中央揃えにする別の方法は次のとおりです。

.parent{
  position: relative;
}

.child{
   position: absolute;
   top: 50%;
   line-height: 0;
}

あるいは単に

.parent{
  overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}

.child{
   margin-top: 50%;
   line-height: 0;
}

0

50%のパディングは子供を中央に配置せず、中央の下に配置します。あなたは本当に25%のパディングトップが欲しいと思います。コンテンツが高くなると、スペースが足りなくなるだけでしょうか?また、パディングトップの代わりにマージントップを設定してみましたか?

編集:ネバーマインド、w3schoolsサイトは言う

%含まれる要素の幅のパーセントでパディングを指定します

それで、おそらくそれは常に幅を使用しますか?気づかなかった。

あなたがやっていることは、display:tableを使って達成できます(少なくとも最近のブラウザでは)。テクニックはここで説明されています


1
Spliffに感謝します。私の50%がdivのコンテンツを中央に配置しないことを理解しています。実際には、垂直方向の中央に配置する必要があるテキストは1行だけです。リンクをありがとう!
Ryan

3
テキストが1行だけの場合、途方もなく大きいline-height、つまり、行の高さを200pxにすることを検討しましたか?
SpliFF、2011

テキストを垂直方向にセンタリングする@Ryan、参照stackoverflow.com/questions/8865458/...
ユーザー

あなたのリンクは壊れています
quemeful 2016年

0

これは非常に興味深いバグです。(私の意見では、とにかくそれはバグです)いい発見です!

設定方法については、カミロ・マーティンの答えをお勧めします。しかし、理由については、皆さんが気にしない場合は少し説明したいと思います。


ではCSSの仕様 Iが見つかりました:

'パディング'
パーセンテージ: 包含ブロックの幅を参照

…これは奇妙ですが、大丈夫です。

だから、親width: 210pxと子でpadding-top: 50%、私は計算された/計算された値を得ますpadding-top: 96.5px-これは期待されていません105px

これは、Windows(他のOSについてはわかりません)では、一般的なスクロールバーのサイズがデフォルト17px × 100%(または100% × 17px水平バー)であるためです。これら17pxは、を計算する前に差し引かれます。50%50% of 193px = 96.5px


仕様には理由があり、これはそれをよりよく説明しています:hongkiat.com/blog/calculate-css-percentage-margins
manikanta
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.