web-dev-qa-db-ja.com

CSSでdivの縦横比を維持する

ウィンドウの幅が変わると幅と高さが変わるdivを作成したいです。

幅に応じて高さを変更できるCSS3規則はありますか?{縦横比を維持しながら

私はJavaScriptを介してこれを実行できることを知っていますが、私はCSSのみを使用したいと思います。

div keeping aspect ratio according to width of window

928
jackb

以下のように、<div>のパーセンテージ値でラッパーpadding-bottomを作成するだけです。

div {
  width: 100%;
  padding-bottom: 75%;
  background: gold; /** <-- For the demo **/
}
<div></div>

コンテナの幅の75%に等しい高さのアスペクト比(4:3)の<div>という結果になります。

これはパディングのために:

パーセンテージは、生成されたボックスの包含ブロックの width を基準にして計算されます(source: w3.org 、強調鉱山)

他の縦横比と100%幅のパディングボトム値:

aspect ratio  | padding-bottom value
--------------|----------------------
    16:9      |       56.25%
    4:3       |       75%
    3:2       |       66.66%
    8:5       |       62.5%

divにコンテンツを配置する:

Divの縦横比を保ち、その内容が拡大されないようにするには、絶対配置の子を追加して、それをラッパーの端まで拡大する必要があります。

div.stretchy-wrapper {
  position: relative;
}

div.stretchy-wrapper > div {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
}

これは demo そしてもう1つの詳細は demo

1222
Web_Designer

vwの単位:

要素の 幅と高さ の両方にvw単位を使用できます。これにより、ビューポートの幅に基づいて要素の縦横比を維持できます。

vw:ビューポートの幅の1/100 [_ mdn _]

あるいは、ビューポートの高さにvhを使用したり、ビューポートの寸法の小さい/大きいものを使用したりするためにvmin/vmaxを使用することもできます(考察 ここ )。

例:1:1の縦横比

div {
  width: 20vw;
  height: 20vw;
  background: gold;
}
<div></div>

他の縦横比の場合は、次の表を使用して、要素の幅に応じて高さの値を計算できます。

aspect ratio  |  multiply width by
-----------------------------------
     1:1      |         1
     1:3      |         3
     4:3      |        0.75
    16:9      |       0.5625

例:4×4グリッドの正方div

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>

これはこのデモの Fiddleです そしてこれは垂直方向と水平方向を中心とした内容を持つ 応答グリッドを作るための解決策です


Vh/vwユニットのブラウザサポートはIE9 +です/詳細は canIuseを参照

371
web-tiki

私はCSSを使ってこれを行う方法を見つけました、しかしあなたはそれがあなた自身のウェブサイトの流れによって変わるかもしれないので注意しなければなりません。私は自分のウェブサイトの流動的な幅の部分の中に一定のアスペクト比でビデオを埋め込むためにそれをしました。

このような埋め込みビデオがあるとします。

<object>
     <param ... /><param ... />...
     <embed src="..." ...</embed>
</object>

それから、これをすべて "video"クラスのdivの中に配置することができます。このビデオクラスは、それ自体では直接の高さの制限がないため、Webサイトの流動的な要素になる可能性がありますが、ブラウザのサイズを変更すると、Webサイトの流れに応じて幅が変わります。これは、ビデオの特定の縦横比を維持しながら、埋め込みビデオを取り込もうとしている可能性がある要素です。

これを行うために、私は "video"クラスdiv内の埋め込みオブジェクトの前に画像を置きます。

!!!重要なのは、画像の縦横比を維持したいということです。また、画像のサイズがAT少なくともあなたがあなたのレイアウトに基づいて得るためにあなたがビデオが(またはあなたがA.R. ofを維持しているものは何でも)期待する最小と同じくらい大きいことを確かめなさい。これは、画像がパーセンテージでサイズ変更されている場合に、画像の解像度における潜在的な問題を回避します。たとえば、縦横比を3:2に維持する場合は、3 x 2ピクセルの画像を使用しないでください。状況によっては動作するかもしれませんが、テストしていません。おそらく避けることをお勧めします。

あなたはおそらくすでにあなたのウェブサイトの流動的な要素のためにこのような最小幅が定義されているはずです。そうでない場合は、ブラウザウィンドウが小さくなりすぎたときに要素が途切れたり重なったりしないようにするために、そうすることをお勧めします。ある時点でスクロールバーを用意することをお勧めします。 Webページの最小幅は、電話対応のサイトを扱っているのでない限り、画面の解像度が小さくならないため、約600ピクセル(固定幅の列も含む)です。 !!!

私は完全に透明なpngを使いますが、正しくやれば問題になるとは思わない。このような:

<div class="video">
     <img class="maintainaspectratio" src="maintainaspectratio.png" />
     <object>
          <param ... /><param ... />...
          <embed src="..." ...</embed>
     </object>
</div>

これで、次のようなCSSを追加できるはずです。

div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }

また、オブジェクト内の明示的な高さまたは幅の宣言と、通常コピー/ペーストされた埋め込みコードに付随する埋め込みタグも削除してください。

どのように機能するかは、ビデオクラス要素のpositionプロパティと、特定の縦横比を維持したい項目によって異なります。要素のサイズを変更したときに画像が正しい縦横比を維持する方法を利用します。これは、動画クラス要素の幅/高さを画像によって調整される動画クラス要素の100%に強制することによって、動画クラス要素内にある他のすべてのものに、動的画像によって提供されるスペースを最大限に活用するよう指示します。

かなりかっこいいね。

あなたはそれをあなた自身のデザインで動作させるためにそれを少し遊ばなければならないかもしれません、しかしこれは実際に私にとっては驚くほどうまくいきます。一般的な概念があります。

25
forgo

エリオットは私にこの解決策に影響を与えました - ありがとう:

aspectratio.pngは完全に透明なPNGファイルです。私の場合は30×10ピクセルです。

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

注意してください: background-sizeはあなたのターゲットブラウザでは動作しないかもしれないcss3機能です。あなたは相互運用性をチェックすることができます(例えば、{ caniuse.com )。

13
florianb

Web_Designerの答えに追加すると、<div>は、 要素を含む の幅の75%の高さ(完全に下部の余白で構成されています)になります。これは良い要約です: http://mattsnider.com/css-using-percent-for-margin-and-padding/ 。なぜこれがそうなのかわからないが、それはそうである。

Divを100%以外の幅にしたい場合は、幅を設定するための別のdivをラッピングする必要があります。

div.ar-outer{
    width: 60%; /* container; whatever width you want */
    margin: 0 auto; /* centered if you like */
}
div.ar {
    width:100%; /* 100% of width of container */
    padding-bottom: 75%; /* 75% of width of container */
    position:relative;
}
div.ar-inner {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

私は最近Elliotの画像トリックに似たものを使用して、デバイスの解像度に応じてCSSメディアクエリを使用して異なるロゴファイルを提供できるようにしましたが、それでも<img>は当然比例します。正しいアスペクト比でPNG)しかし、Web_Designerのソリューションは私にhttpリクエストを保存するでしょう。

13
nabrown

ここでw3schools.com で述べられているように、そしてこの 受け入れられた答え でいくらか繰り返されているように、パーセンテージとしての値のパディング(強調私のもの):

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

16:9の縦横比を維持するレスポンシブDIVの正しい例として、Ergoがあります。

CSS

.parent {
    position: relative;
    width: 100%;
}
.child {
    position: relative;
    padding-bottom: calc(100% * 9 / 16);
}
.child > div {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

HTML

<div class="parent">
    <div class="child">
        <div>Aspect is kept when resizing</div>
    </div>
</div>

JSFiddleのデモ

11
Marc A

あなたの解決策に基づいて、私はいくつかのトリックを作りました:

あなたがそれを使うと、あなたのHTMLは

<div data-keep-ratio="75%">
    <div>Main content</div>
</div>

このように使うには:CSS:

*[data-keep-ratio] {
    display: block;
    width: 100%;
    position: relative;
}
*[data-keep-ratio] > * {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

and js(jQuery)

$('*[data-keep-ratio]').each(function(){ 
    var ratio = $(this).data('keep-ratio');
    $(this).css('padding-bottom', ratio);
});

そしてこれを持ってあなたはちょうど高さ/幅にattr data-keep-ratioをセットしました、そしてそれはそれです。

8
pie6k

あなたはSVGを使用することができます。コンテナ/ラッパーの位置を相対にして、最初にsvgを静的に配置し、次に絶対に配置したコンテンツを配置します(上:0、左:0、右:0、下:0;)。

16:9の比率の例:

image.svg :( srcにインライン化できます)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

インラインsvgはうまくいかないようですが、svgをurlencodeしてimg src属性に埋め込むことができます。

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />
7
Maciej Krawczyk

@ web-tikiは既にvh/vwを使う方法を示しているので、画面の中央に置く方法も必要です。これは 9:16 portraitのスニペットコードです。

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateYはこの中心を画面の中央に配置します。 calc(100vw * 16 / 9)は9/16の予想される高さです。(100vw * 16 / 9 - 100vh)はオーバーフローの高さなので、overflow height/2を引き上げると画面の中央に配置されます。

風景のために、そして 16:9 を保つ、あなたはuseを示す

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

9/16の比率は変更が簡単で、あらかじめ定義された100:56.25100:75を必要としません。 9:16の肖像画のためのheight:100vh;width: calc(100vh * 9 / 16)

あなたが異なる画面サイズに適応したいならば、あなたはまた興味があるかもしれません

  • background-size cover/contains
    • 上記のスタイルは、幅と高さの比率によって異なり、包含に似ています。
  • オブジェクトフィット
    • img/videoタグ用のcover/contains
  • @media (orientation: portrait)/@media (orientation: landscape)
    • 比率を変更するためのportrait/landscapeに対するメディアクエリー。
7
wener

これは、受け入れられた答えに対する改善です。

  • ラッパーdivの代わりに擬似要素を使用します
  • 縦横比は、親ではなくボックスの幅に基づいています
  • 内容が高くなるとボックスは垂直方向に伸びます
.box {
  margin-top: 1em;
  margin-bottom: 1em;
  background-color: #CCC;
}

.fixed-ar::before {
  content: "";
  float: left;
  width: 1px;
  margin-left: -1px;
}
.fixed-ar::after {
  content: "";
  display: table;
  clear: both;
}

.fixed-ar-16-9::before {
  padding-top: 56.25%;
}
.fixed-ar-3-2::before {
  padding-top: 66.66%;
}
.fixed-ar-4-3::before {
  padding-top: 75%;
}
.fixed-ar-1-1::before {
  padding-top: 100%;
}

.width-50 {
  display: inline-block;
  width: 50%;
}
.width-20 {
  display: inline-block;
  width: 20%;
}
<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div>
<div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div>
<div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div>
<hr>
<div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div>
<div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>
7
Salman A

私の場合はSCSSが最善の解決策です。データ属性を使用する:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;

    &:before {
        content: '';
        display: block;
    }

    > * {
        display: block;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

例えば ​​:

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

ソース

5
gordie

あなたが2 divを持っているとしましょうouther divはコンテナであり、innerはあなたがその比率を維持するために必要な要素であるかもしれません(imgあるいはyoutube iframeあるいは何でも)

htmlはこのようになります:

<div class='container'>
  <div class='element'>
  </div><!-- end of element -->

あなたは "要素"の比率を維持する必要があると言うことができます

比率=> 4対1または2対1 ...

cssはこんな感じです

.container{
  position: relative;
  height: 0
  padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/

}

.element{
  width : 100%;
  height: 100%;
  position: absolute; 
  top : 0 ;
  bottom : 0 ;
  background : red; /* just for illustration */
}

パディングは%で指定された場合、高さではなく幅に基づいて計算されます。 ..それで基本的にあなたはあなたの幅と高さが常にそれに基づいて計算されるかは関係ありません。これは比率を維持します。

3
aeid

ほとんどの回答は非常にクールですが、ほとんどの場合、画像のサイズを正しく設定しておく必要があります。他の解決策は幅に対してのみ機能し、使用可能な高さには関係ありません。 。

完全に移植可能でサイズ変更可能なソリューションを提供するためにそれらを結合することを試みました。トリックは事前にレンダリングされたイメージまたは任意の形式の代わりにインラインsvg要素を使用することです。 2番目のHTTPリクエスト...

div.holder{
  background-color:red;
  display:inline-block;
  height:100px;
  width:400px;
}
svg, img{
  background-color:blue;
  display:block;
  height:auto;
  width:auto;
  max-width:100%;
  max-height:100%;
}
.content_sizer{
  position:relative;
  display:inline-block;
  height:100%;
}
.content{
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  background-color:rgba(155,255,0,0.5);
}
<div class="holder">
  <div class="content_sizer">
    <svg width=10000 height=5000 />
    <div class="content">
    </div>
  </div>
</div>

SVGのwidth属性とheight属性には大きな値を使用したことに注意してください。縮小できるのは最大予想サイズよりも大きい必要があるからです。例ではdivの比率を10:5にしています

2
Salketer

スマートな解決策<svg>display:gridを使うことにつまずいた。

グリッド要素を使用すると、どの要素が高さを設定するかを指定しなくても、2つ(またはそれ以上)の要素で同じスペースを占有できます。つまり、箱から出して 背の高い方が比率 を設定するということです。

これは、コンテンツが全体の「比率」を満たすのに十分な高さになることは決してなく、コンテンツをこのスペースに配置する方法を探しているときにそのまま使用できることを意味します。 display:flex; align-items:center; justify-content:center).
透明な<img>display:blockおよびあらかじめ決められた比率を使うのとほとんど同じですが、<svg>はより軽くて修正がかなり簡単です(必要に応じて比率を変えるため)。

<div class="ratio">
  <svg viewBox="0 0 1 1"></svg>
  <div>
    I'm square
  </div>
</div>
.ratio {
  display: grid;
}
.ratio > * {
  grid-area: 1/1/1/1;
}

<svg>sの比率を変更するだけです。

  • <svg viewBox="0 0 4 3"></svg>
  • <svg viewBox="0 0 16 9"></svg>

動作確認してください。

.ratio {
  display: grid;
}
.ratio > * {
  grid-area: 1/1/1/1;
}

/* below code NOT needed for setting the ratio 
 * I just wanted to mark it visually
 * and center contents
 */
.ratio div {
  border: 1px solid red;
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="ratio">
  <svg viewBox="0 0 7 1"></svg>
  <div>
    Fixed ratio 7:1
  </div>
</div>

高さが高いときにコンテンツ要素が比率を設定できないような解決策が必要な場合(オーバーフローが非表示または自動の場合)、グリッドにposition:relativeを、コンテンツにposition:absolute; height:100%; overflow-y: auto;を設定する必要があります。例:

.ratio {
  display: grid;
  position: relative;
}
.ratio > * {
  grid-area: 1/1/1/1;
}


.ratio > div {
  height: 100%;
  overflow-y: auto;
  position: absolute;
  
  /* the rest is not needed */
  border: 1px solid red;
  padding: 0 1rem;
}
<div class="ratio">
  <svg viewBox="0 0 7 1"></svg>
  <div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. A scelerisque purus semper eget. Sem nulla pharetra diam sit amet nisl suscipit adipiscing bibendum. A cras semper auctor neque vitae tempus quam pellentesque nec. Morbi enim nunc faucibus a pellentesque sit amet porttitor. Arcu odio ut sem nulla. Sed viverra ipsum nunc aliquet bibendum enim facilisis gravida neque. Cras tincidunt lobortis feugiat vivamus at augue eget. Laoreet sit amet cursus sit amet. Amet nulla facilisi morbi tempus iaculis urna id volutpat. Leo in vitae turpis massa sed elementum tempus egestas sed. Egestas integer eget aliquet nibh. Dolor sit amet consectetur adipiscing elit.

<p>Ut aliquam purus sit amet. Eget magna fermentum iaculis eu non diam phasellus vestibulum. Diam in arcu cursus euismod quis viverra nibh. Nullam vehicula ipsum a arcu cursus vitae congue. Vel orci porta non pulvinar neque laoreet suspendisse. At tellus at urna condimentum mattis pellentesque. Tristique senectus et netus et malesuada. Vel pretium lectus quam id leo in. Interdum velit euismod in pellentesque. Velit euismod in pellentesque massa placerat duis. Vitae suscipit tellus mauris a diam maecenas sed enim.

<p>Mauris a diam maecenas sed enim ut sem. In hendrerit gravida rutrum quisque. Amet dictum sit amet justo donec enim diam. Diam vulputate ut pharetra sit amet aliquam id. Urna porttitor rhoncus dolor purus non enim praesent. Purus in massa tempor nec feugiat nisl pretium. Sagittis vitae et leo duis ut. Facilisi nullam vehicula ipsum a arcu cursus vitae congue mauris. Volutpat odio facilisis mauris sit amet massa vitae tortor condimentum. Aliquam purus sit amet luctus venenatis lectus magna. Sit amet purus gravida quis blandit turpis. Enim eu turpis egestas pretium aenean. Consequat mauris nunc congue nisi. Nunc sed id semper risus in hendrerit gravida rutrum. Ante metus dictum at tempor. Blandit massa enim nec dui nunc mattis enim ut.
  </div>
</div>
2

単なるアイデアやハックです。

div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>
2
Orland

縦長または横長のビューでビューポートの内側に四角形を表示する場合(できるだけ大きく、外側には何も表示されないようにする)は、vw/vhの向きをportrait/landscapeに切り替えます。

@media (orientation:portrait ) {
  .square {
    width :100vw;
    height:100vw;
  }
} 
@media (orientation:landscape) {
  .square {
    width :100vh;
    height:100vh;
  }
} 
1
MoonLite

私はこの問題にかなりの時間を実行してきたので、私はそれのためのJSソリューションを作りました。これは基本的に、指定した比率によって要素の幅に従ってDOMELEMENTの高さを調整します。以下のようにあなたはそれを使用することができます。

<div ratio="4x3"></div>

要素の高さを設定しているので、要素はdisplay:blockまたはdisplay:inline-blockのいずれかでなければならないことに注意してください。

https://github.com/JeffreyArts/html-ratio-component

1
user007

幅:100ピクセル、高さ:50ピクセル(つまり2:1)を維持するとしましょう。

.pb-2to1 {
  padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1
}
0
Syed

私は自分の解決策を共有したいのですが、ここでは特定の縦横比を満たすimg-タグがあります。 CMSがサポートされていないため、backgroundを使用できませんでした。また、<img style="background:url(...)" />のようなスタイルタグは使用したくありません。また、幅は100%なので、一部のソリューションのように固定サイズに設定する必要はありません。それは責任を持ってスケールするでしょう!

.wrapper {
  width: 50%;
}

.image-container {
  position: relative;
  width: 100%;
}

.image-container::before {
  content: "";
  display: block;
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ratio-4-3::before {
  padding-top: 75%;
}

.ratio-3-1::before {
  padding-top: calc(100% / 3);
}

.ratio-2-1::before {
  padding-top: 50%;
}
<div class="wrapper"> <!-- Just to make things a bit smaller -->
  <p>
  Example of an 4:3 aspect ratio, filled by an image with an 1:1 ratio.
  </p>
  <div class="image-container ratio-4-3"> <!-- Lets go for a 4:3 aspect ratio -->
    <img src="https://placekitten.com/1000/1000/" alt="Kittens!" />
  </div>
  <p>
  Just place other block elements around it; it will work just fine.
  </p>
</div>
0
LaVomit

フラックスレイアウト(FWD)を使用できます。

https://en.wikipedia.org/wiki/Adaptive_web_design

それはレイアウトを拡大縮小して維持します、それは少し複雑ですが、(RWD)のような内容を押さずにページのサイズを変更することを可能にします。

レスポンシブに見えますが、スケーリングです。 https://www.youtube.com/watch?v=xRcBMLI4jbg

CSSのスケーリング式はここにあります。

http://plugnedit.com/pnew/928-2/

0
user1410288