Satır içi geri kalan öğeyi satırın geri kalanını dolduracak şekilde nasıl yapabilirim?


186

Tablo yerine CSS ve iki satır içi blok (ya da her ne olursa olsun) DIV etiketi kullanmak böyle bir şey olabilir mi?

Tablo sürümü budur (kenarlıklar eklendi, böylece görebilirsiniz):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<table style="width:100%;">
<tr>
<td style="border:1px solid black;width:100px;height:10px;"></td>
<td style="border:1px solid black;height:10px;"></td>
</tr>
</table>
</body>
</html>

SABİT GENİŞLİK (yüzde genişlik değil) içeren bir sol sütun ve satırdaki KALAN ALAN'ı doldurmak için genişleyen sağ bir sütun üretir . Kulağa basit geliyor, değil mi? Ayrıca, hiçbir şey "yüzülmediği" için, ana kabın yüksekliği içeriğin yüksekliğini kapsayacak şekilde genişler.

--BEGIN RANT -
Sabit genişlikli yan sütuna sahip çok sütunlu düzenler için "net düzeltme" ve "kutsal kase" uygulamalarını gördüm ve emiyorlar ve karmaşıklar. Öğelerin sırasını tersine çevirirler, yüzde genişliklerini kullanırlar veya yüzer, negatif kenar boşlukları kullanırlar ve "sol", "sağ" ve "kenar boşluğu" öznitelikleri arasındaki ilişki karmaşıktır. Ayrıca, mizanpajlar alt piksele duyarlıdır, böylece tek bir kenarlık, dolgu veya kenar boşluğu pikselinin eklenmesi tüm mizanpajı kırar ve bir sonraki satıra kaydırma yapan tüm sütunları gönderir. Örneğin, her biri genişliği% 25 olarak ayarlanmış bir satıra 4 öğe koymak gibi basit bir şey yapmaya çalışsanız bile, yuvarlama hataları bir sorundur.
- END RANT--

Ben "inline-block" ve "white-space: nowrap;" kullanarak denedim, ama sorun ben sadece satırda kalan alanı doldurmak için 2 eleman alamıyorum . Genişliği "width: 100% - (LeftColumWidth) px" gibi bir şeye ayarlamak bazı durumlarda işe yarar, ancak width özelliğinde hesaplama yapmak gerçekten desteklenmez.


1
Bunu işe display: table-*yarayacak bir yapıya dönüştürmek dışında bunu yapmanın akılcı bir yolu olduğunu sanmıyorum , ama gerçekten "daha semantik" ya da (korkunç bir divçorba olmanın ) ve IE6 uyumluluğunu bozuyor. <table>Birisi olmadan çalışan dahi basit bir fikir
bulmayı

51
Evet. CSS çağının başlangıcından itibaren tüm bu "tablolardan kaçın" argümanlarına koşmaya devam ediyorum ve hala mizanpajlar için tablolar kullanıyorsanız, sizi yetersiz tembel bir moron gibi seslendirmek için yazıyoruz. On yıl ileri git ve hala idealist bir boru rüyası. Gerçek şu ki, akış düzeni semantiği, kullanıcı arayüzleri ve formları gibi sabit ama esnek düzenler için SUCK. Gerçek şu ki, akıllı insanlar uygun olan yerlerde tabloları kullanacaklar, çünkü olası her CSS çözümünü tükettiler ve hepsinin kusurlu ve sadece bir tablo kullanmaktan çok daha karmaşık olduklarını fark ettiler.
Triynko

4
Şamandıralar? Satır sonu öğelerinin beklenmedik bir şekilde satır sarmazken ve kenarlıklar ile kenar boşluklarının düzeni bozmadığı çalışma kodunu göster. Onlarda yanlış olan bu. Ayrıca, otomatik olarak boyutlandırılan ana kap, "açık düzeltme" saldırıları olmadan kayan öğeleri de kapsayacak şekilde düzgün şekilde genişliyor mu? Ben öyle düşünmedim.
Triynko

Ana konteynerinizde en az bir adet yüzen olmayan eleman varsa, o zaman yüzmeleri temizlemek için bir "hack" değil, şimdi değil mi? CSS'nin köklerinin baskıda olduğunu unutmayın - neden otomatik temizleme yapmadığınızı iyi bir şekilde tartışmak için css-tricks.com/containers-dont-clear-floats adresine bakın .
Chowlett

3
@Triynko: Daha önce yaptığım şey: jsfiddle.net/thirtydot/qx32C - Sanırım puanlarınızın çoğuna çarpıyor. Yaptığım demo hakkındaki eleştirinizi duyacağım ve daha sonra düzeltmeye çalışacağım.
thirtydot

Yanıtlar:


169

Bkz. Http://jsfiddle.net/qx32C/36/

.lineContainer {
    overflow: hidden; /* clear the float */
    border: 1px solid #000
}
.lineContainer div {
    height: 20px
} 
.left {
    width: 100px;
    float: left;
    border-right: 1px solid #000
}
.right {
    overflow: hidden;
    background: #ccc
}
<div class="lineContainer">
    <div class="left">left</div>
    <div class="right">right</div>
</div>


Neden on margin-left: 100pxile değiştirdim ? overflow: hidden.right

EDIT: İşte yukarıdaki (ölü) bağlantı için iki ayna:


60
Kendinize bir web geliştiricisi diyorsanız, bu bağlantıyı tıklamanız gerekir. Yaptım ve sihirli bir halı yolculuğunda Yasemin gibi hissettim.
Chris

2
@ChrisShouts, muhtemelen bunu tanımlamanın en iyi yolu. Bu yöntem bir anlam ifade etmiyor, ama sonra tekrar ... Açıkça yapabileceğiniz bir şey için harika bir çözüm.
mjvotaw

14
Taşan gizli bir çözüm değil. Varsayalım, sağ kabın taşmasını gizlemek istemiyorsunuz. Bu, sağ kabın boyutunun satırdaki kalan alanı doldurmasını sağlamaz. Bu, hala cevap vermediğim iki yaşındaki bir soruya bir örnektir, çünkü hala tatmin edici bir cevap yoktur.
Triynko

3
Triynko: 'taşma: gizli' kullanıyor olsanız bile, genellikle hiçbir şey gizlenmeyecektir (en azından orada metin varsa). Div içindeki metin / elemanlar, div içine sığacak şekilde düzenlenir (elbette div'den daha büyük bir öğeniz yoksa).
CpnCrunch

1
@RMorrisey: Muhtemelen sadece bazı ihtiyaçları box-sizing: border-boxile ilgili divs. Sadece bir tahmin, çünkü tarif ettiğin davranışı gösteren bir demo sunmadın. Bununla birlikte , display: tabletemelli çözüm genellikle daha iyidir . Bu çok eski bir soru, ama ben OP bu davranışı nedeniyle bu soru tabloları ile ilgisi önlemek için çalışıyordu düşünüyorum.
thirtydot

65

Flexbox kullanarak modern bir çözüm:

.container {
    display: flex;
}
.container > div {
    border: 1px solid black;
    height: 10px;
}

.left {
   width: 100px;
}

.right {
    width: 100%;
    background-color:#ddd;
}
<div class="container">
  <div class="left"></div>
  <div class="right"></div>
</div>

http://jsfiddle.net/m5Xz2/100/


4
ekran esnekliği ve genişliği% 100 .. hatırlamak
zorunda

10
flex kullanırken neden flex: 1yerine kullanmıyorsunuz width: 100%?
Itai Bar-Haim

Flexbox'ta yeni olanlar için : flex: 1kısayol flex-grow: 1. Bu bir kombinasyon nitelik var: flex: <grow> <shrink> <basis>.
tanius

1
Ekranın hızlı bir notu: flex IE 11'de desteklenmez ve 11'de çok buggy olur.
Eric Shields

1
@EricShields bu, hiç kimsenin Flexbox kullanmasını engellememelidir. Bugünlerde flexbugsbiliyoruz.
Nörotransmitter

47

Yaygın modern tarayıcılarla (IE 8+) uyumlu: http://jsfiddle.net/m5Xz2/3/

.lineContainer {
    display:table;
    border-collapse:collapse;
    width:100%;
}
.lineContainer div {
    display:table-cell;
    border:1px solid black;
    height:10px;
}
.left {
    width:100px;
}
 <div class="lineContainer">
    <div class="left">left</div>
    <div class="right">right</div>
</div>


9
Tabloları kullanmaya karşı olan argümanın sunum özellikleriyle ilgisi yoktur. Yönetilemeyen işaretleme, biçem / belge karıştırma ve yanlış anlambilim ile ilgilidir. Bu argümanların hiçbiri için geçerli değildir display:table.
Rich Remer

Bu inline-block, hattın geri kalanını nasıl dolduracağınızı cevaplamaz .
Nörotransmitter

1
@TranslucentCloud Cevabımın soru başlığına tam olarak cevap vermediğini kabul ediyorum, ancak soru gövdesinde sorulduğu gibi div değerlerini kullanarak mevcut genişliği doldurmanın bir yolunu sağlıyor.
Ayaz Z

1
Bu çözümü çok seviyorum. Gizli CSS mantığından kaynaklanan bazı tuhaf stilleri kullanmaya zorlanmıyorsunuz (gizli taşma gibi).
Chaoste

4

Her iki eleman için display: inline-block ile birlikte akışkan elemanında calc (% 100 - 100 piksel) kullanabilirsiniz.

Etiketler arasında boşluk olmamalıdır, aksi takdirde bu alanı kireçinizdeki de dikkate almanız gerekir.

.left{
    display:inline-block;
    width:100px;
}
.right{
    display:inline-block;
    width:calc(100% - 100px);
}


<div class=“left”></div><div class=“right”></div>

Kısa örnek: http://jsfiddle.net/dw689mt4/1/


1

flex-growBu hedefe ulaşmak için mülk kullandım . Sen sette gerekecek display: flexüst kapsayıcı için, o zaman sette gerekir flex-grow: 1kalan boşluk, ya da sadece doldurmak istiyor blok için flex: 1olduğu gibi tanius yorum olarak bahsedilen.


0

Kullanamıyorsanız overflow: hidden(istemediğiniz için overflow: hidden) veya CSS kesmek / geçici çözümlerden hoşlanmıyorsanız, bunun yerine JavaScript kullanabilirsiniz. JavaScript olduğu için işe yaramayabileceğini unutmayın.

var parent = document.getElementsByClassName("lineContainer")[0];
var left = document.getElementsByClassName("left")[0];
var right = document.getElementsByClassName("right")[0];
right.style.width = (parent.offsetWidth - left.offsetWidth) + "px";
window.onresize = function() {
  right.style.width = (parent.offsetWidth - left.offsetWidth) + "px";
}
.lineContainer {
  width: 100% border: 1px solid #000;
  font-size: 0px;
  /* You need to do this because inline block puts an invisible space between them and they won't fit on the same line */
}

.lineContainer div {
  height: 10px;
  display: inline-block;
}

.left {
  width: 100px;
  background: red
}

.right {
  background: blue
}
<div class="lineContainer">
  <div class="left"></div>
  <div class="right"></div>
</div>

http://jsfiddle.net/ys2eogxm/


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.