CSS:幅/高さをパーセントマイナスピクセルとして設定


479

私は自分のサイトで一貫性を保ち、乱雑さを減らすために再利用可能なCSSクラスをいくつか作成しようとしていますが、頻繁に使用するものを標準化しようとしています。

<div>高さを設定したくないコンテナがあります(これはサイトの場所によって異なるため)、内部にはヘッダー<div>があり、次に項目の順序付けされていないリストがあり、すべてCSSが適用されていますそれら。

次のようになります。

ウィジェット

ヘッダーの高さがわかっているので、順序付けられていないリストがコンテナの残りのスペースを占めるようにしたい。リストの高さを「マイナスの結果」として指定する方法がわかりません。<div><div>18px100%18px

この質問がSOの他のいくつかのコンテキストで質問されるのを見たことがありますが、私の特定のケースについてもう一度尋ねる価値があると思いました。この状況で誰かアドバイスはありますか?


6
マージンを設定しますか?__
kennytm 2010年

@KennyTM、私はあなたが私の注文していないリスト、例えば17pxにマージントップを置くことを提案していると思います。しかし、これはリスト全体を押し下げるだけです。コンテナ内に留まるために収縮することはありません。基本的に、現在の高さは維持されますが、17pxだけ押し下げられます。これで私の問題は解決しませんが、この手法を使用した他のアプローチをオンラインで見たので、これは正しい方向への一歩だと思います。
MegaMatt

ここに投稿した質問で、この問題を解決しました。stackoverflow.com/a/10420387/340947
Steven Lu

回答:


895

私は、これは古い記事で実現するが、あなたがCSS3対応のブラウザのために書いている場合は、あなたが使用することができます言及する価値があることが示唆されていなかったことを考えますcalc

height: calc(100% - 18px);

現在、すべてのブラウザーが標準のCSS3 calc()関数をサポートしているわけではないため、次のように、ブラウザー固有のバージョンの関数の実装が必要になる場合があることに注意してください。

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);

5
はい、それは当分正常です。
Levi Botelho 2013年

1
IE10とChrome 27で私のために動作します。
BrainSlugs83 2013年

3
@LeviBotelho悪い。オペレーターの周りにスペースがありませんでした。
ユーザー

20
また、Lessを使用する場合はlessc --strict-math=on、内部の式を評価しないようにファイルをコンパイルする方がよいでしょうcalc-私が直面し、多くの時間を費やした問題(Less 2.0.0以降)
Dmitry Wojciechowski

34
:マイナス記号の周りのスペースはオプションではないことに注意してください100%-18px100%- 18px100% -18px私はテストしたブラウザでは動作しませんでした。
nisetama

71

少し異なるアプローチの場合、リストで次のようなものを使用できます。

position: absolute;
top: 18px;
bottom: 0px;
width: 100%;

これは、親コンテナが持っている限り機能します position: relative;


1
ありがとう。親コンテナposition: relative;がつまずいていた。
gthmb

私のように不思議に思う人のために:位置はabsolute子コンテナにある必要がありますが、それはできませんrelative
グレッグ

続き(申し訳ありません):ただし、親は配置が必要なだけです(配置することもabsoluteできます)。高さも100%に設定する必要があります。
グレッグ

1
残念ながら、これはSafari iOS 8では動作しません(Android 4.1ストックブラウザーおよび標準FF 34でテスト済み):-(
Greg

これは場合によっては機能するかもしれませんが、絶対位置の要素が通常のフローから削除されるため、いくつかの問題を引き起こす可能性があります。stackoverflow.com/a/12821537/4173303を参照してください。
Christophe Weis

26

私はこれにjqueryを使用しています

function setSizes() {
   var containerHeight = $("#listContainer").height();
   $("#myList").height(containerHeight - 18);
}

次に、ウィンドウのサイズ変更をバインドして、ブラウザウィンドウのサイズが変更されるたびに再計算します(ウィンドウのサイズ変更でコンテナのサイズが変更された場合)

$(window).resize(function() { setSizes(); });

12
@puffpio、確かにJSはケースバイケースでこれを達成する方法です。しかし、先ほど述べたように、CSSを汎用的にして、(偶然にもマスターページから継承する)複数のページに適用できるようにしています。だから私はJSを使用したくないのですが。しかし、答えてくれてありがとう。
MegaMatt

7
JavaScriptの中にスタイルを入れないでください。
グレッグ

8
@ greg、CSSにさらに便利な機能があったら助かります。あなたがハックしなければならないことのいくつかはばかげています。
ジョナサン。

1
@puffpio確かに素晴らしい解決策。しかし、ウィンドウでイベントをバインドすることは、私にとって良い解決策ではありません。ページにこのような要素が3〜4個以上ある場合、ウィンドウサイズ変更ハンドラーで各要素の高さと幅を更新する必要があります。これはCSSソリューションよりも少し遅くなります。
sachinjain024 2013

1
「JavaScript内にxyzを配置しないでください」は、「ブラウザ市場の80%をサポートしないでください」と言っているようなものです。
Beejor、2015年

16

高さをパーセントで定義するのではなく、次のようにtop=0とを設定するだけbottom=0です。

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}

高さをパーセントに設定しないでください。
Shrikant Sharat、2013

@ShrikantSharatこれは、絶対配置要素の視覚フォーマット仕様の一部です。このソリューションは可能性5を利用しています。 0にして「高さ」を解決します。ブラウザは要素の高さを計算できます。これは、要素の親の上部と下部からの距離がわかっているためです。
ロス・アレン

これは、少なくともFirefoxでは機能しないようです。すべての親要素がとに設定されていてheight:100%display:block。それ以外の場合は、非常にエレガントなソリューションになります。興味深いことに、margin:auto固定幅のオブジェクトを垂直方向に中央揃えすることもできません。
Beejor

8

ヘッダーの高さを17ピクセルと推定

cssのリスト:

height: 100%;
padding-top: 17px;

ヘッダーCSS:

height: 17px;
float: left;
width: 100%;

うん、それは私が得ていたものです。
dclowd9901 2010年

1
それは期待していたほどうまくいきませんでした。順序付けられていないリストがそのヘッダーdivの下から開始されています。ヘッダーdivはコンテナー内のスペースを占有しているため、リストに17pxのpadding-topを配置すると、コンテナーdivの上部から17pxではなく、上の画像にある場所から17px押し下げられます。上記の回答で提供されたCSSで得られる画像は、i41.tinypic.com / mcuk1x.jpgです。努力に感謝しますが、私が不足していると思われるものがあれば、知らせてください。ところで、私はオーバーフローしています:順序付けられていないリストでもautoです。
MegaMatt 2010年

2
実際のcssを投稿すると、どのようなやり取りが行われているかを正確に把握できるため、トラブルシューティングがはるかに簡単になります。あなたが試みるかもしれないもう一つはあなたのulの負のトップマージンです。ul { margin-top: -17px; }
ghoppe

7
  1. マイナスピクセルをオフにする要素に負のマージンを使用します。(望ましい要素)
  2. 作りoverflow:hidden;含む要素に
  3. overflow:auto;目的の要素に切り替えます。

それは私のために働いた!


3
これは私にとって魅力のように機能しました(オーバーフローを変更する必要すらありませんでした)。素晴らしい解決策、ありがとうございます!
Aaj

1
すごい!人気のある「CSS calc」ソリューションについて学ぶことを楽しんだが、これははるかに単純であり、より広いブラウザーをサポートしている。完璧なマイナスマージン!
Simon Steinberger 14年

これは非常にエレガントで互換性のあるソリューションです。主な欠点は、要素の高さが固定されている必要があることです。それ以外の場合は、JSを使用するかcalc()、実行時にそれを中央に配置する必要があります。しかし、多くの場合、これは問題になりません。留意すべきもう1つの点は、マージン、パディング、オフセットに多くの負の値を使用すると、後でコードをデバッグするときに混乱が生じる可能性があるため、物事をシンプルに保つことです。
Beejor、2015年

5

ボックスサイズを試してください。リストの場合:

height: 100%;
/* Presuming 10px header height */
padding-top: 10px;
/* Firefox */
-moz-box-sizing: border-box;
/* WebKit */
-webkit-box-sizing: border-box;
/* Standard */
box-sizing: border-box;

ヘッダー:

position: absolute;
left: 0;
top: 0;
height: 10px;

もちろん、親コンテナは次のようになります。

position: relative;

3

同じ目標を達成する別の方法:フレックスボックス。コンテナーを列フレックスボックスにすると、一部の要素を固定サイズ(デフォルトの動作)にするか、コンテナースペースまで(フレックスグロー:1およびフレックスを使用して)フィルアップ/シュリンクダウンできるようになります。収縮:1)。

#wrap {        
  display:flex;
  flex-direction:column;
}
.extendOrShrink {
  flex-shrink:1;
  flex-grow:1;
  overflow:auto;
}

https://jsfiddle.net/2Lmodwxk/を参照してください (ウィンドウを拡大または縮小して、効果を確認してください)

注:省略形のプロパティを使用することもできます。

   flex:1 1 auto;

これは、ヘッダーdivの設定された高さ(元の質問では18px)を指定する必要がないことを意味し、パディングやマージンなどを差し引く必要がないことを意味するため、今日の最良の答えであると思います。設定されたピクセルはなく、すべてが自分で処理します。
MegaMatt

2

私は他のいくつかの答えを試してみましたが、どれも私が望んでいたほどうまく機能しませんでした。ウィンドウヘッダーがあり、ウィンドウ本体の画像を使用してウィンドウのサイズを変更できる場合も、状況はよく似ていました。ヘッダーの固定サイズを考慮に入れるために計算を追加する必要なく、サイズ変更のアスペクト比をロックし、画像をウィンドウボディ全体に表示したかったのです。

以下に、私たちの状況にうまく機能し、ほとんどのブラウザーで互換性があるように見えるようになったことを示す非常に単純なスニペットを作成しました。

ウィンドウ要素に20pxのマージンを追加しました。これは、画面上の他の要素に対する相対的な配置に寄与しますが、ウィンドウの「サイズ」には寄与しません。次に、ウィンドウヘッダーが絶対的に配置され(他の要素のフローから削除されるため、順序付けられていないリストなどの他の要素がシフトされることはありません)、ヘッダーの上部がマージンの内側に配置される-20pxになります。ウィンドウの。最後に、ul要素がウィンドウに追加され、高さを100%に設定して、ウィンドウの本体(マージンを除く)を埋めることができます。

*,*:before,*:after
{
  box-sizing: border-box;
}

.window
{
  position: relative;
  top: 20px;
  left: 50px;
  margin-top: 20px;
  width: 150px;
  height: 150px;
}

.window-header
{
  position: absolute;
  top: -20px;
  height: 20px;
  border: 2px solid black;
  width: 100%;
}

ul
{
  border: 5px dashed gray;
  height: 100%;
}
<div class="window">
  <div class="window-header">Hey this is a header</div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
  </ul>
</div>


1

ありがとう、私はあなたの助けを借りて私の問題を解決しました.divを100%幅100%の高さ(下部バーの高さを低く)にし、本体をスクロールしない(ハック/スクロールバーを非表示にしない)ため、少し微調整しました。

CSSの場合:

 html{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 body{
  position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 div.adjusted{
  position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px;
 }
 div.the_bottom_bar{
  width:100%;height:31px;margin:0px;border:0px;padding:0px;
}

HTMLの場合:

<body>
<div class="adjusted">
 // My elements that go on dynamic size area
 <div class="the_bottom_bar">
  // My elements that goes on bottom bar (fixed heigh of 31 pixels)
 </div>  
</div>  

これでうまくいきました。そうです、div.adjustedの値をボトムバーの高さよりもボトムに少し大きくすると、垂直スクロールバーが表示され、最も近い値に調整されます。

その違いは、動的領域の要素の1つが、私が取り除く方法がわからない余分な下部の穴を追加しているためです...これはビデオタグ(HTML5)です。このcss(だからそれが底穴を作る理由はありませんが、それはそうです):

 video{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

オブジェクティブ:ブラウザーの100%(およびブラウザーのサイズが変更されたときに動的にサイズ変更されますが、アスペクト比は変更されない)の動画に、テキスト、ボタンなど(およびバリデーター)を含むdivに使用する下部スペースを差し引いたものを用意しますもちろんw3c&css)。

編集:理由を見つけました、ビデオタグはブロック要素ではなくテキストのようなものですので、このCSSで修正しました:

 video{
  display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

display:block;on videoタグに注意してください。


0

これがあなたの特定の状況で機能するかどうかはわかりませんが、内側のdivのパディングは、それを含むdivが固定サイズの場合、divの内側にコンテンツをプッシュすることがわかりました。ヘッダー要素をフロートにするか絶対配置する必要がありますが、それ以外の場合は、可変サイズのdivに対してこれを試していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.