Rentangkan div untuk mengisi lebar yang tersisa

552

Saya ingin tata letak div dua kolom, di mana masing-masing dapat memiliki lebar variabel misalnya

div {
  float: left;
}

.second {
  background: #ccc;
}
<div>Tree</div>
<div class="second">View</div>

Saya ingin 'view' div untuk memperluas ke seluruh lebar yang tersedia setelah 'tree' div telah mengisi ruang yang dibutuhkan.

Saat ini, 'view' div saya diubah ukurannya menjadi konten di dalamnya. Ini juga akan bagus jika kedua divs mengambil seluruh ketinggian.


Bukan duplikat penafian:

Anurag Uniyal
sumber
1
Entah saya tidak mengerti pertanyaannya atau saya tidak mengerti bagaimana Anda memilih jawaban yang diterima, karena ada lebar dan tinggi tetap dengan ketidaknyamananoverflow hidden
user10089632

Jawaban:

1012

Solusi untuk ini sebenarnya sangat mudah, tetapi sama sekali tidak jelas. Anda harus memicu sesuatu yang disebut "blok konteks format" (BFC), yang berinteraksi dengan pelampung dengan cara tertentu.

Ambil div kedua itu, hapus float, dan berikan itu overflow:hidden. Nilai luapan apa pun selain yang terlihat membuat blok yang disetel menjadi BFC. BFC tidak mengijinkan pelampung keturunan untuk melarikan diri dari mereka, mereka juga tidak membiarkan saudara kandung / leluhur mengapung ke dalamnya. Efek bersih di sini adalah bahwa div yang terapung akan melakukan tugasnya, kemudian div kedua akan menjadi blok biasa, mengambil semua lebar yang tersedia kecuali yang ditempati oleh float .

Ini harus bekerja di semua browser saat ini, meskipun Anda mungkin harus memicu hasLayout di IE6 dan 7. Saya tidak bisa mengingat.

Demo:

Xanthir
sumber
28
Jawaban yang sangat bagus! Tetapi Anda salah ketika Anda mengatakan "nilai kelebihan apa pun selain otomatis" akan menjadikannya BFC. Yang Anda maksudkan adalah nilai luapan apa pun selain dari standar (terlihat) akan menjadikannya BFC. Bahkan, overflow otomatis berfungsi dengan baik juga - itulah yang saya sarankan (kalau-kalau Anda memiliki elemen yang relatif diposisikan yang mungkin mengintip dari div itu).
BT
52
Artikel ini memiliki penjelasan yang bagus: colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor
1
Bagaimana jika kontennya cukup besar untuk membanjiri div?
giannis christofakis
11
Penting untuk dicatat, bahwa urutan anak-anak penting. Elemen mengambang dengan lebar tetap harus di atas yang lain. Butuh waktu lama bagi saya untuk mencari tahu, mengapa itu tidak berhasil bagi saya dengan pesanan yang diubah.
Riplexus
2
Saya menulis jawaban yang menjelaskan mengapa semua hal yang meluap memicu BFC, berdasarkan tanggapan yang diberikan oleh David dan Boris, yang dapat ditemukan di sini: stackoverflow.com/questions/9943503/... Apakah interpretasi saya benar?
BoltClock
106

Saya baru saja menemukan keajaiban kotak fleksibel (layar: fleksibel). Coba ini:

<style>
  #box {
    display: flex;
  }
  #b {
    flex-grow: 100;
    border: 1px solid green;
  }
</style>
<div id='box'>
 <div id='a'>Tree</div>
 <div id='b'>View</div>
</div>

Kotak fleksibel memberi saya kontrol yang saya harapkan dimiliki css selama 15 tahun. Akhirnya di sini! Info lebih lanjut: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

BT
sumber
Saya tidak tahu apa yang Anda temukan, tetapi kode Anda tidak berfungsi di Chrome terbaru jsfiddle.net/fjb548kw/3
Yevgeniy Afanasyev
@YevgeniyAfanasyev saya menghapus "float: left;" untuk memperbaiki masalah ini. Terima kasih atas catatannya!
BT
Terima kasih. Bisa tolong jelaskan mengapa Anda memiliki flex-grow: 100;bukan flex-grow: 1;?
Yevgeniy Afanasyev
2
@YevgeniyAfanasyev Tidak ada alasan khusus kecuali itu yang saya suka lakukan. Ini memungkinkan saya untuk berpikir dalam persen jadi jika saya bisa melakukan sesuatu seperti mengatur #a menjadi flex-grow:10dan kemudian saya akan mengatur #b menjadi flex-grow: 90jadi #a akan menjadi 10% dari lebar garis dan #b akan menjadi 90% dari lebar garis. Jika tidak ada elemen lain yang memiliki gaya lebar flex, maka secara teknis tidak masalah apa yang Anda masukkan.
BT
ini bekerja paling baik untuk saya, mencoba menempatkan input dan tombol berdampingan seolah-olah mereka adalah satu.
Souleste
29

Solusi Flexbox

Untuk inilah flex-growproperti itu.

html, body {
  height: 100%;
}
body {
  display: flex;
}
.second {
  flex-grow: 1;
}
<div style="background: #bef;">Tree</div>
<div class="second" style="background: #ff9;">View</div>

Catatan: Tambahkan awalan vendor fleksibel jika diperlukan oleh browser yang didukung .

Reggie Pinkham
sumber
27

Ini akan menjadi contoh yang baik dari sesuatu yang sepele untuk dilakukan dengan tabel dan sulit (jika tidak mustahil, setidaknya dalam arti lintas-browser) untuk dilakukan dengan CSS.

Jika kedua kolom memiliki lebar tetap, ini akan mudah.

Jika salah satu kolom adalah lebar tetap, ini akan sedikit lebih sulit tetapi sepenuhnya bisa dilakukan.

Dengan lebar kedua kolom variabel, IMHO Anda hanya perlu menggunakan tabel dua kolom.

cletus
sumber
11
Tabel tidak akan terlalu bagus dalam desain responsif di mana Anda ingin kolom kanan meluncur di bawah kiri pada perangkat kecil.
S ..
1
Ada beberapa trik desain responsif untuk bekerja dengan tabel: css-tricks.com/responsive-data-tables
Rikki
Sekarang saya cenderung sering mendesain dua tata letak yang terpisah sepenuhnya dan berubah pada ponsel menggunakan kueri media dan display:none;membuat sebanyak mungkin responsif 100% pada skala geser kadang lebih baik mengubah desain Anda sepenuhnya untuk ponsel yang memanfaatkan nuansa layar sentuh. dan gaya tombol.
Bysander
22

Lihat solusi ini

.container {
  width: 100%;
  height: 200px;
  background-color: green;
}
.sidebar {
  float: left;
  width: 200px;
  height: 200px;
  background-color: yellow;
}
.content {
  background-color: red;
  height: 200px;
  width: auto;
  margin-left: 200px;
}
.item {
  width: 25%;
  background-color: blue;
  float: left;
  color: white;
}
.clearfix {
  clear: both;
}
<div class="container">
  <div class="clearfix"></div>
  <div class="sidebar">width: 200px</div>

  <div class="content">
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
  </div>
</div>

angel.dimitrov
sumber
2
Ini umumnya merupakan solusi superior karena menyembunyikan limpahan tidak selalu diinginkan.
Joseph Lennox
3
Per OP: "Saya ingin tata letak div dua kolom, di mana masing-masing dapat memiliki lebar variabel". Dalam jawaban Anda, Anda harus tahu lebar kolom pertama, jadi bukan variabel. Anda mungkin juga menetapkan lebar tetap pada kedua kolom dan hanya mengapungkannya.
Jacob Alvarez
17

Gunakan calc:

.leftSide {
  float: left;
  width: 50px;
  background-color: green;
}
.rightSide {
  float: left;
  width: calc(100% - 50px);
  background-color: red;
}
<div style="width:200px">
  <div class="leftSide">a</div>
  <div class="rightSide">b</div>
</div>

Masalahnya adalah bahwa semua lebar harus didefinisikan secara eksplisit, baik sebagai nilai (px dan em berfungsi dengan baik), atau sebagai persen dari sesuatu yang secara eksplisit didefinisikan sendiri.

joel Moses
sumber
15

Di sini, ini mungkin membantu ...

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="clear" />
  </div>
</body>

</html>

a6hi5h3k
sumber
Memberi +1 karena contoh Anda tampaknya berfungsi, tetapi dalam skenario saya yang sebenarnya bagaimana konten dari 'view' merayap ke div 'tree', karena div pohon tidak 100%, mungkin beberapa javascript memaksanya menjadi kecil dan setelah ketinggian pohon Saya melihat konten tampilan
Anurag Uniyal
Dalam hal ini, jika Anda mengetahui lebar maks kolom kiri, Anda dapat memberikannya gaya lebar maks (tidak berfungsi di IE) atau memikirkan margin-kiri (waspadai bug margin ganda pada IE) atau padding-kiri.
a6hi5h3k
Ini luar biasa! Saya menggunakannya sebaris sebagai solusi sekali <div class="clear" style="clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px;"></div>
pakai
5

Saya tidak mengerti mengapa orang mau bekerja keras untuk menemukan solusi CSS murni untuk tata letak kolom sederhana yang SANGAT MUDAH menggunakan yang lama TABLE tag .

Semua Peramban masih memiliki logika tata letak tabel ... Panggil saya mungkin dinosaurus, tapi saya katakan biarkan itu membantu Anda.

<table WIDTH=100% border=0 cellspacing=0 cellpadding=2>
  <tr>
    <td WIDTH="1" NOWRAP bgcolor="#E0E0E0">Tree</td>
    <td bgcolor="#F0F0F0">View</td>
  </tr>
</table>

Jauh lebih tidak beresiko dalam hal kompatibilitas lintas-browser juga.

PatM
sumber
2
ya, tetapi jika semuanya dilakukan oleh css mengapa tidak ini, setidaknya rasa ingin tahu jika itu mungkin?
Anurag Uniyal
2
Itu karena jika Anda ingin media-queriesmeletakkan kedua kolom satu di atas yang lain di perangkat kecil, tidak mungkin dengan tabletag yang lama . Agar ini berfungsi, Anda perlu menerapkan CSSgaya tabel. Jadi, untuk saat ini lebih baik menyelesaikannya dengan CSSjika Anda menginginkan tata letak responsif untuk ukuran layar apa pun.
ElChiniNet
5

Jika lebar kolom lainnya sudah diperbaiki, bagaimana menggunakan calcfungsi CSS yang berfungsi untuk semua browser umum :

width: calc(100% - 20px) /* 20px being the first column's width */

Dengan cara ini lebar baris kedua akan dihitung (yaitu sisa lebar) dan diterapkan secara responsif.

anit
sumber
Ini adalah jawaban terbaik sejauh menggunakan selain flexbox, seperti misalnya css-grid,. Juga bekerja dengan position: fixedyang membuatnya menjadi pilihan sempurna! Terima kasih!
Bartekus
3

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="right">View</div>
    <div style="width: <=100% getTreeWidth()100 %>">Tree</div>
    <div class="clear" />
  </div>
  <div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
  </div>

</body>

</html>

A.ramod Kumar
sumber
Saya ingin sesuatu seperti bilah status dengan item tetap di sebelah kiri, item tetap di sebelah kanan dan satu baris pesan yang menggunakan semua sisa ruang. Saya mulai dengan jawaban ini dan menambahkan div pesan saya SETELAH mengapung dengan: height: 20px; white-space: nowrap; overflow: disembunyikan; text-overflow: clip
englebart
3

Anda dapat mencoba Layout Kotak CSS .

dl {
  display: grid;
  grid-template-columns: max-content auto;
}

dt {
  grid-column: 1;
}

dd {
  grid-column: 2;
  margin: 0;
  background-color: #ccc;
}
<dl>
  <dt>lorem ipsum</dt>
  <dd>dolor sit amet</dd>
  <dt>carpe</dt>
  <dd>diem</dd>
</dl>

kanon
sumber
2

flex-grow - Ini mendefinisikan kemampuan untuk item flex tumbuh jika perlu. Ia menerima nilai tanpa unit yang berfungsi sebagai proporsi. Ini menentukan jumlah ruang yang tersedia di dalam wadah fleksibel yang harus diambil barang.

Jika semua item memiliki flex-grow set ke 1, sisa ruang dalam wadah akan didistribusikan secara merata ke semua anak. Jika salah satu dari anak-anak memiliki nilai 2, ruang yang tersisa akan memakan waktu dua kali lebih banyak daripada yang lain (atau itu akan mencoba, setidaknya). Lihat lebih lanjut di sini

.parent {
  display: flex;
}

.child {
  flex-grow: 1; // It accepts a unitless value that serves as a proportion
}

.left {
  background: red;
}

.right {
  background: green;
}
<div class="parent"> 
  <div class="child left">
      Left 50%
  </div>
   <div class="child right">
      Right 50%
  </div>
</div>

Stanislav Ostapenko
sumber
1

Implementasi yang sedikit berbeda,

Dua panel div (konten + ekstra), berdampingan, content panelmembesar jika extra paneltidak ada.

jsfiddle: http://jsfiddle.net/qLTMf/1722/

Rao
sumber
1

Pat - Anda benar. Itulah sebabnya solusi ini akan memuaskan "dinosaurus" dan orang-orang sezaman. :)

.btnCont {
  display: table-layout;
  width: 500px;
}

.txtCont {
  display: table-cell;
  width: 70%;
  max-width: 80%;
  min-width: 20%;
}

.subCont {
  display: table-cell;
  width: 30%;
  max-width: 80%;
  min-width: 20%;
}
<div class="btnCont">
  <div class="txtCont">
    Long text that will auto adjust as it grows. The best part is that the width of the container would not go beyond 500px!
  </div>
  <div class="subCont">
    This column as well as the entire container works like a table. Isn't Amazing!!!
  </div>
</div>

johnmanoahs
sumber
2
Tidak ada referensi html untuk kelas css .ip dan tidak berfungsi di IE7
Keith K
1

Anda dapat menggunakan pustaka CSS W3 yang berisi kelas yang dipanggil restyang melakukan hal itu:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<div class="w3-row">
  <div class="w3-col " style="width:150px">
    <p>150px</p>
  </div>
  <div class="w3-rest w3-green">
    <p>w3-rest</p>
  </div>
</div>

Jangan lupa menautkan pustaka CSS di halaman header:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

Inilah demo resmi: W3 School Tryit Editor

manar
sumber
Sepertinya itu hanya menambahkan "overflow: hidden", yang membuatnya menjadi versi yang lebih buruk dari jawaban yang sudah diberikan
vpzomtrrfrt
0

Saya tidak yakin apakah ini jawaban yang Anda harapkan tetapi, mengapa Anda tidak mengatur lebar Tree menjadi 'otomatis' dan lebar 'Tampilan' menjadi 100%?


sumber
3
Karena itu akan menempatkan float kedua di bawah yang pertama karena terlalu lebar.
cletus
0

Lihat kerangka tata letak CSS yang tersedia. Saya akan merekomendasikan Simpl atau, kerangka kerja cetak biru yang sedikit lebih kompleks.

Jika Anda menggunakan Simpl (yang melibatkan mengimpor hanya satu file simpl.css ), Anda dapat melakukan ini:

<div class="Colum­nOne­Half">Tree</div>
<div class="Colum­nOne­Half">View</div>

, untuk tata letak 50-50, atau:

<div class="Colum­nOne­Quarter">Tree</div>
<div class="Colum­nThreeQuarters">View</div>

, untuk yang 25-75.

Sesederhana itu.


sumber
akankah kedua kolom menjadi lebar variabel?
Anurag Uniyal
0

Terima kasih atas steker Simpl.css!

ingat untuk membungkus semua kolom Anda ColumnWrapperseperti itu.

<div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
</div>

Saya akan merilis versi 1.0 dari Simpl.css jadi bantu sebarkan!

Shaggy
sumber
0

Saya menulis fungsi javascript yang saya panggil dari jQuery $ (document) .ready (). Ini akan mem-parsing semua anak dari div induk dan hanya memperbarui sebagian besar anak yang tepat.

html

...
<div class="stretch">
<div style="padding-left: 5px; padding-right: 5px; display: inline-block;">Some text
</div>
<div class="underline" style="display: inline-block;">Some other text
</div>
</div>
....

javascript

$(document).ready(function(){
    stretchDivs();
});

function stretchDivs() {
    // loop thru each <div> that has class='stretch'
    $("div.stretch").each(function(){
        // get the inner width of this <div> that has class='stretch'
        var totalW = parseInt($(this).css("width"));
        // loop thru each child node
        $(this).children().each(function(){
            // subtract the margins, borders and padding
            totalW -= (parseInt($(this).css("margin-left")) 
                     + parseInt($(this).css("border-left-width")) 
                     + parseInt($(this).css("padding-left"))
                     + parseInt($(this).css("margin-right")) 
                     + parseInt($(this).css("border-right-width")) 
                     + parseInt($(this).css("padding-right")));
            // if this is the last child, we can set its width
            if ($(this).is(":last-child")) {
                $(this).css("width","" + (totalW - 1 /* fudge factor */) + "px");
            } else {
                // this is not the last child, so subtract its width too
                totalW -= parseInt($(this).css("width"));
            }
        });
    });
}
bcr666
sumber
0

Ini cukup mudah menggunakan flexbox. Lihat cuplikan di bawah. Saya telah menambahkan wadah pembungkus untuk mengontrol aliran dan mengatur ketinggian global. Perbatasan telah ditambahkan juga untuk mengidentifikasi elemen. Perhatikan bahwa div sekarang juga memperluas ke ketinggian penuh, seperti yang diperlukan. Awalan vendor harus digunakan untuk flexbox dalam skenario dunia nyata karena belum sepenuhnya didukung.

Saya telah mengembangkan alat gratis untuk memahami dan merancang tata letak menggunakan flexbox. Lihat di sini: http://algid.com/Flex-Designer

.container{
    height:180px;
    border:3px solid #00f;
    display:flex;
    align-items:stretch;
}
div {
    display:flex;
    border:3px solid #0f0;
}
.second {
    display:flex;
    flex-grow:1;
    border:3px solid #f00;
}
<div class="container">
    <div>Tree</div>
    <div class="second">View</div>
</div>

Mario Vázquez
sumber
apakah Anda membaca SEMUA jawaban sebelumnya sebelum menambahkan jawaban Anda? sepertinya tidak ...
Temani Afif
sebagai catatan tambahan, Anda tidak perlu menambahkan stretchkarena ini adalah nilai default dan tidak perlu membuat wadah elemen anak jadi display:flextidak berguna untuk elemen dalam
Temani Afif
Saya heran mengapa downvote, tanpa komentar. Bukankah jawaban ini menjawab pertanyaan? Mengapa? Jika mencoba untuk membantu orang lain dihukum, saya akan berpikir dua kali sebelum jawaban saya berikutnya,
Mario Vázquez
1
Anda mendapat dua komentar setelah downvote, itu tidak cukup?
Temani Afif
Temari, Apakah Anda memeriksa alat saya? Tidakkah menurut Anda berguna dan dapat membantu orang lain? Apakah menurut Anda tidak ada kaitannya dengan pertanyaan? Di mana jawaban Anda untuk pertanyaan ini? Saya tidak bisa melihatnya. Apa peranmu di sini?
Mario Vázquez
-3

Jika kedua lebar adalah panjang variabel, mengapa Anda tidak menghitung lebar dengan beberapa sisi scripting atau server?

<div style="width: <=% getTreeWidth() %>">Tree</div>

<div style="width: <=% getViewWidth() %>">View</div>
amischiefr
sumber
3
Bagaimana cara server mengetahui bagaimana mesin tata letak klien akan bekerja?
Kev
Sederhana: kembangkan untuk 90% browser di luar sana :) IE 7+, FF3 + dan Safari mendukung CSS 3. Anda juga bisa memasukkan elemen standar IE6 <! - [if lte IE 6]>. Omong-omong, browser apa yang tidak mendukung style = "width:%" ??
amischiefr
Saya tidak tahu bagaimana hal itu dapat dilakukan di sisi server, tapi ya beberapa javscript dapat melakukannya tetapi saya ingin menghindarinya kecuali css / html tidak dapat melakukannya
Anurag Uniyal
Yang mana tidak bisa. Oleh karena itu, jika Anda ingin keduanya dinamis maka Anda harus melakukannya di sisi skrip atau server.
amischiefr