Środkowanie pływających elementów DIV w innym elemencie DIV

142

Przeszukałem inne pytania i chociaż ten problem wydaje się podobny do kilku innych, nic, co do tej pory widziałem, nie rozwiązuje problemu, który mam.

Mam element div, który zawiera kilka innych elementów div, z których każdy jest przesunięty w lewo. Każdy z tych elementów div zawiera zdjęcie i podpis. Chcę tylko, aby grupa zdjęć była wyśrodkowana w zawierającym div.

Jak widać z poniższego kodu, próbowałem używać obu overflow:hiddeni margin:x autow nadrzędnych divach, a także dodałem clear:both(jak zasugerowałem w innym temacie) po zdjęciach. Wydaje się, że nic nie robi różnicy.

Dziękuję Ci. Doceniam wszelkie sugestie.

<div style="position: relative; margin: 0 auto; overflow: hidden; text-align: center;">
    <h4>Section Header</h4>

    <div style="margin: 2em auto;">

        <div style="float: left; margin: auto 1.5em;">
            <img src="photo1.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo2.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo3.jpg" /><br />
             Photo Caption
        </div>

        <div style="clear: both; height: 0; overflow: hidden;"> </div>

    </div>

</div>
Darren
źródło
@TylerH Jak doszło? Po prostu zobacz datę, kiedy o to zapytano. Wygląda na to, że pytanie w Twoim linku to prawdziwy duplikat.
The Pragmatick
@ThePragmatick Ponieważ ta osoba ma dwa razy więcej wyświetleń, więcej odpowiedzi, większą (i nowszą) aktywność, a jej sformułowanie służy jako lepsze pytanie kanoniczne niż to.
TylerH

Odpowiedzi:

266

Najpierw usuń floatatrybut z wewnętrznego divs. Następnie załóż text-align: centergłówny wierzch div. A dla wewnętrznych divużyj display: inline-block. Mądrze byłoby również nadać im wyraźne szerokości.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>
Sampson
źródło
6
@Darren: czy przestałeś się unosić, kiedy próbowałeś? Nie będziesz w stanie osiągnąć tego, co chcesz, dopóki pływasz / chyba że / ustawisz stałą szerokość w kontenerze pływaków.
Ken Browning
1
Och ... mylę się. Usunięcie pływaka wygląda tak, jakby osiągnęło dokładnie to, czego chcę. Nie jestem pewien, czy rozumiem dlaczego, ale ... Dziękuję bardzo.
Darren
9
@Darren, zauważ, że w moim przykładzie kodu nie uwzględniłem pływającego;) Następnym razem przeczytaj uważniej, zaoszczędzi ci to trochę frustracji :) Cieszę się, że to zrozumiałeś. Kontynuujcie dobrą robotę i witajcie w SO.
Sampson
2
Takie podejście zaczyna się nie powieść, gdy niektóre podpisy obrazów są wystarczająco długie, aby zawijać wiersz. Jakieś inne sugestie?
greg.kindel
3
Nieważne, okazało się, że problem z napisami o różnej liczbie wierszy można rozwiązać za pomocą polecenia „vertical-align: top”. =)
greg.kindel
33

Dzięki Flexbox możesz łatwo wyśrodkować dzieci pływające w poziomie (i w pionie) wewnątrz elementu div.

Więc jeśli masz takie proste znaczniki:

<div class="wpr">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>

z CSS:

.wpr
{
    width: 400px;
    height: 100px;
    background: pink;
    padding: 10px 30px;
}

.wpr span
{
    width: 50px;
    height: 50px;
    background: green;
    float: left; /* **children floated left** */
    margin: 0 5px;
}

(To jest (oczekiwany - i niepożądany) WYNIK )

Teraz dodaj następujące reguły do ​​opakowania:

display: flex;
justify-content: center; /* align horizontal */

a pływające dzieci są wyrównane do środka ( DEMO )

Dla zabawy, aby uzyskać wyrównanie w pionie, po prostu dodaj:

align-items: center; /* align vertical */

PRÓBNY

Danield
źródło
nadal muszę sprawdzać zgodność przeglądarki, ale to wydaje się niesamowite!
low_rents
Możesz także użyć display: inline zamiast flex do centrowania elementów div. Flex ma problemy z Safari i Operą.
TY
inline nie działa dla mnie. Problemem tego rozwiązania jest to, że pola nie przechodzą do drugiej linii, jeśli przekraczają szerokość elementu div. Więc właściwie zamieniłeś je w stół ...
Pavel Jiri Strnad
10

Powyższe osiągnąłem używając względnego pozycjonowania i pływania w prawo.

Kod HTML:

<div class="clearfix">                          
    <div class="outer-div">
        <div class="inner-div">
            <div class="floating-div">Float 1</div>
            <div class="floating-div">Float 2</div>
            <div class="floating-div">Float 3</div>
        </div>
    </div>
</div>

CSS:

.outer-div { position: relative; float: right; right: 50%; }
.inner-div { position: relative; float: right; right: -50%; }
.floating-div { float: left; border: 1px solid red; margin: 0 1.5em; }

.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

JSFiddle: http://jsfiddle.net/MJ9yp/

To zadziała w IE8 i nowszych, ale nie wcześniej (niespodzianka, niespodzianka!)

Nie pamiętam niestety źródła tej metody, więc nie mogę podać nazwiska pierwotnego autora. Jeśli ktoś wie, proszę zamieścić link!

Kendolein
źródło
+1 To działa pięknie. Przyjęta odpowiedź nie zadziałała dla mnie. Stworzyło to problemy z wyrównaniem w pionie ...
TimH - Codidact
@TimH Wiem, że spóźniłem się na imprezę, ale problem z wyrównaniem w pionie można naprawić, dodając do kontenera „vertical-align: top”
Alfie
Przepraszam, miałem na myśli wewnętrzny div, a nie kontener div *
Alfie
Działa prawie idealnie. Elementy przechodzą do następnej linii, jeśli przepełnienie, ale kiedy to zrobią, nie są wyśrodkowane.
Pavel Jiri Strnad
5

Poniższe rozwiązanie nie używa bloków wbudowanych. Jednak wymaga dwóch pomocniczych elementów div:

  1. Zawartość jest pływająca
  2. Pomocnik wewnętrzny jest pływający (rozciąga się tak bardzo, jak zawartość)
  3. Pomocnik wewnętrzny jest popychany w prawo o 50% (jego lewa strona jest wyrównana ze środkiem pomocnika zewnętrznego)
  4. Treść jest ciągnięta w lewo o 50% (jej środek jest wyrównany z lewą stroną wewnętrznego pomocnika)
  5. Zewnętrzny pomocnik jest ustawiony tak, aby ukryć przepełnienie

.ca-outer {
  overflow: hidden;
  background: #FFC;
}
.ca-inner {
  float: left;
  position: relative;
  left: 50%;
  background: #FDD;
}
.content {
  float: left;
  position: relative;
  left: -50%;
  background: #080;
}
/* examples */
div.content > div {
  float: left;
  margin: 10px;
  width: 100px;
  height: 100px;
  background: #FFF;
}
ul.content {
  padding: 0;
  list-style-type: none;
}
ul.content > li {
  margin: 10px;
  background: #FFF;
}
<div class="ca-outer">
  <div class="ca-inner">
    <div class="content">
      <div>Box 1</div>
      <div>Box 2</div>
      <div>Box 3</div>
    </div>
  </div>
</div>
<hr>
<div class="ca-outer">
  <div class="ca-inner">
    <ul class="content">
      <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
      <li>Nullam efficitur nulla in libero consectetur dictum ac a sem.</li>
      <li>Suspendisse iaculis risus ut dapibus cursus.</li>
    </ul>
  </div>
</div>

Salman A
źródło
4

display: inline-block;nie będzie działać w żadnej z przeglądarek IE. Oto, czego użyłem.

// change the width of #boxContainer to 
// 1-2 pixels higher than total width of the boxes inside:

#boxContainer {         
    width: 800px; 
    height: auto;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}

#Box{
    width: 240px; 
    height: 90px;
    background-color: #FFF;
    float: left;
    margin-left: 10px;
    margin-right: 10px;
}
Abdulla Kaleem
źródło
3

Rozwiązanie:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Knowledge is Power</title>
        <script src="js/jquery.js"></script>
        <script type="text/javascript">
        </script>
        <style type="text/css">
            #outer {
                text-align:center;
                width:100%;
                height:200px;
                background:red;
            }
            #inner {
                display:inline-block;
                height:200px;
                background:yellow;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner">Hello, I am Touhid Rahman. The man in Light</div>
        </div>
    </body>
</html>
Touhid Rahman
źródło
To rozwiązanie jest nie na temat. Wewnętrzna powinna być pływająca: pozostawiona, aby spełnić wymagania PO.
s15199d
1

W moim przypadku nie mogłem uzyskać odpowiedzi od @Sampsona, która pracowała dla mnie, w najlepszym przypadku otrzymałem jedną kolumnę pośrodku strony. Jednak w trakcie tego procesu dowiedziałem się, jak faktycznie działa float i stworzyłem to rozwiązanie. W istocie poprawka jest bardzo prosta, ale trudna do znalezienia, o czym świadczy ten wątek, który miał ponad 146 tysięcy wyświetleń w czasie tego postu bez wzmianki.

Wszystko, co jest potrzebne, to zsumować szerokość przestrzeni ekranu, jaką zajmie żądany układ, a następnie nadać rodzicowi taką samą szerokość i zastosować margines: auto. Otóż ​​to!

Elementy układu będą określać szerokość i wysokość „zewnętrznego” elementu div. Weź każdy „myFloat” lub szerokość lub wysokość elementu + jego krawędzie + jego marginesy i wypełnienia i dodaj je wszystkie razem. Następnie dodaj pozostałe elementy razem w ten sam sposób. To da ci szerokość rodzica. Wszystkie mogą mieć nieco inne rozmiary i możesz to zrobić z mniejszą lub większą liczbą elementów.

Np. (Każdy element ma 2 boki, więc obramowanie, margines i dopełnienie są mnożone x2)

Tak więc element o szerokości 10 pikseli, obramowaniu 2 piks., Marginesie 6 piks. I dopełnieniu 3 piks. Wyglądałby tak: 10 + 4 + 12 + 6 = 32

Następnie zsumuj wszystkie zsumowane szerokości elementu.

Element 1 = 32
Element 2 = 24
Element 3 = 32
Element 4 = 24

W tym przykładzie szerokość „zewnętrznego” elementu div będzie wynosić 112.

.outer {
  /* floats + margins + borders = 270 */
  max-width: 270px;
  margin: auto;
  height: 80px;
  border: 1px;
  border-style: solid;
}

.myFloat {
    /* 3 floats x 50px = 150px */
    width: 50px;
    /* 6 margins x 10px = 60 */
    margin: 10px;
    /* 6 borders x 10px = 60 */
    border: 10px solid #6B6B6B;
    float: left;
    text-align: center;
    height: 40px;
}
<div class="outer">
  <div class="myFloat">Float 1</div>
  <div class="myFloat">Float 2</div>
  <div class="myFloat">Float 3</div>
</div>

dimmech
źródło
To jest odpowiedź, której szukałem, dzięki. Jak obliczyć potrzebny piksel? Nie jest dla mnie jasne.
SilverSurfer,