Jak wyśrodkować element div w pionie wewnątrz absolutnie umieszczonego nadrzędnego elementu DIV


146

Próbuję uzyskać niebieski pojemnik w środku różowego, ale wydaje vertical-align: middle;się, że w tym przypadku nie działa.

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

Wynik:

wprowadź opis obrazu tutaj

Oczekiwanie:

wprowadź opis obrazu tutaj

Proszę zasugerować, jak mogę to osiągnąć.

Jsfiddle


1
Czy jest jakiś powód, dla którego używasz position: absolutewszędzie?
Vucko,

że vertical-align: middle;współpracuje z display: inline-blocklub układ tabeli
ctf0


@Vucko tak - to warunek wstępny, ponieważ jest to tylko uproszczona wersja bardzo złożonego układu, ale absolutna pozycja w obu górnych elementach div jest kluczowa.
Vladimirs

@Vladimirs Mogę tylko pomyśleć o tym margin-top: calc((56px - 16px) / 2), gdzie 56px - parent height, 16px - element height/font-size- JSFiddle
Vucko

Odpowiedzi:


332

Przede wszystkim zauważ to vertical-align ma zastosowanie tylko do komórek tabeli i elementów wbudowanych.

Istnieje kilka sposobów uzyskania wyrównania w pionie, które mogą, ale nie muszą spełniać Twoich potrzeb. Jednak pokażę ci dwie metody z moich ulubionych:

1. Używanie transformitop

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Kluczową kwestią jest to, że wartość procentowa topjest określana względem heightbloku zawierającego; Natomiast wartość procentowa na transforms zależy od rozmiaru samego prostokąta (obwiedni).

Jeśli wystąpią problemy z renderowaniem czcionek (rozmyta czcionka), rozwiązaniem jest dodanie perspective(1px)do transformdeklaracji, aby wyglądała następująco:

transform: perspective(1px) translateY(-50%);

Warto zauważyć, że CSS transform jest obsługiwany w IE9 + .

2. Korzystanie inline-block (pseudo) elementów

W tej metodzie mamy dwa inline-blockelementy siostrzane , które są wyrównane pionowo w środku przez vertical-align: middledeklarację.

Jeden z nich ma heightod 100%swojego rodzica, a drugi to nasz pożądany pierwiastek, którego chcieliśmy wyrównać go w środku.

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Na koniec powinniśmy użyć jednej z dostępnych metod, aby usunąć lukę między elementami na poziomie liniowym .


Dzięki za te przydatne wskazówki. Pracowało dla mojego projektu. Dobra robota.
Sedat Kumcu

Jako pierwszy valignelement metody powinien byćdisplay: block
Oleg

transform: translateY(-50%);Nigdy wcześniej tego nie widziałem, ale działa bez zarzutu. Wygaszacz prawdziwego życia.
Benny Bottema

55

Użyj tego :

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

odnieś ten link: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/


Dlaczego nie jest to główne rozwiązanie? To takie proste i działa!
Mason

21
Pamiętaj, że heightwłaściwość musi być zdefiniowana (w px, em itp.), Aby to zadziałało.
Vaidas

Co się stanie, jeśli mam wiele elementów div w elemencie nadrzędnym? czy wszyscy nie byliby umieszczeni jeden na drugim?
psykid

to nie działa, jeśli jest jeszcze jedno dziecko na tym samym poziomie z „absolutnym centrum”
Pascut,

18

Użyj flex blox w niedopasowanym elemencie div, aby wyśrodkować jego zawartość.

Zobacz przykład https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}

11

Wyśrodkuj w pionie i poziomie:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}

3

Możesz użyć display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>


Dzięki, Twój przykład działa idealnie, jednak .bbrakuje go, position: absolute;co jest ważne, aby uzyskać inną właściwość wyświetlaną rzeczy, której nie uwzględniłem, aby kod był bardziej przejrzysty. Wiem, że nie ma sensu mający table-cell pozycjonowany bezwzględnie, ale być może jest inne podejście, które pozwoli utrzymać position: absolute;w obu .ai .bklas?
Vladimirs

jeśli a jest pozycją absolutną, a b (dziecko) nadając mu swój rozmiar, samo b jest w pozycji absolutnej względem reszty treści. chyba że a ma pozostać nieokreślone, to nie rozumiem celu absolutnego wewnętrznego absolutu?
G-Cyrillus

1

Oto prosty sposób użycia obiektu Top.

np .: Jeśli bezwzględny rozmiar elementu to 60 pikseli.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}

2
Używanie calcjest pomocne, chociaż powinno być top: calc(50% - 30px)rzeczywiście wyśrodkowane.
pycha mózgów

1

Dodatkowe proste rozwiązanie

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}

0

Sprawdź tę odpowiedź na podobny problem.

To zdecydowanie najłatwiejszy sposób, jaki znalazłem.

https://stackoverflow.com/a/26079837/4593442

UWAGA. Użyłem wyświetlacza: -webkit-flex; zamiast wyświetlacza: flex;do testowania w safari.

NOTATKA. Jestem tylko nowicjuszem, dzielę się pomocą od kogoś, kto jest wyraźnie doświadczony.


0

Możesz to zrobić, używając display:table;w div parent i display: table-cell; vertical-align: middle;child div

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>


3
możliwe, że twoja odpowiedź jest dobra, ale możesz ją bardzo poprawić, dodając opis tego, co robi twój kod ...
DaFois
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.