Ich hatte neulich eine kleine Situation, in der ich eine dieser seitenverhältnis-freundlichen Boxen erstellen musste. Das ist nichts Besonderes Neues. Ich glaube, die ursprüngliche Anerkennung geht bis ins Jahr 2009 zurück, mit Thierry Koblentz' Intrinsic Ratios und behielt auch für andere Arten von Inhalten mit Artikeln wie Uncle Dave’s Ol’ Padded Box an Popularität.
Lassen Sie uns auf eine kleine Reise durch dieses Konzept gehen, da es viel zu besprechen gibt.
Das Kernkonzept: Innenabstand in Prozent basiert auf der Breite
Auch wenn das etwas unintuitiv ist, wie bei vertikalem Innenabstand. Das ist kein Hack, aber es ist seltsam: padding-top und padding-bottom basieren auf der width des Elternelements. Wenn Sie also ein Element hätten, das 500 Pixel breit ist, und einen padding-top von 100 %, wäre der padding-top 500 Pixel.
Ist das nicht ein perfektes Quadrat, 500px × 500px? Ja, ist es! Ein Seitenverhältnis!
Wenn wir die Höhe des Elements auf Null erzwingen (height: 0;) und keine Ränder haben. Dann ist der Innenabstand der einzige Teil des Box-Modells, der die Höhe beeinflusst, und wir haben unser Quadrat.
Stellen Sie sich nun vor, wir hätten statt 100 % oberen Innenabstand 56,25 % verwendet. Das ist ein perfektes 16:9-Verhältnis! (9 / 16 = 0,5625).
Jetzt haben wir eine freundliche Seitenverhältnis-Box, die in flüssigen Breiten gut funktioniert. Wenn sich die Breite ändert, ändert sich auch die Höhe, und das Element behält dieses Seitenverhältnis bei.
Anwendungsfall: ein Hintergrundbild
Vielleicht haben wir ein typografisches Lockup erstellt. Es ist für den Titel eines Artikels, daher ist es sinnvoll, ein <h1>-Tag zu verwenden.
<h1>
Happy Birthday
</h1>
Wir können dieses <h1> Tag zur Seitenverhältnis-Box machen und das Lockup als Hintergrundbild anwenden.
h1 {
overflow: hidden;
height: 0;
padding-top: 56.25%;
background: url(/images/happy-birthday.svg);
}
Aber ich habe bei dem Seitenverhältnis da oben gelogen. Es ist nicht wirklich ein 16:9-Bild. Ich habe diese Grafik gerade von einer Stockfoto-Website heruntergeladen. Es handelt sich zufällig um eine SVG mit einem viewBox="0 0 1127.34 591.44", was bedeutet, dass es sich im Hinblick auf das Seitenverhältnis im Wesentlichen um ein 1127,34 × 591,44-Bild handelt. Oder es könnte ein 328 × 791-Bild gewesen sein.
Ich würde sagen, es ist sehr üblich, dass zufällige Bilder nicht in ein ganz bestimmtes vordefiniertes Seitenverhältnis passen...
Die Mathematik jedes möglichen Seitenverhältnisses
Perfekte Quadrate und 16:9-Sachen sind großartig, aber die dafür verwendeten Werte sind nur einfache Mathematik. Ein Seitenverhältnis kann alles sein, und oft ist es vollkommen willkürlich. Ein Video oder Bild kann auf jede beliebige Größe zugeschnitten werden.
Wie ermitteln wir also den oberen Innenabstand für unsere SVG mit 1127,34 × 591,44 oben?
Eine Möglichkeit ist die Verwendung von calc(), wie hier
padding-top: calc(591.44 / 1127.34 * 100%);
Mir wurde vor kurzem gesagt, dass die Verwendung von calc() hier "langsamer" sein mag, aber ich habe nie Beweise dafür gesehen. Ich stelle mir vor, dass ja, der Computer muss etwas berechnen, also ist bei einem Kopf-an-Kopf-Rennen gegen eine Situation, in der er es nicht tut, die Berechnung langsamer. Aber ein mathematisches Problem scheint für einen Computer keine allzu große Arbeit zu sein. Zum Beispiel konnte der beliebte Intel Pentium III (erschienen 1999) 2.054 MIPS oder "Millionen von Instruktionen pro Sekunde" verarbeiten, sodass er eine Division unmerklich schnell erledigen würde. Und jetzt sind Chips 50-mal schneller.
Wenn wir einen Präprozessor wie Sass verwenden würden, könnten wir die Berechnung im Voraus durchführen
padding-top: 591.44px / 1127.34px * 100%;
So oder so, ich bin ein Fan davon, die Mathematik im erstellten Code zu belassen.
Wie fügt man Inhalt ein, wenn der Innenabstand alles nach unten verschiebt?
Wir haben den Inhalt in der obigen Demo verborgen, indem wir den Inhalt herausdrängen und den Überlauf ausblenden. Aber was, wenn Sie eine Seitenverhältnis-Box benötigen und den Inhalt darin behalten möchten? Das ist etwas kniffliger. Wir müssen ihn wieder nach oben positionieren. Absolute Positionierung kann diese Aufgabe übernehmen.
Nehmen wir an, wir verwenden jetzt nur Text, möchten aber immer noch die Seitenverhältnis-Box. Wir benötigen einen inneren Wrapper für die absolute Positionierung. Lassen Sie uns spezifisch mit unseren Klassennamen werden
<h1 class="aspect-ratio-box">
<div class="aspect-ratio-box-inside">
Happy Birthday
</div>
</h1>
Dann machen wir die Positionierung
.aspect-ratio-box {
height: 0;
overflow: hidden;
padding-top: 591.44px / 1127.34px * 100%;
background: white;
position: relative;
}
.aspect-ratio-box-inside {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Nur zum Spaß, machen wir hier alles rein und zentrieren den Text und skalieren ihn, damit er mit der Box skaliert
<h1 class="aspect-ratio-box">
<div class="aspect-ratio-box-inside">
<div class="flexbox-centering">
<div class="viewport-sizing">
Happy Birthday
</div>
</div>
</div>
</h1>
Noch ein paar Klassen zum Stylen
.flexbox-centering {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.viewport-sizing {
font-size: 5vw;
}
Anwendungsfall: Video
Dies ist wahrscheinlich der am häufigsten und praktischste Anwendungsfall für all diese Seitenverhältnis-Box-Sachen. HTML5 <video> ist kein Problem, da es sich verhält, als hätte es ein Seitenverhältnis, genau wie <img>. Aber viele Videos im Web kommen in <iframe>s, die sich nicht mit einem Seitenverhältnis skalieren.
Genau darum geht es bei FitVids. Es findet Videos auf der Seite, ermittelt ihre einzigartigen Seitenverhältnisse und wendet dann dieselben CSS-Konzepte an, um sie flüssig zu machen und gleichzeitig ihre einzigartigen Seitenverhältnisse beizubehalten.
FitVids basiert auf jQuery, aber es gibt Vanilla-JavaScript-Optionen, wie diese hier von Ross Zurowski.
Aber… was, wenn es zu viel Inhalt gibt?
Zurück zu beliebigem (wahrscheinlich textlichem) Inhalt für einen Moment.
Wir legen hier im Wesentlichen *Höhen* fest, was beim Arbeiten mit CSS immer ein *blinkendes rotes Licht* aufleuchten lassen sollte. Das Web wächst gerne nach unten, und das Festlegen fester Höhen ist ein Feind dieser natürlichen Bewegung.
Wenn der Inhalt für den Platz zu viel wird, befinden wir uns im Reich des schlechten Designs

Vielleicht könnten wir etwas wie overflow: auto; tun, aber das könnte im Reich des unbeholfenen Designs liegen.
Die Pseudo-Element-Taktik
Dies ist meiner Meinung nach der beste Weg, um eine Seitenverhältnis-Box mit völlig beliebigem Inhalt zu handhaben. Keith Grant hat einen guten Artikel dazu. Marc Hinse hatte bereits 2013 eine Erklärung und Demos.
Mit dieser Technik erhalten Sie die Seitenverhältnis-Box mit weniger Markup, und sie ist *immer noch sicher*, wenn der Inhalt die Höhe überschreitet.
Der Trick besteht darin, den %-Innenabstand auf ein Pseudo-Element statt auf die Box selbst anzuwenden. Sie schwebend das Pseudo-Element, damit der Inhalt darin schön platziert werden kann, und löschen dann den Float.
.aspect-ratio-box {
background: white;
}
.aspect-ratio-box::before {
content: "";
width: 1px;
margin-left: -1px;
float: left;
height: 0;
padding-top: 591.44px / 1127.34px * 100%;
}
.aspect-ratio-box::after { /* to clear float */
content: "";
display: table;
clear: both;
}
Sehen Sie, wie es sicherer ist

Und ein Video
Verwendung von benutzerdefinierten Eigenschaften
Dies ist vielleicht die coolste Idee von allen!
Thierry Koblentz hat dies kürzlich aufgeschrieben (Link entfernt, da Thierry's Seite tot ist.), Sérgio Gomes für die Idee gutgeschrieben.
Um es zu verwenden, setzen Sie eine benutzerdefinierte Eigenschaft, die direkt auf das benötigte Element beschränkt ist
<div style="--aspect-ratio:815/419;">
</div>
<div style="--aspect-ratio:16/9;">
</div>
<!-- even single value -->
<div style="--aspect-ratio:1.4;">
</div>
Das CSS, das dies stylt, ist verdammt genial
[style*="--aspect-ratio"] > :first-child {
width: 100%;
}
[style*="--aspect-ratio"] > img {
height: auto;
}
@supports (--custom:property) {
[style*="--aspect-ratio"] {
position: relative;
}
[style*="--aspect-ratio"]::before {
content: "";
display: block;
padding-bottom: calc(100% / (var(--aspect-ratio)));
}
[style*="--aspect-ratio"] > :first-child {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
Lassen Sie mich Thierry's Schritt-für-Schritt-Erklärung zitieren
- Wir verwenden
[style*="--aspect-ratio"]als Hook, um die entsprechenden Boxen anzusprechen - Wir strecken die innere Box, unabhängig von der Unterstützung für benutzerdefinierte Eigenschaften
- Wir stellen sicher, dass die Höhe von Bildern aus ihrem intrinsischen Verhältnis und nicht aus ihren
height-Attributen stammt - Wir stylen den Container als enthaltenden Block (damit die innere Box diesen Vorfahren für ihre Positionierung referenziert)
- Wir erstellen ein Pseudo-Element, das mit dem "Padding-Hack" verwendet wird (es ist dieses Element, das das Seitenverhältnis erzeugt)
- Wir verwenden
calc()undvar(), um den Innenabstand basierend auf dem Wert der benutzerdefinierten Eigenschaft zu berechnen - Wir stylen die innere Box so, dass sie den Abmessungen ihres enthaltenden Blocks entspricht
Andere Ideen & Werkzeuge
Lisi Linhart hat mich auf Ratio Buddy aufmerksam gemacht, was super cool ist

Beachten Sie, dass es ein Pseudo-Element verwendet, aber dann immer noch den inneren Container absolut positioniert. Das ist irgendwie seltsam. Sie würden wahrscheinlich entweder das Pseudo-Element überspringen und den Innenabstand direkt auf den Container legen oder das Pseudo-Element schweben lassen, damit Sie keinen inneren Container benötigen. Dennoch gefällt mir die Idee eines kleinen Generators dafür.
Tommy Hodgins hat CSSplus, das Aspecty enthält, das genau dafür da ist, vorausgesetzt, Sie sind damit einverstanden, dass eine JavaScript-Analyse und -Änderung Ihres CSS erfolgt
Ich habe im Laufe der Jahre tatsächlich ziemlich viel reale Nutzung von Seitenverhältnis-Boxen gesehen. Teilen Sie gerne mit, wenn Sie Erfahrungen damit haben!
Ich denke, wenn wir
attrinnerhalb voncalcalsnumberverwenden könnten, würden wir so etwas verwenden:height: calc(attr(width)/calc(height) * ...)Dann müssten Sie auf alte Breite- und Höheneigenschaften jedes Elements zurückgreifen.
Ich mag diese Idee. Ja, die Verwendung von Höhe/Breite ist jetzt etwas veraltet, aber dies macht es komplett automatisiert und funktioniert für Dinge wie eingefügte YouTube-Embeds, ohne jeglichen Aufwand für einen Benutzer (im Falle eines CMS).
Wirklich ein CSS-Trick.
Ich muss mich fragen, ob Browser dafür irgendwann eine richtige Lösung finden werden. So wie es früher üblich war,
float:rightzu verwenden, wenn man etwas neben fließendem Inhalt rechtsbündig ausrichten wollte, was jetzt durch Flexbox unnötig geworden ist.Das Schöne an benutzerdefinierten Eigenschaften ist, dass ein Selektor wie
[style*="--aspect-ratio"]mir etwas "zerbrechlich" erscheint. Eine Namenskonvention muss streng eingehalten werden, oder ein Attribut wiestyle="--aspect-ratio-alt: 1.5"würde die Deklaration auslösen.Übrigens, ist es nur bei mir so, oder können wir die meisten Videos nicht sehen? Ich habe vier "Failed to load resource: net::ERR_SPDY_PROTOCOL_ERROR"-Fehler in der Konsole (Chrome 60 unter Mac – aber auch Chrome 58 unter Android).
Guter Punkt. Aber nur um eine zusätzliche Coolness der Technik hervorzuheben,
style="--aspect-ratio-alt: 1.5"funktioniert trotzdem!„padding-top und padding-bottom basieren auf der Breite eines Elements.“
Ich würde dies ändern zu: „basierend auf der Breite des *Elternelements*.“ Es ist ein kleiner Unterschied, aber es hat mich ewig gekostet, das zu verstehen, als ich es zum ersten Mal herauszufinden versuchte. Sie können nicht einfach einen Div erstellen, der 500 Pixel breit ist, ihn auf null Höhe setzen und 100 % Innenabstand darauf anwenden und diesen 500 Pixel großen roten Kasten erhalten. Er muss bereits in einem 500 Pixel breiten Div liegen!
Und wo wir gerade dabei sind: Dies ist für mich das seltsamste CSS-Verhalten. Ich verstehe persönlich nicht, wie es dazu kam… aber ich bin dankbar, dass es funktioniert! Ich benutze es in fast jedem Projekt.
Und die Tatsache, dass es auf einem Elternteil basiert, ist der Grund, warum
ist überhaupt nicht seltsam.
Das Anwenden des Innenabstands auf das Pseudo-Element macht effektiv das Höhenverhältnis vom Breite des Elements selbst abhängig und nicht von der Breite des Containers des Elements.
Das Anwenden des Innenabstands auf das Element selbst würde eine Feinabstimmung der Innenabstandseinstellung erfordern, wenn Sie dem Element eine bestimmte Breite geben, die nicht 100 % beträgt.
Danke für diese Klarstellung. Und ich fand es interessant, dass Sie dies in fast jedem Projekt verwenden. Ich habe es bei einem verwendet, und ja, das ist einer der seltsamsten Aspekte von CSS.
Eine weitere Variante der oben beschriebenen "Pseudo-Element"-Technik ist die Verwendung eines *Flexbox*-Containers anstelle des *Block > Float-und-Clear*-Musters, da Flex-Zeilen-Geschwister immer so hoch sein werden wie das höchste in der Zeile. Markup und Stil sind noch einfacher
flexbox max-aspect 2:1
Gute Zusammenstellung traditioneller Techniken oder "CSS Old School" ;-)
Heute ist es jedoch bereits möglich, dasselbe zu tun, ohne Innenabstände berechnen zu müssen, "position: absolute" deklarieren zu müssen oder Variablen oder andere Methoden verwenden zu müssen, um das Seitenverhältnis beizubehalten.
All dies kann von CSS Grid Layout für uns erledigt werden, da es möglich ist, mehrere Elemente in derselben Grid-Bereich zu platzieren, ohne den Dokumentenfluss zu verlassen.
Ein Pen als Beispiel
https://codepen.io/Kseso/full/VWaWZR/
Ein Beitrag (Entschuldigung, es ist auf meinem Blog) mit weiteren Beispielen und einer Erklärung auf Spanisch.
Wo ich arbeite, fordern Content-Ersteller, dass ALLE Bilder IMMER 16:9 sind – was eine anspruchsvolle Aufgabe ist, wenn wir auch anpassbare, responsive und mobilfreundliche Websites erstellen.
Unsere Lösung war es, ein nahezu 16:9 bei der gängigsten Browsergröße zu unterstützen und mit unseren Kunden zusammenzuarbeiten, um die Vorteile zu erklären, Inhalte nicht ständig an ein Verhältnis zu binden. Wir setzen background-size/object-fit: contain als Übergangslösung ein, wenn sie es trotzdem wollen. Es lohnt sich nicht, unsere gesamte Plattform um ein einzelnes Verhältnis herum aufzubauen.
Relevanter aktueller verwandter Artikel
https://www.bram.us/2017/06/16/aspect-ratios-in-css-are-a-hack/
Tolle Pseudo-Element-Tipps für Verhältnisse! Aber wie kann man dann Text horizontal zentrieren? (Wenden Sie die Float-Technik auf das Happy Birthday Demo an.)
Eine Flex-Lösung bricht den %-Innenabstand, absolut nicht vergrößert die Boxhöhe…
Geoff Yuen schreibt
Und verweist auf Stack Overflow für eine Erklärung: https://stackoverflow.com/questions/36783190/why-doesnt-percentage-padding-margin-work-on-flex-items-in-firefox-and-edge/36783414#36783414