Układ DIV z 2 kolumnami: prawa kolumna o stałej szerokości, lewa płynna


158

Moje wymaganie jest proste: dwie kolumny, z których prawa ma stały rozmiar . Niestety nie mogłem znaleźć działającego rozwiązania ani na stackoverflow, ani w Google. Każde opisane tam rozwiązanie zawodzi, jeśli zaimplementuję w swoim własnym kontekście. Obecne rozwiązanie to:

div.container {
    position: fixed;
    float: left;
    top: 100px;
    width: 100%;
    clear: both;
}

#content {
    margin-right: 265px;
}

#right {
    float: right;
    width: 225px;
    margin-left: -225px;
}

#right, #content {
    height: 1%; /* fixed for IE, although doesn't seem to work */
    padding: 20px;
}
<div class="container">
    <div id="content">
        fooburg content
    </div>
    <div id="right">
        test right
    </div>
</div>

Otrzymuję następujący kod z powyższym kodem:

|----------------------- -------|
| fooburg content  |            |
|-------------------------------|
|                  | test right | 
|----------------------- -------|

Proszę doradź. Wielkie dzięki!

Odpowiedzi:


268

Usuń pływak z lewej kolumny.

W kodzie HTML prawa kolumna musi znajdować się przed lewą.

Jeśli prawa kolumna ma zmiennoprzecinkową (i szerokość), a lewa kolumna nie ma szerokości ani liczby zmiennoprzecinkowej, będzie elastyczna :)

Zastosuj także overflow: hiddeni pewną wysokość (może być auto) do zewnętrznego elementu div, tak aby otaczał oba wewnętrzne elementy div.

Na koniec w lewej kolumnie dodaj width: autoi overflow: hidden, dzięki temu lewa kolumna będzie niezależna od prawej (na przykład, jeśli zmienisz rozmiar okna przeglądarki, a prawa kolumna dotknie lewej, bez tych właściwości, lewa kolumna będzie działać wokół prawego, z tymi właściwościami pozostaje w swojej przestrzeni).

Przykładowy kod HTML:

<div class="container">
    <div class="right">
        right content fixed width
    </div>
    <div class="left">
        left content flexible width
    </div>
</div>

CSS:

.container {
   height: auto;
   overflow: hidden;
}

.right {
    width: 180px;
    float: right;
    background: #aafed6;
}

.left {
    float: none; /* not needed, just for clarification */
    background: #e8f6fe;
    /* the next props are meant to keep this block independent from the other floated one */
    width: auto;
    overflow: hidden;
}​​

Przykład tutaj: http://jsfiddle.net/jackJoe/fxWg7/


2
@Mir A clear: both wewnątrz żadnej z kolumn nie wpłynie na zewnętrzne elementy pływające. To nie jest „kruche”, chyba że umieścisz przezroczysty na tym samym poziomie kolumn między kolumnami, jeśli umieścisz go na końcu, nic się nie stanie.
jackJoe

6
Rozważyłbym użycie przykładu Adama. Nie sądzę, aby w znacznikach HTML umieścić prawą kolumnę przed lewą.
Danny_Joris

1
@Danny_Joris Zgadzam się. Ponadto, jeśli używasz zapytań o media, trudno jest teraz przesunąć prawą kolumnę pod lewą kolumnę
andrewtweber

2
Dla tych, którzy są ciekawi, jak to działa, wyjaśnienie można znaleźć tutaj: stackoverflow.com/questions/25475822/…
Hashem Qolami

1
Zastanawiam się, czy jest sposób na to, aby prawa kolumna PO lewej była tak, aby prawidłowo układała się (bez użycia flexboksa)
Dominic

71

Zobacz http://www.alistapart.com/articles/negativemargins/ , to jest dokładnie to, czego potrzebujesz ( przykład 4 tam).

<div id="container">
    <div id="content">
        <h1>content</h1>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  Phasellus varius eleifend tellus. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla facilisi. Sed wisi lectus, placerat nec, mollis quis, posuere eget, arcu.</p>
        <p class="last">Donec euismod. Praesent mauris mi, adipiscing non, mollis eget, adipiscing ac, erat. Integer nonummy mauris sit amet metus. In adipiscing, ligula ultrices dictum vehicula, eros turpis lacinia libero, sed aliquet urna diam sed tellus. Etiam semper sapien eget metus.</p>
    </div>
</div>

<div id="sidebar">
    <h1>sidebar</h1>
    <ul>
        <li>link one</li>
        <li>link two</li>
    </ul>
</div>

#container {
    width: 100%;
    background: #f1f2ea url(background.gif) repeat-y right;
    float: left;
    margin-right: -200px;
}
#content {
    background: #f1f2ea;
    margin-right: 200px;
}
#sidebar {
    width: 200px;
    float: right;

1
Fantastyczne, proste rozwiązanie i zachowuje prawidłową kolejność HTML!
user1794295

3
Jest to lepsze niż przyjęte rozwiązanie, ponieważ znaczniki są we właściwej kolejności.
Petri Lehtinen

Nie wiedziałem o tym. Jak o tym nie wiedziałem. Idealny! Próbowałem zrobić cały „płynne wejście, przycisk wyszukiwania o stałej szerokości” i oczywiście kolejność źródeł jest tutaj naprawdę ważna. To gwoździ. Dzięki!
Malabar Front

Podoba mi się to rozwiązanie, ponieważ w czasie mobilnego punktu przerwania prawe kolumny / pasek boczny pojawią się poniżej, a nie powyżej zawartości lewej kolumny.
dougtesting.net

nie udało mi się znaleźć odpowiedniej kolumny, aby przejść na górę tą metodą.
mulllhausen

29

Najlepiej unikać umieszczania prawej kolumny przed lewą, po prostu użyj ujemnego prawego marginesu.

Bądź „responsywny”, dodając ustawienie @media, tak aby prawa kolumna znajdowała się pod lewą na wąskich ekranach.

<div style="background: #f1f2ea;">
  <div id="container">
    <div id="content">
        <strong>Column 1 - content</strong>
    </div>
  </div>
  <div id="sidebar">
    <strong>Column 2 - sidebar</strong>
  </div>
<div style="clear:both"></div>

<style type="text/css">
#container {
    margin-right: -300px;
    float:left;
    width:100%;
}
#content {
    margin-right: 320px; /* 20px added for center margin */
}
#sidebar {
    width:300px;
    float:left
}
@media (max-width: 480px) {
    #container {
        margin-right:0px;
        margin-bottom:20px;
    }
    #content {
        margin-right:0px;
        width:100%;
    }
    #sidebar {
        clear:left;
    }
}
</style>

1
Świetne rozwiązanie. Zachowanie prawej strony poniżej lewej w HTML ma kluczowe znaczenie dla układów, takich jak blogi, w których lewa strona zawiera ważniejsze treści.
Jake

3
Doskonała odpowiedź! Oto działający przykład na Codepen: codepen.io/martinkrulltott/pen/yNxezM
Martin

11

Najprostsze i jak dotąd najbardziej elastyczne rozwiązanie w użyciutable display :

HTML, lewy element div jest pierwszy, prawy element div jest drugi ... czytamy i piszemy od lewej do prawej, więc nie ma sensu umieszczać elementów div od prawej do lewej

<div class="container">
    <div class="left">
        left content flexible width
    </div>
    <div class="right">
        right content fixed width
    </div>
</div>

CSS:

.container {
  display: table;
  width: 100%;
}

.left {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}​​

.right {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}

Przykłady przypadków:

// One div is 150px fixed width ; the other takes the rest of the width
.left {width: 150px} .right {width: 100%}

// One div is auto to its inner width ; the other takes the rest of the width
.left {width: 100%} .right {width: auto}

Świetnie, dobrze działało, dzięki. Czasami jest czas i miejsce na stoły, kiedy flexbox nie jest realną alternatywą. Zamiast umieszczać właściwą treść wcześniej w DOMU, który nie układa się prawidłowo…
Dominic

1
Podoba mi się, że jest to „czyste” rozwiązanie. Jednak jedynym problemem związanym z przełączaniem elementów div w tryb tabeli-komórki jest to, że równie dobrze możesz używać tabel i tabel.
Skończysz

To niesprawiedliwe, bo to rozwiązanie jest co najmniej poprawne semantycznie i przyjazne dla prostych technik RWD, podczas gdy użycie tablez tds z pewnością nie jest!
Ianp

Ta metoda z łatwością pozwala zapytaniu o media usunąć tabelę dla zwykłych elementów div, jeśli kolumny zawężą się. Ładnie i czysto. Podoba mi się.
AnthonyVO

6

Chciałbym zasugerować jeszcze nie wspomniane rozwiązanie: użyj CSS3 calc()do miksowania %i pxjednostek. calc()ma obecnie doskonałe wsparcie i pozwala na szybkie tworzenie dość skomplikowanych układów.

Oto link JSFiddle do poniższego kodu.

HTML:

<div class="sidebar">
  sidebar fixed width
</div>
<div class="content">
  content flexible width
</div>

CSS:

.sidebar {
    width: 180px;
    float: right;
    background: green;
}

.content {
    width: calc(100% - 180px);
    background: orange;
}

A oto kolejny JSFiddle demonstrujący tę koncepcję zastosowaną do bardziej złożonego układu. Użyłem tutaj SCSS, ponieważ jego zmienne pozwalają na elastyczny i samoopisujący kod, ale układ można łatwo odtworzyć w czystym CSS, jeśli posiadanie wartości „zakodowanych na stałe” nie stanowi problemu.


2

To jest ogólne uporządkowane rozwiązanie w formacie HTML, w którym:

  • Pierwsza kolumna w kolejności źródła jest płynna
  • Naprawiono drugą kolumnę w kolejności źródłowej
    • Ta kolumna może być pływająca w lewo lub w prawo za pomocą CSS

Naprawiono / druga kolumna po prawej stronie

#wrapper {
  margin-right: 200px;
}
#content {
  float: left;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: right;
  width: 200px;
  margin-right: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

Stała / druga kolumna po lewej stronie

#wrapper {
  margin-left: 200px;
}
#content {
  float: right;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: left;
  width: 200px;
  margin-left: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

Alternatywnym rozwiązaniem jest użycie display: table-cell ; co daje w wyniku kolumny o równej wysokości.


druga kolumna po prawej nie będzie działać. jeśli lewa kolumna jest pełna tekstu, prawa kolumna zostanie wyświetlona jako nowy wiersz.
TomSawyer

czy kiedykolwiek próbowałeś umieścić więcej treści i zmienić rozmiar. właśnie przetestowałem twój kod i nie zadziałał.
TomSawyer

@TomSawyer Nie jestem pewien, o czym mówisz. Oto ja próbuję umieścić więcej treści: jsfiddle.net/salman/mva6cnxL i jsfiddle.net/salman/mva6cnxL/1 . Działa bez zarzutu.
Salman A

Właśnie tego szukałem. Dzięki

0

Hej, co możesz zrobić, to zastosować stałą szerokość do obu kontenerów, a następnie użyć innej klasy div, jeśli jest wyczyszczona: obie, na przykład

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

umieść wyraźny div pod lewym i prawym pojemnikiem.


-3

Uprościłem to: zredagowałem odpowiedź jackjoe. Myślę, że wysokość auto itp. Nie jest wymagana.

CSS:

#container {
position: relative;
margin:0 auto;
width: 1000px;
background: #C63;
padding: 10px;
}

#leftCol {
background: #e8f6fe;
width: auto;
}

#rightCol {
float:right;
width:30%;
background: #aafed6;
}

.box {
position:relative;
clear:both;
background:#F39;
 }
</style>

HTML:

<div id="container">

  <div id="rightCol"> 
   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
 </div>

 <div id="leftCol">

   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.

</div>

</div>

<div class="box">
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
</div>

Oryginalne pytanie dotyczy prawej kolumny o stałym rozmiarze.
Dr. Aaron Dishno
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.