Div obok diva.. Niby proste, ale..

0

Witam.

Kolejny raz spotykam się z problemem źle działającego diva obok diva. Używam opery, zastosowałem zwykłe float: left. Najpierw tylko w pierwszym obiekcie, a drugi automatycznie ustawił się obok. W taki sposób skończyłem stronę, myślałem że wszystko jest cacy i zaktualizowałem mapę strony.

Dzisiaj znajomy mi napisał, że jakiś tekst wchodzi na obrazek. Z ciekawości porobiłem screeny z różnych przeglądarek i okazało się, że divy nie są obok siebie, a jedno pod drugim.

http://api.browsershots.org/png/original/d0/d0e6697f385e6afda53d0737c60abd6c.png - Screen

Ok, zmieniłem więc float na left też przy drugim divie. Przez to oba divy straciły swoją "wysokość" i Chrome przestało rozumieć ile każdy z nich ma wysokości, przez co divy spod spodu wyświetlał nad nimi.

Nie ma sensu żebym kopiował długi kod strony, podam po prostu adresy:

http://pozytyff.art.pl/blog/ - Strona główna
http://pozytyff.art.pl/blog/style.css - Style CSS

http://api.browsershots.org/png/original/70/706d6c9e053974efa82d3f14715094f4.png - Tak powinna wyglądać strona.

A i jeszcze coś:
Obok siebie mają być: post_date_wrap i post_enter_wrap
Oraz: posty i menusy
Wszystko to divy.

0

Na potrzeby tego posta załóżmy, że masz trzy elementy:

<div id="container">
  <div id="column1">
    ...
  </div><!-- /column1 -->
  <div id="column2">
    ...
  </div><!-- /column2 -->
</div><!-- /container -->

Elementy #column1 i #column2 mają być obok siebie, a otaczać ma je #container.

Poprawnym rozwiązaniem jest nadanie float: left; (lub right) zarówno #column1, jak i #column2. Rzadko się zdarza żeby w przypadku kolumn nadawać float tylko jednej z nich.

Rodzi to problem, na który -- jak rozumiem -- się natknąłeś. Elementy pływające (z ustawionym float) normalnie nie wpływają na wysokość elementu zawierającego. Jeśli element zawierający (u nas: #container) ma bezpośrednio w sobie jedynie elementy pływające, to wysokość elementu zawierającego wynosi zero. #container zaczyna się tam, gdzie normalnie, czyli na górze kolumn, ale kończy w tym samym miejscu, bo z punktu widzenia standardowego przepływu nie zawiera żadnej treści, która rozciągnęłaby go w pionie.

Można to zmienić na kilka sposobów.

Można dodać do #containera element czyszczący (ang. clearing). Wiemy, że jeśli jakiemuś elementowi dasz clear: both,to jest zagwarantowane, że znajdzie się on poniżej poprzedzających go w danym bloku elementów pływających. Nasz element czyszczący nie musi i nie powinien sam mieć ustawionego float. Kod HTML wyglądałby tak:

<div id="container">
  <div id="column1">
    ...
  </div><!-- /column1 -->
  <div id="column2">
    ...
  </div><!-- /column2 -->
  <div class="clearfix">
  </div><!-- /clearfix -->
</div><!-- /container -->

A kod CSS tak:

#column1,
#column2 {
  float: left;
  width: 300px; /* przykładowa wartość*/
}

.clearfix {
  clear: both;
}

Jak teraz wyświetlany będzie #container? Jego góra zaczyna się na górze naszych kolumn, ale co z dołem? Element .clearfix to normalny element, nie element pływający. #container musi więc rozciągnąć się w pionie tak, by objąć naszego .clearfixa. Ponieważ .clearfix ma clear: both;, jego góra będzie poniżej elementów pływających, czyli kolumn. .clearfix będzie pod kolumnami, a #container rozciągnie się tak, by go objąć -- więc siłą rzeczy #container obejmie też w pionie nasze kolumny.

To jest najprostszy do wytłumaczenia sposób, ale nie najbardziej elegancki. Dodawanie do kodu elementu .clearfix, który z punktu widzenia struktury dokumentu jest zbędny i bezsensowny, a potrzeba go jedynie do prezentacji -- to nie jest najładniejsze rozwiązanie.

Praktycznie taki sam efekt można osiągnąć, dając #containerowi overflow: hidden -- bez żadnego elementu .clearfix.

Są jeszcze inne metody czyszczenia elementów pływających (ang. clearing floats). Pogoogluj.

W Twoim przypadku możesz dodać po prostu overflow: hidden do elementu #wrapper i ewentualnie innych elementów zawierających jedynie elementy pływające.

0

Trochę się spóźniłem :). Wielkie wielkie dzięki za tą odpowiedź, wspomniałeś w nim o "overflow: hidden;" przeglądałem trochę blogi w tym czasie i zauważyłem, że właśnie w ten sposób rozwiązuje się taki problem. Zastosowałem to i działa, chociaż oczywiście musiałem lekko przebudować końcówkę strony, bo okazało się, że zrobiłem ją nie tak jak trzeba :).

Jakby ktoś chciał dokładniej, "overflow: hidden;" dodałem do diva "#calosc", który obejmuje "#wrapper" obejmujący "#posty" i "#menusy". Za to "#menusy" dostało "float: right;".

Wszystko śmiga.

0

Musisz jeszcze wiedzieć, że elementy pływające nie wpływają co prawda na elementy blokowe będące w zwykłym przepływie strony, ale wpływają na inne elementy pływające. Czyli jeśli #container by miał float, to też by objął oba #columny. Tyle że jeśli pójdziesz tą drogą i nadasz elementowi zawierającemu float, to pewnie element, który zawiera ten element też będzie potrzebował czyszczenia. I mu też dasz float, albo overflow: hidden. Jeśli wybierzesz float, to w końcu co drugi element na stronie będzie miał float ;). Czasami jednak to się przydaje. Gdy w pasku bocznym masz elementy pływające (bo np. sam pasek boczny dzieli się na kolumny), to pasek boczny w naturalny sposób ma float i nie musisz się o nic w jego przypadku martwić.

0

Sorry, że tu zapytam się, ale uznałem, że lepiej nie dublować wątków. Kiedyś próbowałem robić divy z inline-block, ale też niespecjalnie to wychodziło. Czy są jakieś inne alternatywy?

0

@tpsa:
???

No przecież tu masz jedną opisaną. Użyj float: left -- to standardowy sposób na zrobienie wielu kolumn.

1 użytkowników online, w tym zalogowanych: 0, gości: 1