Wie wird der Rand oder die Polsterung als Prozentsatz der Höhe des übergeordneten Containers festgelegt?


236

Ich hatte mir den Kopf zerbrochen, um eine vertikale Ausrichtung in CSS zu erstellen

.base{
        background-color:green;
	    width:200px;
	    height:200px;
	    overflow:auto;
	    position:relative;
	}

    .vert-align{
		padding-top:50%;
		height:50%;
	}
<!-- and used the following div structure. -->

    <div class="base">
       <div class="vert-align">
    	   Content Here
       </div>
    </div>

Während dies für diesen Fall zu funktionieren schien, war ich überrascht, dass die vertikale Ausrichtung einrasten würde, wenn ich die Breite meines Basis-Div vergrößerte oder verkleinerte. Ich hatte erwartet, dass beim Festlegen der Eigenschaft padding-top das Auffüllen als Prozentsatz der Höhe des übergeordneten Containers verwendet wird, was in unserem Fall die Basis ist, aber der obige Wert von 50 Prozent wird als Prozentsatz von berechnet Breite. :((

Gibt es eine Möglichkeit, die Auffüllung und / oder den Rand als Prozentsatz der Höhe festzulegen, ohne JavaScript zu verwenden?

Antworten:


223

Die Lösung ist , dass ja, senkrechte Polsterung und Rand - zu - Breite relativ ist, aber , topund bottom ist es nicht.

Platzieren Sie also einfach ein Div in einem anderen und verwenden Sie im inneren Div etwas wie top:50%(denken positionSie daran , wenn es immer noch nicht funktioniert).


3
topeignet sich hervorragend zum Ändern der Größe basierend auf der Browser- / Fensterhöhe. Wie wäre es mit einem Div unter diesem Div? Wie können Sie cleardie 2. Div unter der Div sein, die um ein nach unten verschoben ist top:50%?
Federico

Lerne etwas Neues. Wusste vorher nicht, dass vertikale Polsterung und Rand relativ zur Breite sind. Danke dir.
Shaosh

5
Es ist auch möglich, ein 'Spacer'-Div mit einer festgelegten prozentualen Höhe hinzuzufügen. Scheint wenig schmutzig, aber es funktioniert. siehe diese Antwort .
WCByrne

4
Was zum ewigen Leben @%! ^? Warum sind vertikaler Rand und Polsterung relativ zur Breite ? WAS? Warum um alles in der Welt wurde diese Entscheidung getroffen?
temporärer_Benutzername

Ihre Antwort ist im Vergleich zu Alains Antwort unten, die eine allgemeine Lösung darstellt, äußerst unverhältnismäßig positiv, und ich fand sie sehr hilfreich und habe sie fast nicht gesehen. top: 50%ist nicht sehr nützlich, wenn Sie den Inhalt an der eigenen Mitte ausrichten müssen.
Okovko

35

Eine Antwort auf eine etwas andere Frage: Sie können vhEinheiten verwenden, um Elemente in der Mitte des Ansichtsfensters aufzufüllen :

.centerme {
    margin-top: 50vh;
    background: red;
}

<div class="centerme">middle</div>

Warum wird diese Antwort nicht höher gewählt? Stimmt etwas mit der Verwendung von vh nicht?
AlanH

3
Dies liegt daran, dass es sich nicht um eine Antwort handelt, die auf die ursprüngliche Frage zugeschnitten ist, sondern um einen nützlichen Trick, der nur in wenigen verwandten Fällen funktioniert.
Willoller

Verwenden vhist fast das gleiche wie Prozentsätze ... in einigen Fällen sogar noch schlimmer. Diese Antwort ist für die Frage irrelevant
vsync

33

Hier sind zwei Optionen, um das erforderliche Verhalten zu emulieren. Keine allgemeine Lösung, kann aber in einigen Fällen hilfreich sein. Der vertikale Abstand wird hier auf der Grundlage der Größe des äußeren Elements berechnet, nicht seines übergeordneten Elements. Diese Größe selbst kann jedoch relativ zum übergeordneten Element sein, und auf diese Weise wird auch der Abstand relativ.

<div id="outer">
    <div id="inner">
        content
    </div>
</div>

Erste Option: Verwenden Sie Pseudoelemente, hier sind der vertikale und der horizontale Abstand relativ zum äußeren. Demo

#outer::before, #outer::after {
    display: block;
    content: "";
    height: 10%;
}
#inner {
    height: 80%;
    margin-left: 10%;
    margin-right: 10%;
}

Wenn Sie den horizontalen Abstand zum äußeren Element verschieben, wird er relativ zum übergeordneten Element des äußeren Elements. Demo

#outer {
    padding-left: 10%;
    padding-right: 10%;
}

Zweite Option: Absolute Positionierung verwenden. Demo

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}

10

Um das untergeordnete Element absolut von seinem übergeordneten Element zu positionieren, müssen Sie die relative Position auf dem übergeordneten Element UND die absolute Position auf dem untergeordneten Element festlegen.

Dann ist 'top' auf dem untergeordneten Element relativ zur Höhe des übergeordneten Elements. Sie müssen also auch das Kind 50% seiner eigenen Größe nach oben "übersetzen".

.base{
    background-color: green;
    width: 200px;
    height: 200px;
    overflow: auto;
    position: relative;
}
    
.vert-align {
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
    <div class="base">
        <div class="vert-align">
            Content Here
        </div>
    </div>

Es gibt eine andere Lösung mit Flexbox.

.base{
    background-color:green;
    width: 200px;
    height: 200px;
    overflow: auto;
    display: flex;
    align-items: center;
}
<div class="base">
    <div class="vert-align">
        Content Here
    </div>
</div>

Sie finden Vor- und Nachteile für beide.


1
Die Verwendung von translate ist die einzige echte Möglichkeit, ein Element relativ zu seiner eigenen Größe vertikal zu verschieben.
Eran Goldin

Danke dafür. Dies sollte die gewählte Antwort sein.
Wessam El Mahdy

6

Dies kann mit der writing-modeEigenschaft erreicht werden. Wenn Sie ein Element writing-modeauf einen vertikalen Schreibmodus einstellen , zvertical-lr werden die Prozentwerte seiner Nachkommen für Auffüllen und Rand in beiden Dimensionen relativ zur Höhe anstatt zur Breite.

Aus der Spezifikation :

. . . Prozentsätze der Rand- und Polsterungseigenschaften, die immer in Bezug auf die Breite des enthaltenen Blocks in CSS2.1 berechnet werden, werden in Bezug auf die Inline-Größe des enthaltenen Blocks in CSS3 berechnet .

Die Definition der Inline-Größe :

Eine Messung in der Inline-Dimension: Bezieht sich auf die physische Breite (horizontale Dimension) in horizontalen Schreibmodi und auf die physische Höhe (vertikale Dimension) in vertikalen Schreibmodi.

Beispiel mit einem veränderbaren Element, bei dem horizontale Ränder relativ zur Breite und vertikale Ränder relativ zur Höhe sind.

.resize {
  width: 400px;
  height: 200px;
  resize: both;
  overflow: hidden;
}

.outer {
  height: 100%;
  background-color: red;
}

.middle {
  writing-mode: vertical-lr;
  margin: 0 10%;
  width: 80%;
  height: 100%;
  background-color: yellow;
}

.inner {
  writing-mode: horizontal-tb;
  margin: 10% 0;
  width: 100%;
  height: 80%;
  background-color: blue;
}
<div class="resize">
  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>
</div>

Die Verwendung eines vertikalen Schreibmodus kann besonders nützlich sein, wenn das Seitenverhältnis eines Elements konstant bleiben soll, die Größe jedoch in Abhängigkeit von seiner Höhe anstelle der Breite skaliert werden soll.


Dies ist, IMO, die elegantere Lösung, aber (Stand: 05.05.2018) werden vertikale Schreibmodi nicht gut unterstützt . Hoffentlich ändert sich das bald.
Zanerock

1
@zanerock Ich bin ziemlich sicher, dass die MDN-kompatible Tabelle veraltet ist. Zum Beispiel heißt es, dass Safari das -webkit-Präfix benötigt, aber laut caniuse das Präfix seit Safari 11 nicht mehr benötigt hat. Haben Sie es mit einem Browser versucht, in dem es nicht funktioniert hat?
James T

1
Nein, ich muss zugeben, ich habe nur angenommen, dass es gut und sogar automatisiert war.
Zanerock

4

Eine andere Möglichkeit, einen Zeilentext zu zentrieren, ist:

.parent{
  position: relative;
}

.child{
   position: absolute;
   top: 50%;
   line-height: 0;
}

oder nur

.parent{
  overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}

.child{
   margin-top: 50%;
   line-height: 0;
}

0

Eine 50% ige Polsterung zentriert Ihr Kind nicht, sondern platziert es unterhalb der Mitte. Ich denke, Sie wollen wirklich eine Polsterung von 25%. Vielleicht geht Ihnen gerade der Speicherplatz aus, wenn Ihre Inhalte größer werden? Haben Sie auch versucht, die Randoberseite anstelle der Polsteroberseite festzulegen?

EDIT: Nevermind, heißt es auf der Website von w3schools

% Gibt den Abstand in Prozent der Breite des enthaltenen Elements an

Vielleicht verwendet es immer die Breite? Ich hatte es nie bemerkt.

Was Sie tun, kann jedoch mit display: table erreicht werden (zumindest für moderne Browser). Die Technik wird hier erklärt .


1
Danke Spliff. Ich verstehe, dass meine 50% den Inhalt des Div nicht zentrieren werden. Ich habe tatsächlich nur eine Textzeile, die vertikal zentriert werden muss. Vielen Dank für den Link!
Ryan

3
Wenn es sich nur um eine Textzeile handelt, haben Sie darüber nachgedacht, eine lächerlich große Textzeile zu verwenden line-height, dh die Zeilenhöhe auf 200 Pixel festzulegen?
SpliFF

@ Ryan für die vertikale Zentrierung von Text, siehe stackoverflow.com/questions/8865458/…
Benutzer

Ihr Link ist defekt
quemeful

0

Dies ist ein sehr interessanter Fehler. (Meiner Meinung nach ist es sowieso ein Fehler) Netter Fund!

In Bezug auf, wie es zu setzen, würde ich Camilo Martin Antwort empfehlen. Aber warum , ich würde das gerne ein bisschen erklären, wenn es euch nichts ausmacht.


In den CSS-Spezifikationen fand ich:

'padding'
Prozentsätze: beziehen sich auf die Breite des enthaltenen Blocks

… Was komisch ist, aber okay.

Mit einem Elternteil width: 210pxund einem Kind padding-top: 50%erhalte ich einen berechneten / berechneten Wert von padding-top: 96.5px- was nicht der erwartete Wert ist 105px.

Dies liegt daran, dass in Windows (ich bin mir bei anderen Betriebssystemen nicht sicher) die Größe der gängigen Bildlaufleisten standardmäßig 17px × 100%(oder 100% × 17pxfür horizontale Balken) ist. Diese 17pxwerden vorher abgezogen Berechnung des 50%daher50% of 193px = 96.5px .


Es gibt einen Grund für die Spezifikation, und dies erklärt es besser: hongkiat.com/blog/calculate-css-percentage-margins
manikanta
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.