Frage Pflegen Sie das Seitenverhältnis eines div mit CSS


Ich möchte ein div erstellen, das seine Breite / Höhe ändern kann, wenn sich die Fensterbreite ändert.

Gibt es CSS3-Regeln, die es erlauben, die Höhe entsprechend der Breite zu ändern, unter Beibehaltung des Seitenverhältnisses?

Ich weiß, dass ich dies über JavaScript tun kann, aber ich würde nur CSS verwenden.

div keeping aspect ratio according to width of window


796
2017-09-29 23:11


Ursprung


Antworten:


Erstellen Sie einfach einen Wrapper <div> mit einem Prozentwert für padding-bottom, so was:

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

Es wird zu einem führen <div> mit einer Höhe gleich 75% der Breite seines Behälters (ein Seitenverhältnis von 4: 3).

Dies beruht auf der Tatsache, dass zum Auffüllen:

Der Prozentsatz wird in Bezug auf die berechnet Breite des umschließenden Blocks der generierten Box [...] (Quelle: w3.org, Betonung meiner)

Padding-bottom-Werte für andere Seitenverhältnisse und 100% Breite:

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

Platzieren von Inhalt im div:

Um das Seitenverhältnis des div zu erhalten und zu verhindern, dass sein Inhalt es dehnt, müssen Sie ein absolut positioniertes Kind hinzufügen und es an den Kanten des Wrappers dehnen mit:

div.stretchy-wrapper {
  position: relative;
}

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

Hier ist ein Demo und ein weiterer mehr in der Tiefe Demo


1077
2018-05-04 01:19



vw Einheiten:

Sie können verwenden vw Einheiten für beide Breite und Höhe des Elements. Dadurch kann das Seitenverhältnis des Elements basierend auf der Breite des Darstellungsbereichs beibehalten werden.

vw: 1/100 der Breite des Ansichtsfensters. [MDN]

Alternativ können Sie auch verwenden vh für Ansichtsfensterhöhe oder gerade vmin/vmax Verwenden Sie die kleineren / größeren der Ansichtsfensterdimensionen (Diskussion Hier).

Beispiel: 1: 1 Seitenverhältnis

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

Für andere Seitenverhältnisse können Sie anhand der folgenden Tabelle den Wert für die Höhe gemäß der Breite des Elements berechnen:

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

Beispiel: 4x4 Gitter aus quadratischen Divs

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>

Hier ist ein Fiedle mit dieser Demo und hier ist eine Lösung, um ein zu machen ansprechendes Gitter aus Quadraten mit vertikal und horizontal zentriertem Inhalt.


Browser-Unterstützung für vh / vw-Einheiten ist IE9 + zu sehen canIuse für weitere Informationen


327
2018-05-15 08:48



Ich habe einen Weg gefunden, dies mit CSS zu tun, aber Sie müssen vorsichtig sein, da es sich abhängig vom Fluss Ihrer eigenen Website ändern kann. Ich habe es getan, um Video mit einem konstanten Seitenverhältnis innerhalb eines Flüssigkeitsbreitenabschnitts meiner Website einzubetten.

Angenommen, Sie haben ein eingebettetes Video wie folgt:

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

Sie könnten dies alles in ein Div mit einer "Video" -Klasse platzieren. Diese Videoklasse wird wahrscheinlich das flüssige Element in Ihrer Website sein, so dass sie selbst keine direkten Höhenbeschränkungen hat, aber wenn Sie die Größe des Browsers ändern, ändert sich die Breite entsprechend dem Fluss der Website. Dies ist das Element, das Sie wahrscheinlich versuchen, Ihr eingebettetes Video zu erhalten, während Sie ein bestimmtes Seitenverhältnis des Videos beibehalten.

Um dies zu tun, lege ich ein Bild vor das eingebettete Objekt in der "Video" -Klasse div.

!!! Der wichtige Teil ist, dass das Bild das richtige Seitenverhältnis hat, das Sie beibehalten möchten. Stellen Sie außerdem sicher, dass die Größe des Bildes MINDESTENS so groß ist wie die kleinste, die Sie erwarten, dass das Video (oder was immer Sie beibehalten) von Ihrem Layout abhängt. Dadurch werden mögliche Probleme bei der Auflösung des Bildes vermieden, wenn es in Prozent geändert wird. Wenn Sie beispielsweise ein Seitenverhältnis von 3: 2 beibehalten möchten, verwenden Sie nicht nur ein 3 x 2 Pixel großes Bild. Es kann unter bestimmten Umständen funktionieren, aber ich habe es nicht getestet, und es wäre wahrscheinlich eine gute Idee zu vermeiden.

Sie sollten wahrscheinlich bereits eine minimale Breite wie diese für flüssige Elemente Ihrer Website definiert haben. Wenn nicht, ist es eine gute Idee, dies zu tun, um zu vermeiden, dass Elemente abgeschnitten werden oder sich überlappen, wenn das Browserfenster zu klein wird. Es ist besser, an irgendeiner Stelle eine Bildlaufleiste zu haben. Die kleinste Breite, die eine Webseite erreichen sollte, liegt irgendwo bei ~ 600px (einschließlich aller Spalten mit fester Breite), weil die Bildschirmauflösungen nicht kleiner werden, es sei denn, Sie haben es mit handyfreundlichen Seiten zu tun. !!!

Ich benutze eine völlig transparente PNG, aber ich glaube nicht, dass es am Ende ankommt, wenn du es richtig machst. So was:

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

Jetzt sollten Sie in der Lage sein, CSS wie folgt hinzuzufügen:

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%; }

Stellen Sie sicher, dass Sie auch explizite Deklarationen von Höhe oder Breite in den Objekt- und Einbettungs-Tags entfernen, die normalerweise mit dem Einbettungs- / Einfüge-Code geliefert werden.

Die Funktionsweise hängt von den Positionseigenschaften des Video-Klassenelements und dem Element ab, das ein bestimmtes Seitenverhältnis beibehalten soll. Es nutzt die Art und Weise, wie ein Bild bei der Größenanpassung in einem Element sein korrektes Seitenverhältnis beibehält. Es gibt an, was auch immer im Videoklassenelement vorhanden ist, um die durch das dynamische Bild bereitgestellte Grundfläche voll auszunutzen, indem seine Breite / Höhe auf 100% des durch das Bild eingestellten Videoklassenelements gezwungen wird.

Ziemlich cool, was?

Sie müssen vielleicht etwas damit herumspielen, um es mit Ihrem eigenen Design zu arbeiten, aber das funktioniert tatsächlich überraschend gut für mich. Das allgemeine Konzept ist da.


25
2017-12-22 02:08



Um der Antwort von Web_Designer hinzuzufügen, muss der <div> wird eine Höhe von 75% der Breite haben, die vollständig aus Bodenpolster besteht enthaltendes Element. Hier ist eine gute Zusammenfassung: http://mattsnider.com/css-using-percent-for-margin-and-padding/. Ich bin nicht sicher, warum das so sein sollte, aber so ist es.

Wenn Sie möchten, dass Ihr div eine andere Breite als 100% hat, benötigen Sie ein anderes Wrapping div, auf dem die Breite eingestellt werden kann:

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;
}

Ich habe kürzlich etwas Ähnliches wie Elliots Bildtrick verwendet, um CSS-Medienabfragen zu verwenden, um abhängig von der Geräteauflösung eine andere Logo-Datei zu liefern, die aber immer noch proportional skaliert wird <img> würde natürlich tun (Ich setze das Logo als Hintergrundbild auf ein transparentes .png mit dem richtigen Seitenverhältnis). Aber die Lösung von Web_Designer würde mir eine HTTP-Anfrage ersparen.


13
2018-05-06 17:35



Elliot hat mich zu dieser Lösung inspiriert - danke:

aspectratio.png ist eine komplett transparente PNG-Datei mit der Größe deines bevorzugten Seitenverhältnisses, in meinem Fall 30x10 Pixel.

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);
}

Bitte beachten Sie:  background-size ist eine CSS3-Funktion, die möglicherweise nicht mit Ihren Zielbrowsern funktioniert. Sie können die Interoperabilität prüfen (z. B. auf caniuse.com).


13
2017-07-07 14:25



Wie angegeben in hier auf w3schools.com und etwas wiederholt in diesem akzeptierte Antwort, Füllwerte als Prozentsätze (Hervorhebung meins):

Gibt die Auffüllung in Prozent der Breite der Option an enthaltendes Element

Ergo ist ein korrektes Beispiel für ein reaktionsfähiges DIV, das ein Seitenverhältnis von 16: 9 aufweist, wie folgt:

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>

Demo auf JSFiddle


9
2018-03-22 12:18



Basierend auf Ihren Lösungen habe ich einen Trick gemacht:

Wenn Sie es verwenden, wird Ihr HTML nur sein

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

Um es auf diese Weise zu benutzen, machen Sie: CSS:

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

und js (jQuery)

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

Und wenn du das machst, stellst du dich einfach auf data-keep-ratio zu Höhe / Breite und das war's.


9
2017-12-05 21:13



Sie können eine SVG verwenden. Setze die Position des Containers / Wrappers relativ, setze zuerst die Svg als statisch positioniert und dann den absolut positionierten Inhalt (oben: 0; links: 0; rechts: 0; unten: 0;)

Beispiel mit 16: 9 Proportionen:

image.svg: (kann in src eingebunden werden)

<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>

Beachten Sie, dass inline svg nicht zu funktionieren scheint, aber Sie können die svg perllencodieren und sie wie folgt in das Attribut img src einbetten:

<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%;" />

6
2017-10-05 05:26



Wie @ web-tiki schon einen Weg zeigen zu verwenden vh/vw, Ich brauche auch eine Möglichkeit, in den Bildschirm zu zentrieren, hier ist ein Code-Schnipsel für 9:16 Porträt.

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

translateY wird dieses Zentrum auf dem Bildschirm behalten. calc(100vw * 16 / 9) ist erwartete Höhe für 9/16.(100vw * 16 / 9 - 100vh) ist Überlaufhöhe, also, hochziehen overflow height/2 wird es auf dem Bildschirm zentrieren.

Für Landschaft und behalten 16: 9, du zeigst Gebrauch

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

Das Verhältnis 9/16 ist einfach zu ändern, keine Notwendigkeit, vordefiniert 100:56.25 oder 100:75Wenn Sie die Höhe zuerst sicherstellen möchten, sollten Sie Breite und Höhe, z. height:100vh;width: calc(100vh * 9 / 16) für 9:16 Porträt.

Wenn Sie für unterschiedliche Bildschirmgröße angepasst werden möchten, können Sie auch interessieren

  • Hintergrundgröße abdecken / enthalten
    • Über Stil ist ähnlich zu enthalten, hängt von Breite: Höhe-Verhältnis.
  • Objekt-fit
    • cover / enthalten für img / video tag
  • @media (orientation: portrait)/@media (orientation: landscape)
    • Medienabfrage für portrait/landscape um das Verhältnis zu ändern.

4
2017-11-01 02:40



SCSS ist die beste Lösung in meinem Fall; Verwenden eines Datenattributs:

[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%;
}

Beispielsweise :

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

Quelle


3
2017-10-23 11:18



Nur eine Idee oder ein Hack.

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
2017-09-30 15:43