Verständnis und Festlegung von Seitenverhältnissen

Jedes Element, das auf der Seite gerendert wird, hat eine Höhe und eine Breite und somit ein Seitenverhältnis, das das Verhältnis zwischen Breite und Höhe darstellt. Die natürlichen Abmessungen eines Media-Objekts, also seine Größe ohne jegliche Größenänderung, Skalierung, Zoom oder Rahmen, werden als natürliche oder intrinsische Größe bezeichnet. Die intrinsische Größe eines Elements wird durch das Element selbst bestimmt und nicht durch Formatierungen wie Box Sizing oder das Setzen von Rahmen-, Rand- oder Abstandsbreiten.

Beim Entwickeln von Websites möchten Sie häufig die Breite eines Elements auf einen Prozentsatz der Größe des Ansichtsfensters oder des übergeordneten Containers einstellen und die Höhe proportional ändern, um ein bestimmtes Seitenverhältnis basierend auf der Größe des Ansichtsfensters beizubehalten. Für ersetzte Elemente wie Bilder und Videos ist die Beibehaltung eines bestimmten Seitenverhältnisses nicht nur notwendig für ein responsive Webdesign, sondern auch ein wichtiger Bestandteil einer guten Benutzererfahrung. Das Festlegen des Seitenverhältnisses eines Assets verhindert das Laden von Jank — der Layout-Verschiebung, die auftritt, wenn Medien geladen werden, nachdem die Seite bereits gerendert wurde, und eine Neuanordnung verursacht, weil der Platz für das Asset nicht reserviert wurde.

Mithilfe von CSS können Sie die Größe von ersetzten und nicht ersetzten Elementen basierend auf ihrem Seitenverhältnis anpassen. In diesem Leitfaden werden wir die aspect-ratio-Eigenschaft kennenlernen, über Seitenverhältnisse für ersetzte und nicht ersetzte Elemente sprechen und anschließend einige häufige Anwendungsfälle für Seitenverhältnisse untersuchen.

Wie die Eigenschaft aspect-ratio funktioniert

Der CSS-Wert der aspect-ratio-Eigenschaft definiert das bevorzugte Verhältnis von Breite zu Höhe eines Element-Kastens. Der Wert ist entweder ein <ratio>, das Schlüsselwort auto oder eine durch Leerzeichen getrennte Kombination aus beidem.

Das <ratio> ist das Verhältnis von Breite zu Höhe, in dieser Reihenfolge. Es wird durch zwei positive <number>-Werte dargestellt, die durch einen Schrägstrich (/) oder eine einzelne <number> getrennt sind. Wenn eine einzelne Zahl verwendet wird, entspricht dies dem Schreiben des Verhältnisses als <number> / 1, was ebenfalls der Breite geteilt durch die Höhe entspricht.

Die folgenden Werte sind alle gleichwertig:

css
aspect-ratio: 3 / 6;
aspect-ratio: 1 / 2;
aspect-ratio: 0.5 / 1;
aspect-ratio: 0.5;

Die folgenden Werte sind ebenfalls alle gleichwertig:

css
aspect-ratio: 9/6;
aspect-ratio: 3/2;
aspect-ratio: 1.5;

Die Wirkung des auto-Schlüsselworts hängt davon ab, ob das Element, auf dem es angewendet wird, ein ersetztes Element ist oder nicht. Für ersetzte Elemente mit einem intrinsischen Seitenverhältnis bedeutet auto, dass das intrinsische Seitenverhältnis verwendet werden sollte. In allen anderen Fällen bedeutet der auto-Wert, dass die Box kein bevorzugtes Seitenverhältnis hat. In beiden Fällen ist dies das Standardverhalten, als ob keine aspect-ratio-Eigenschaft angewendet wäre.

Wenn der Wert sowohl das Schlüsselwort auto als auch einen <ratio>-Wert enthält, wie z.B. aspect-ratio: auto 2 / 3; oder aspect-ratio: 0.75 auto;, wird der auto-Wert auf ersetzte Elemente mit einem natürlichen Seitenverhältnis angewendet, und das angegebene Verhältnis von width / height oder <number> wird als bevorzugtes Seitenverhältnis verwendet.

Sie werden bemerkt haben, dass in den obigen Definitionen das Wort "bevorzugt" vorkommt. Der aspect-ratio-Wert wird nicht immer angewendet, wenn er festgelegt ist. Die aspect-ratio-Eigenschaft setzt ein "bevorzugtes" Seitenverhältnis fest, sodass sie nur dann eine Wirkung entfaltet, wenn mindestens eine der Box-Größen automatisch ist.

Wenn sowohl die Höhe als auch die Breite oder die Inline- und Blockgrößen ausdrücklich festgelegt sind, wird der Wert der aspect-ratio-Eigenschaft ignoriert. In diesem Fall darf keine Dimension automatisch bemessen werden - die bevorzugten Größen sind ausdrücklich festgelegt - daher hat die aspect-ratio-Eigenschaft keine Wirkung. Wenn Sie sowohl die Inline- als auch die Blockdimensionen deklarieren, haben diese Vorrang.

Bei ersetzten Elementen, wenn Sie keinen Wert (außer auto) für eine Dimension explizit festlegen, wird standardmäßig die intrinsische Größe verwendet (jeder aspect-ratio-Wert wird nicht angewendet). Die aspect-ratio wird auf nicht ersetzte Elemente angewendet, die keine explizit festgelegte Dimension haben, da nicht ersetzte Elemente entweder intrinsisch oder extrinsisch dimensioniert sind und ihre Größe von ihrem Inhalt, Container, Box-Modell-Eigenschaften usw. erhalten.

Wenn ein Element auf der Seite gerendert wird, werden, wenn kein CSS angewendet ist und keine HTML-Größenattribute enthalten sind, das Objekt von der Benutzeroberfläche in seiner natürlichen Größe gerendert.

Anpassung der Seitenverhältnisse von ersetzten Elementen

Ersetzte Elemente wie <img> und <video> werden durch Medien ersetzt, die über festgelegte Dimensionen und daher über ein intrinsisches Seitenverhältnis verfügen. Betrachten Sie ein Rasterbild, wie z.B. ein JPEG, PNG oder GIF. Wenn Sie ein Bild auf einer Seite platzieren und keine Höhe oder Breite festlegen, weder über <img>-Attribute noch mit CSS, wird es in seiner intrinsischen Größe angezeigt.

Dies ist ein 220px großes quadratisches Bild ohne angewendetes CSS; es wird in seiner intrinsischen oder Standardgröße angezeigt.

Wenn das ersetzte Bild automatisch dimensioniert wird oder Sie nur für eine Dimension eine Größe angeben, z.B. einen Wert für width, wird der Browser die andere Dimension, in diesem Fall die Höhe, automatisch anpassen und dabei das ursprüngliche Seitenverhältnis des Mediums beibehalten.

In diesem Beispiel ist nur die width des Bildes festgelegt, sodass der Benutzeragent das Seitenverhältnis beibehält. Dasselbe Bild wird dreimal angezeigt, in verschiedenen Breiten: 55px, 110px und in seiner natürlichen Größe von 220px über den Wert width: auto.

Nur wenn Sie Größen für beide Dimensionen angeben, besteht die Gefahr, dass das ersetzte Element verzerrt wird. Wenn Sie z.B. width: 100vw; und height: 100vh; auf ein Bild setzen, erhalten Sie ein variables Seitenverhältnis; das Bild erscheint entweder gestreckt oder gestaucht, wenn sich das Seitenverhältnis des Ansichtsfensters vom natürlichen Seitenverhältnis des Bildes unterscheidet.

In diesem Beispiel wird dasselbe Bild dreimal wiederholt, explizit mit demselben height-Wert (110px) aber verschiedenen width-Werten (55px, 110px und 220px).

Wir haben die Bilder absichtlich verzerrt, indem wir sowohl eine height als auch eine width festgelegt haben: Wir haben das erste gestaucht und das dritte gestreckt.

Wir hätten denselben verzerrten Effekt mit der CSS-Eigenschaft aspect-ratio erzeugen können, indem wir eine einzelne Dimension (nicht beide oder keine) festgelegt und einen anderen Wert als 1 (oder 1/1) angegeben hätten. Sie wollen dies wahrscheinlich nicht tun, aber es ist gut zu wissen, dass es möglich ist.

css
img {
  height: 100vh;
  aspect-ratio: 3;
}

Wir haben eine einzelne Dimension deklariert; 100vh ist die volle Höhe des Ansichtsfensters des Beispiel-<iframe>. Damit aspect-ratio auf ersetzte Elemente angewendet werden kann, darf nur eine Dimension festgelegt sein. Das Festlegen beider oder keiner Dimension funktioniert nicht.

Ersetzte Elemente innerhalb ihrer Container anpassen

Um ein ersetztes Element an die Abmessungen seines Containers anzupassen und dabei sein intrinsisches Seitenverhältnis beizubehalten, setzen Sie den Wert der object-fit-Eigenschaft auf cover oder contain. Dadurch wird das ersetzte Element in der Größe angepasst und entweder abgeschnitten, um den Container zu "füllen" oder in einer kleineren Größe vollständig "eingepasst" angezeigt.

In diesem Beispiel wird das quadratische Bild in ein Raster mit drei Elementen eingefügt, von denen jedes ein Seitenverhältnis von 5 / 2 hat.

Zunächst erstellen wir einen Container mit drei Elementen, die jeweils ein Bild enthalten:

html
<div class="grid">
  <div>
    <img
      src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
      alt="Pride flag" />
  </div>
  <div>
    <img
      class="cover"
      src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
      alt="Pride flag" />
  </div>
  <div>
    <img
      class="contain"
      src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg"
      alt="Pride flag" />
  </div>
</div>

Als nächstes legen wir den Container als Raster fest, in dem jedes Element ein Seitenverhältnis von 2.5 (5/2) hat, mit einer minimalen Breite von 150px. Daher beträgt die minimale Höhe 60px. Die endgültige Breite und Höhe werden jedoch von der Breite des iframes des Beispiels bestimmt, die basierend auf Ihrer Ansichtsfenstergröße festgelegt wird:

css
.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  font-size: 0; /* to minimize whitespace */
}

div div {
  aspect-ratio: 5 / 2;
  background-color: #ccc;
}

Wir dimensionieren dann die Bilder und setzen die object-fit-Eigenschaft für die letzten beiden Bilder:

css
img {
  height: 100%;
  width: 100%;
}

.cover {
  object-fit: cover;
}

.contain {
  object-fit: contain;
}

Nur das erste Bild ist verzerrt (gestreckt). Wir hätten den fill-Wert von object-fit verwenden können, um denselben Effekt zu erzielen. Das cover-Bild spannt die gesamte Breite des Containers und wird vertikal zentriert, um innerhalb des Containers zu passen. Der contain-Wert stellt sicher, dass das Bild innerhalb des Containers enthalten ist, horizontal zentriert und verkleinert wird, um zu passen.

Festlegung von Seitenverhältnissen für nicht ersetzte Elemente

Während das Seitenverhältnis eines ersetzten Elements standardmäßig beibehalten wird, ändert sich das Seitenverhältnis eines nicht ersetzten Elements üblicherweise, wenn die intrinsische Größe angepasst wird. Beispielsweise kann identischer Inhalt auf einem Breitbildschirm oder in einem weiten übergeordneten Container als drei Zeilen erscheinen, während auf einem schmalen Bildschirm oder Container als acht Zeilen angezeigt wird.

In diesem Beispiel wird dasselbe Zitat in 200px und 600px breiten Containern angezeigt, und ein Quadrat wird mit einer Höhe festgelegt, die seiner 200px-Breite entspricht:

Um das Problem bei der Einstellung des Seitenverhältnisses eines nicht ersetzten Elements durch Größenabmessungen hervorzuheben, schalten Sie die overflow-Eigenschaft zwischen auto und visible um.

css
blockquote {
  width: 200px;
}

blockquote:nth-of-type(2) {
  width: 600px;
}

blockquote:nth-of-type(3) {
  height: 200px;
}

Während es möglich ist, ein Seitenverhältnis für nicht ersetzte Elemente zu definieren, indem beide Dimensionen festgelegt und überlaufender Inhalt verborgen wird, bietet die CSS-aspect-ratio-Eigenschaft explizite Unterstützung für das Seitenverhältnis. Dies bedeutet, dass ein bestimmtes Seitenverhältnis festgelegt werden kann, selbst wenn die Inhalte oder Bildschirmgrößen nicht bekannt sind.

Im nächsten Beispiel rendern wir quadratische Boxen unabhängig von der Breite des Textes, indem wir aspect ratio: 1 auf <blockquote>, ein nicht ersetztes Element, setzen:

css
blockquote {
  inline-size: max-content;
  aspect-ratio: 1;
}

Jede Box hat eine definierte Dimension: die inline-size, was die Breite in horizontalen Sprachen ist, wird auf max-content gesetzt, was die Größe auf das Maximale setzt, was erforderlich ist, um den Inhalt ohne Umbruch zu gewährleisten. Die zweite Dimension, in diesem Fall die block-size oder height, wird so gesetzt, dass sie genauso lang ist wie die erste Dimension. Dies wird mit der aspect-ratio-Eigenschaft erreicht. Wir haben das gewünschte Breite-zu-Höhe-Verhältnis des Element-Kastens auf 1 festgelegt, was dem gleichen wie 1/1, einem Quadrat, entspricht. Dies setzt die Blockrichtung so, dass sie der Breite des Elements entspricht, ohne die height- oder block-size-Eigenschaften zu verwenden.

In diesen Beispielen wurde eine Größe explizit auf das Element selbst gesetzt. Wenn mit nicht ersetzten Elementen gearbeitet wird, kommt das Seitenverhältnis ins Spiel, wenn keine Größenabmessung explizit gesetzt ist.

Erzeugen eines Kreises basierend auf der Containergröße

Die Inline-Größe von nicht ersetzten Block-Elementen ist die Größe ihrer Content-Box. Da sie von Natur aus eine Größe haben, müssen sie keine explizite Größe haben, damit die aspect-ratio-Eigenschaft funktioniert.

In diesem Beispiel haben wir einen <div>-Container, der 200px breit ist und 5px Polsterung auf jeder Seite enthält. Daher beträgt die Inline-Größe der Content-Box 190px. Ohne eine Höhe oder Breite auf dem verschachtelten <p>-Element zu setzen, wissen wir, dass seine Inline-Größe 190px beträgt. Mit aspect-ratio: 1 eingestellt, wird der Absatz 190px hoch, es sei denn, er hat sichtbaren überlaufenden Inhalt, der ihn größer macht (was er nicht hat).

Die Höhe des <div>-Elements ist nicht explizit festgelegt, aber es enthält den 190px hohen Absatz, die 5px Polsterung oben und unten sowie die kombinierten Höhen der Standard-Top- und Bottom-Ränder von <p>. Infolgedessen ist es höher als breit. Beide Elemente haben einen border-radius von 50%, sodass der Container oval und das Kind mit einem aspect-ratio von 1 aber ohne explizit definierte Inline- oder Blockgrößen ein Kreis ist.

html
<div><p>Hello world</p></div>
css
div,
p {
  border-radius: 50%;
}

div {
  width: 200px;
  padding: 5px;
  background-color: #66ccff;
}

p {
  aspect-ratio: 1;
  text-align: center;
  border: 10px solid #ffffff;
  background-color: #f4aab9;
}

Um den <div>-Container zu einem Kreis zu machen, können wir die height und width auf denselben Wert setzen oder aspect-ratio: 1 festlegen und den overflow auf auto oder hidden stellen. Alternativ können wir einfach die Ränder des Absatzes mit margin-block: 0 entfernen. Beide Optionen werden unten gezeigt.

html
<section>
  <div><p>Hello world</p></div>
  <div><p>Hello world</p></div>
  <section></section>
</section>
css
div,
p {
  aspect-ratio: 1;
  border-radius: 50%;
}

div:first-of-type {
  overflow: hidden;
}

div:last-of-type p {
  margin-block: 0;
}

Häufige Anwendungsfälle für aspect-ratio

Schauen wir uns einige Situationen an, in denen Sie aspect-ratio verwenden können, um einige häufige Herausforderungen bei der Erstellung responsiver Designs zu lösen.

Externe Ressourcen responsiv machen

Alle Inhalte sollten responsiv sein, auch wenn es sich um eingebettete externe Inhalte handelt, wie z.B. Videos von TikTok, YouTube oder Instagram. Der Code-Ausschnitt, den Sie einfügen, um diese externen Videos einzubetten, erstellt üblicherweise ein <iframe>.

Während ein <video>-Element typischerweise das Seitenverhältnis seiner Mediendatei annimmt, fehlt den iframe-Elementen diese Fähigkeit. Dies stellt die Herausforderung dar, sicherzustellen, dass das <iframe> responsiv ist und gleichzeitig das Seitenverhältnis des darin enthaltenen Videos beibehält. Eine der Techniken, die wir verwenden können, besteht darin, die Breite des iframes auf 100% seines Containers oder 100vw zu setzen, um die Breite des Ansichtsfensters unabhängig von der Größe des Ansichtsfensters anzupassen. Das Setzen einer festen Höhe kann jedoch dazu führen, dass das Video gestreckt oder gestaucht wird. Stattdessen setzen wir das aspect-ratio auf den Container des Videos und passen es so an, dass es dasselbe Seitenverhältnis wie das Video hat. Problem gelöst!

Zum Kontext: Das Standard-Seitenverhältnis von YouTube-Videos beträgt 16:9, wenn sie auf einem Desktop-Computer oder Laptop angesehen werden, während TikTok- und Instagram-Videos ein Seitenverhältnis von 9:16 haben.

css
.youtube {
  aspect-ratio: 16/9;
}

.instagram,
.tiktok {
  aspect-ratio: 9/16;
}

Wir können das aspect-ratio-Feature innerhalb der @media-Abfrage zusammen mit der aspect-ratio-Eigenschaft verwenden, um die Größe sowohl des iframes als auch des darin enthaltenen Videos anzupassen. Dies stellt sicher, dass das Videoinhalt immer so groß wie möglich ist - entweder die volle Breite oder Höhe des Ansichtsfensters einnimmt, unabhängig von der Ansichtsfenstergröße - und ein bestimmtes Seitenverhältnis beibehält.

Wir können die landschaftlich orientierten YouTube-Videos auf die Breite des Ansichtsfensters einstellen und die hochformatig orientierten TikTok- und Instagram-Video-iframes auf die Höhe des Ansichtsfensters. Wenn das Seitenverhältnis eines Ansichtsfensters breiter als 16:9 ist, setzen wir das YouTube-Video auf die Höhe des Ansichtsfensters. Wenn das Ansichtsfenster schmaler als 9:16 ist, setzen wir sowohl Instagram- als auch TikTok-Videos auf die Breite des Ansichtsfensters.

css
iframe.youtube {
  aspect-ratio: 16/9;
  width: 100vw;
  height: auto;
}

iframe.instagram,
iframe.tiktok {
  aspect-ratio: 9/16;
  height: 100vh;
  width: auto;
}

/* If the viewport is very wide but not very tall */
@media (aspect-ratio > 16 / 9) {
  iframe.youtube {
    width: auto;
    height: 100vh;
  }
}

/* If the viewport is very tall but not very wide */
@media (aspect-ratio < 9 / 16) {
  iframe.instagram,
  iframe.tiktok {
    height: auto;
    width: 100vw;
  }
}

Quadratische Gitterzellen erstellen

Ein Gitter aus quadratischen Zellen kann erstellt werden, indem feste Spurgrößen der Spalten definiert werden, sodass jede Zeile derselben Größe wie die Spalte ist. Bei der Erstellung responsiver Gitter mit auto-fill, um so viele Spuren wie möglich innerhalb des Containers zu füllen, wird die Breite jedes Elements jedoch unsicher. Dies macht es schwierig, die geeignete Höhe für das Erstellen quadratischer Elemente zu bestimmen.

Durch das Setzen eines Seitenverhältnisses auf die Elemente können wir sicherstellen, dass, wenn die Gitternetz-Elemente ausgelegt werden, jedes Gitternetz-Element so hoch wie breit ist und quadratische Gitternetz-Elemente entstehen, unabhängig von den Abmessungen des Containers.

In diesem Beispiel von quadratischen Gitternetz-Elementen sind die Gitternetz-Spuren automatisch dimensioniert, wobei ihre Größe von den Elementen übernommen wird. Jedes Element ist mindestens 95px breit, könnte jedoch viel breiter sein. Unabhängig von der Breite wird jedes Element ein Quadrat sein, wobei die Höhen durch das aspect-ratio auf die Breite abgestimmt wird.

css
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
}

.item {
  aspect-ratio: 1;
}

Um sicherzustellen, dass der Inhalt eines Gitternetz-Elements nicht über die bevorzugte Höhe hinauswächst, die durch das aspect-ratio festgelegt wird, setzen Sie die min-height auf 0 und den overflow auf einen anderen Wert als visible. Dies funktioniert für von Natur aus dimensionierte Inhalte. Wenn Sie Inhalte haben, die von Natur aus größer als der verfügbare Platz sind, setzen Sie diesen Inhalt so, dass er nicht größer als das Gitternetz-Element ist, indem Sie die max-height (oder max-width, abhängig vom Inhalt) auf 100% setzen.

css
.item {
  min-height: 0;
  overflow: auto;
}

.item > * {
  max-height: 100%;
}

Spezifikationen

Specification
CSS Box Sizing Module Level 3
# aspect-ratio

Siehe auch