2014-03-26 16 views
27

Dies ist ein wenig schwierig zu erklären, aber: Ich möchte eine ansprechende Höhe div (height: 100%), der die Breite proportional zur Höhe (nicht umgekehrt) skaliert.CSS: div Breite proportional zur Höhe macht

Ich kenne this method mit einem padding-top Hack, um die Höhe proportional zur Breite zu machen, aber ich brauche es anders herum zu arbeiten. Abgesehen davon, bin ich nicht besonders scharf auf die zusätzliche Anforderung von absolut positionierten Elementen für den Inhalt dieser Methode, also merke ich, dass ich hier durchaus nach dem Mond fragen kann.

sichtbar zu machen, hier zu helfen, ist ein Bild:

Visual representation of desired effect

... und hier ist ein jsFiddle, so ziemlich die gleiche Sache darstellt.

Es ist erwähnenswert, dass ich bereits die :before und :after pseudo-Elemente vertikal ausrichten, den Inhalt der Box I proportional skalieren möge verwenden.

Ich würde wirklich, wirklich genießen nicht zu jQuery zurückkehren müssen, nur weil es eine inhärente Voraussetzung für Resize-Handler sein wird und generell rundum Debuggen ... aber wenn das ist meine einzige Wahl, dann fiat.

+0

Ich fürchte, dass Sie Javascript dafür verwenden müssen ... –

+0

Es gibt keinen anderen Weg als den Trick mit 'padding' oder' margin' http://jsfiddle.net/V2dyZ/3/. Irgendwie müssen wir eine Beziehung zwischen der Breite und der Höhe finden, so dass wir die Höhe entsprechend einstellen können, aber normalerweise ist die 'Breite' nur relativ zur 'Breite' des Elternteils, die' Höhe' ist nur relativ zu der 'Höhe' des Elternteils ', es gibt nur eine Besonderheit an 'margin' und 'padding', dass ihr Wert in ** prozentual ** (relativer Wert) auf der 'Breite' des Elternteils basiert, unabhängig davon, ob 'padding-top', 'padding' gesetzt ist -bottom' oder 'margin-top',' margin-bottom', also haben wir eine Lösung (nur?) –

+0

[verwandt] (http://stackoverflow.com/questions/20456694/grid-of-responsive-squares/ 29670456 # 29670456) – jbutler483

Antwort

12

Ich frage mich seit einiger Zeit über eine pure-css-Lösung für dieses Problem. Ich kam schließlich mit einer Lösung unter Verwendung von ems auf, die schrittweise mit vws verbessert werden können:

Siehe codepen Link für volle Arbeits Demo und Erläuterung:

http://codepen.io/patrickkunka/pen/yxugb

Vereinfachte Version:

.parent { 
    font-size: 250px; // height of container 
    height: 1em; 
} 

.child { 
    height: 100%; 
    width: 1em; // 100% of height 
} 
+5

Hier scheint 'font-size' wirklich ein hässlicher und potentiell unbequemer Hack zu sein. – You

+0

Super-spät akzeptieren! Ich habe völlig vergessen, dass ich diese Frage gestellt habe, dann habe ich genau das gleiche gegoogelt und meine Frage war zuerst. Wie es sich herausstellt, hat dies genau das gemacht, was ich wollte (mit einem kleinen bisschen Feineinstellung für Inline-Proportionen - berechnet aus Bildgrößenverhältnissen). Danke für den Tipp! – indextwo

13

Oh, Sie könnten wahrscheinlich diesen "Padding-Top" Trick verwenden.

width: 50%; 
height: 0; 
padding-bottom: 50%; 

http://absolide.tumblr.com/post/7317210512/full-css-fluid-squares

Oder:

.square-box{ 
    position: relative; 
    width: 50%; 
    overflow: hidden; 
    background: #4679BD; 
} 
.square-box:before{ 
    content: ""; 
    display: block; 
    padding-top: 100%; 
} 

http://codeitdown.com/css-square-rectangle/

Die vertikale padding in CSS an die Breite des Elements verbunden ist, nicht die Höhe.

+0

Das erste ist nicht wirklich anwendbar, weil das 'div' etwas Inhalt enthalten kann, es sei denn, wir optimieren es etwas mit absoluter Positionierung ..., natürlich ist es in Ordnung, wenn wir nur ein leeres Quadrat div brauchen. –

+2

Ja, ich weiß davon; Leider ist die Spezifikation dieses Designs, dass die Breite proportional zur Höhe eingestellt werden muss, nicht umgekehrt. Es sieht so aus, als würde ich mich für jQuery interessieren. – indextwo

1

Basierend auf der Antwort von @ kunkalabs (was wirklich schlau ist) habe ich eine Lösung gefunden, mit der Sie die ererbte Schriftgröße beibehalten können.

HTML:

<div id='rect'> 
    <div id='content'>Text</div> 
</div> 

CSS:

#rect { 
    font-size: 1000%; 
    height: 1em; 
    width: 1em; 
    position: relative; 
} 

#content { 
    font-size: 10%; 
} 

Also im Grunde die Schriftgröße von #content ist (100/$ rectFontSize) * 100 Prozent des Rechtecks.Wenn Sie eine bestimmte Pixelgröße für das Rechteck benötigen, können Sie die Schriftgröße des übergeordneten Elements #rect einstellen ... ansonsten passen Sie einfach die Schriftgröße an, bis sie an der Stelle ist, an der Sie sie haben möchten (und Ihren Designer dazu verärgern).

+0

Hier ist eine Geige zu demonstrieren http://jsfiddle.net/bjqkf458/ – hobberwickey

+0

Gibt es eine Möglichkeit, diese Skala in Reaktion auf die Breite des Darstellungsbereichs zu machen? – jtheletter

+1

Gute Frage, da ist sicher (obwohl Sie die ererbte Schriftbreite verlieren), ändern Sie einfach "#rect font-width, um den Viewport relative CSS-Einheiten für die Schriftgröße zu verwenden. Also etwas wie' font-size: 10vw' bedeutet Ihr Rechteck wird im obigen Fall immer 10% der Breite und Höhe des Ansichtsfensters betragen. Wenn Sie möchten, dass die Schriftart des Inhalts skaliert wird (was keine schlechte Idee ist), lassen Sie es als Prozent, sonst müssen Sie Setzen Sie einen Pixel Wert. – hobberwickey

-2

Lassen Sie das übergeordnete DIV sich wie eine Tabellenzelle verhalten und richten Sie das untergeordnete Element vertikal aus. Sie müssen keine Padding-Tricks machen.

HTML

<div class="parent"> 
<img src="foo.jpg" /> 
</div> 

CSS

.parent { width:300px; height:300px; display:table-cell; vertical-align:middle; } 
+2

Der vertikal zentrierte Inhalt war nicht das Problem - es machte die Höhe des enthaltenden Elements * proportional reagierend * zu seiner Breite In Ihrem Beispiel verwenden Sie fest codierte Werte für beide. – indextwo

4

Die Schrift Lösung erfordert, dass die Höhe bekannt ist. Ich habe eine Lösung gefunden, um ein Element innerhalb eines Elternteils mit unbekannter Breite und Höhe proportional zu machen. Here is a demo.

Der Trick, den ich verwende, ist ein Bild als Spacer verwendet werden. Der Code erklärt:

<div class="heightLimit"> 
<img width="2048" height="2048" class="spacer" 
    src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAA 
     P///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"> 
<div class="filler"> 
    <div class="proportional"> 
    </div> 
</div> 
</div> 

So ist es nicht das schönste mit zwei extra Divs und ein nutzloses Bild. Aber es könnte schlimmer sein. Das Bildelement muss Breite und Höhe mit den gewünschten Abmessungen haben. Breite und Höhe müssen so groß sein wie die maximal zulässige Größe (ein Feature!).

Die CSS:

.heightLimit { 
position: absolute; 
top: 0; 
left: 0; 
height: 100%; 
width: auto; 
max-width: 100%; 
overflow: hidden; 
} 

Dieses Element ist um die Höhe zu begrenzen, sondern horizontal (width: auto), obwohl niemals über die parent (max-width) zu erweitern. Der Überlauf muss ausgeblendet werden, da einige Kinder aus dem div herausragen werden.

.spacer { 
width: auto; 
max-height: 100%; 
visibility: hidden; 
} 

Dieses Bild ist unsichtbar, und proportional zu der Höhe skaliert, während die Breite eingestellt wird, und drückt die Breite der übergeordneten auch angepasst werden.

.filler { 
position: absolute; 
top: 0; 
left: 0; 
bottom: 0; 
right: 0; 
} 

Dieses Element wird benötigt, um den Raum mit einem absolut positionierten Container zu füllen.

.proportional { 
position: relative; 
width: 100%; 
height: 0; 
padding-bottom: 100%; 
} 

Und hier bekommt unser proportionales Element eine Höhe proportional zur Breite mit dem bekannten Padding-Bottom-Trick.

Leider gibt es einen Fehler in Chrome und IE. Wenn Sie also das übergeordnete Element mit Javascript ändern, wie in meiner Demo, werden die Dimensionen nicht aktualisiert. Es gibt einen Hack, der angewendet werden kann, um das zu lösen, wie in meiner Demo gezeigt.