CSS: Genişliği / yüksekliği Yüzde eksi piksel olarak ayarlama


479

Sitemde daha fazla tutarlılık ve daha az dağınıklık için yeniden kullanılabilir bazı CSS sınıfları oluşturmaya çalışıyorum ve sık kullandığım bir şeyi standartlaştırmaya çalışıyorum.

<div>Yüksekliğini ayarlamak istemediğim bir konteynere sahibim (çünkü sitede nerede olduğuna bağlı olarak değişecektir) ve içinde bir başlık <div>ve daha sonra tüm CSS uygulanmış öğelerin sırasız bir listesi var onlar.

Şuna çok benziyor:

Araç

İstediğim sırasız liste kapta kalan odayı almaya <div>başlık bilerek <div>olup 18pxuzun boylu. Listenin yüksekliğini " 100%eksi sonucu" olarak nasıl belirleyeceğimi bilmiyorum 18px.

Bu soruyu SO hakkında birkaç bağlamda sordum gördüm, ancak özel durumum için tekrar sormaya değeceğini düşündüm. Bu durumda herhangi bir tavsiye var mı?


6
Kenar boşluğu belirlensin mi? __
kennytm

@KennyTM, sanırım 17 piksel değerinde sıralamasız listeme bir kenar boşluğu koymamı önerirsiniz. Ancak bu sadece tüm listeyi aşağıya iter; kapta kalması için büzülmesine neden olmaz. Aslında, mevcut yükseklik korunur, ancak sadece 17 piksel aşağı itilir. Bu benim sorunumu çözmüyor, ama bence bu doğru yönde atılmış bir adım çünkü çevrimiçi olarak bu tekniği kullanan başka yaklaşımlar gördüm.
MegaMatt

Bu konuyu burada gönderdiğim sorumda çözdüm. stackoverflow.com/a/10420387/340947
Steven Lu

Yanıtlar:


895

Bunun eski bir gönderi olduğunu anlıyorum, ancak önerilmediği göz önüne alındığında, CSS3 uyumlu tarayıcılar için yazıyorsanız, şunları kullanabilirsiniz calc:

height: calc(100% - 18px);

Şu anda tüm tarayıcıların standart CSS3 calc () işlevini desteklemediğini belirtmek gerekir, bu nedenle işlevin tarayıcıya özgü sürümlerini uygulamak aşağıdaki gibi gerekebilir:

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);

5
Evet, şimdilik bu normal.
Levi Botelho

1
IE10 ve Chrome 27'de benim için çalışıyor. Siz efendim, benim korkutucu kahramanım!
BrainSlugs83

3
@LeviBotelho Benim kötü. Operatörün çevresinde boşluk yoktu.
kullanıcı

20
Ayrıca daha lessc --strict-math=onaz kullanırsanız, içindeki ifadeyi değerlendirmemek için bir dosyayı derlemeniz daha iyi olur calc- sadece karşılaştığım ve çok zaman harcadığım bir sorun (Daha az 2.0.0'dan itibaren)
Dmitry Wojciechowski

34
Eksi işareti etrafında boşluklar isteğe olmadıklarını Not: 100%-18px, 100%- 18pxve 100% -18pxben ile test tarayıcılarda işe yaramadı.
nisetama

71

Biraz farklı bir yaklaşım için listede böyle bir şey kullanabilirsiniz:

position: absolute;
top: 18px;
bottom: 0px;
width: 100%;

Bu, üst kapsayıcıya sahip olduğu sürece çalışır position: relative;


1
teşekkürler dostum. ana kap position: relative;beni açıyor.
12th

Benim gibi merak edebilecekler için: pozisyon absoluteçocuk konteynerinde olmalı, olamaz relative.
Greg

Devam (özür dilerim): Ancak ebeveynin sadece konumlandırması gerekir ( absoluteçok da olabilir ) ve% 100 yüksekliğe de ayarlanması gerekir.
Greg

1
Ne yazık ki, Safari iOS 8'de çalışmıyor. (Android 4.1 stok tarayıcısında ve standart FF 34'de TAMAM test edildi) :-(
Greg

Bu, bazı durumlarda işe yarayabilir, ancak kesinlikle konumlandırılmış öğeler normal akıştan çıkarıldığı için bazı sorunlara da neden olabilir, bkz. Stackoverflow.com/a/12821537/4173303 .
Christophe Weis

26

Bunun için Jquery kullanıyorum

function setSizes() {
   var containerHeight = $("#listContainer").height();
   $("#myList").height(containerHeight - 18);
}

daha sonra tarayıcı penceresi yeniden boyutlandırıldığında yeniden boyutlandırmak için pencerenin yeniden boyutlandırmasını bağlarım (kabın boyutu, pencere yeniden boyutlandırmasıyla değiştiyse)

$(window).resize(function() { setSizes(); });

12
@puffpio, Kesinlikle JS bunu duruma göre gerçekleştirmenin bir yoludur. Ama dediğim gibi, CSS'yi genel yapmaya çalışıyorum, birden fazla sayfaya uygulanacak (bu bir ana sayfadan miras olarak). Bu yüzden JS kullanmamayı tercih ederim. Ama cevap için teşekkürler.
MegaMatt

7
Tarzınızı JavaScript'in içine koymayın.
Greg

8
@greg, CSS'nin daha kullanışlı bazı özellikleri varsa yardımcı olur. Hack yapmak zorunda olduğunuz bazı şeyler saçma.
Jonathan.

1
@puffpio Gerçekten güzel bir çözüm. Ancak pencerede bağlayıcı olaylar benim için iyi bir çözüm değil. Sayfamda 3-4 veya daha fazla öğe varsa, pencere yeniden boyutlandırma işleyicisindeki her öğenin yüksekliğini ve genişliğini güncellemem gerekir. Bu, CSS çözümünden biraz daha yavaş olacaktır.
sachinjain024

1
"Xyz'inizi JavaScript'in içine koymayın" demek "tarayıcı pazarının% 80'ini desteklemeyin" demek gibidir.
Beejor

16

Yüksekliği yüzde olarak tanımlamayın, top=0ve öğesini bottom=0şu şekilde ayarlayın:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}

Yüksekliği neden yüzde olarak ayarlamadığınızı açıklayabilir misiniz?
Shrikant Sharat

@ShrikantSharat Bu, kesinlikle konumlandırılmış öğeler için görsel biçimlendirme spesifikasyonunun bir parçasıdır . Bu çözüm 5. olasılıktan yararlanır. "" Yükseklik "," otomatik "," üst "ve" alt "," otomatik "değildir, daha sonra" kenar boşluğu "ve" kenar boşluğu "için" otomatik "değerler ayarlanır 0'a getirin ve 'yükseklik' için çözün. Tarayıcı, öğenin yüksekliğini hesaplayabilir, çünkü üst öğesinin üstünden ve altından ne kadar uzakta olması gerektiğini bilir.
Ross Allen

En azından Firefox'ta bu işe yaramıyor gibi görünüyor. Tüm üst öğeler height:100%ve ile ayarlanmış olsa bile display:block. Aksi takdirde çok şık bir çözüm olurdu. İlginç bir şekilde, margin:autosabit genişlikte bir nesneyi yatay olarak iyi çalışmasına rağmen dikey olarak ortalayamaz.
Ocak'ta Beejor

8

17 piksel başlık yüksekliği varsayımı

Css listesi:

height: 100%;
padding-top: 17px;

Başlık css:

height: 17px;
float: left;
width: 100%;

Evet, ben de buna katılıyordum.
dclowd9901

1
Umduğum kadar iyi olmadı. Sıralanmamış listem, div üstbilgisinin altında başlatılıyor. Başlık divı kapta yer kaplıyor, bu nedenle listeye 17px'lik dolgu üstünü koymak, kabın div'inin üstünden 17px değil, yukarıdaki resimde olduğu yerden 17px aşağı itecek. Yukarıdaki cevapta verilen CSS ile aldığımın bir resmi: i41.tinypic.com/mcuk1x.jpg . Yine de çabayı takdir ediyorum ve eksik olduğumu düşündüğünüz bir şey varsa, lütfen bana bildirin. Btw, taşma var: sırasız listede otomatik.
MegaMatt

2
Tam olarak hangi etkileşimlerin olduğunu görmek için, gerçek css gönderirseniz, bu sorunu gidermek çok daha kolay olurdu. Deneyebileceğiniz başka bir şey, ülkenizdeki negatif üst marjdır. ul { margin-top: -17px; }
Mart'ta ghoppe

7
  1. Eksi pikselleri kapatmak istediğiniz öğede negatif kenar boşlukları kullanın. (istenen öğe)
  2. Make overflow:hidden;içeren elemana
  3. Geçiş overflow:auto;istenilen elemana.

Benim için çalıştı!


3
Bu benim için bir cazibe gibi çalıştı (taşma değiştirmek bile gerekmedi). Harika bir çözüm, teşekkür ederim!
Aaj

1
Tamamen sahane! Popüler "CSS calc" çözümü hakkında bilgi edinmek hoşuma gitti, ancak bu çok daha basit ve daha geniş tarayıcı desteğine sahip. Negatif marjlar mükemmel!
Simon Steinberger

Bu çok zarif ve uyumlu bir çözümdür. Ana dezavantajı, elemanın sabit bir yükseklik olması gerektiğidir. Aksi takdirde JS kullanmanız veya calc()çalışma zamanında ortalamanız gerekir. Ancak çoğu durumda bu bir sorun olmamalı. Akılda tutulması gereken başka bir şey, kenar boşlukları, dolgu ve ofsetler için çok sayıda negatif değer kullanmanın, daha sonra kodda hata ayıklarken karışıklığa neden olabileceğidir, bu yüzden işleri basit tutmaya çalışın.
Beejor

5

Kutu boyutlandırmayı deneyin. Liste için:

height: 100%;
/* Presuming 10px header height */
padding-top: 10px;
/* Firefox */
-moz-box-sizing: border-box;
/* WebKit */
-webkit-box-sizing: border-box;
/* Standard */
box-sizing: border-box;

Üstbilgi için:

position: absolute;
left: 0;
top: 0;
height: 10px;

Tabii ki, ana kapsayıcı şöyle olmalıdır:

position: relative;

3

Aynı hedefe ulaşmanın başka bir yolu: esnek kutular . Konteyneri bir sütun esnek kutusu yapın ve daha sonra bazı öğelerin sabit boyutlu (varsayılan davranış) olmasına izin verme veya konteyner boşluğunu doldurma / küçültme (flex-grow: 1 ve flex- küçültmek: 1).

#wrap {        
  display:flex;
  flex-direction:column;
}
.extendOrShrink {
  flex-shrink:1;
  flex-grow:1;
  overflow:auto;
}

Bkz. Https://jsfiddle.net/2Lmodwxk/ (efekti fark etmek için pencereyi genişletmeye veya azaltmaya çalışın)

Not: steno özelliğini de kullanabilirsiniz:

   flex:1 1 auto;

Bunun bugün için en iyi yanıt olabileceğine inanıyorum, çünkü div div (orijinal sorumda 18px) için belirlenmiş bir yükseklik belirtmek zorunda değilsiniz ve dolgu ve marj gibi şeyleri çıkarmak zorunda değilsiniz. Belirlenmiş piksel yok ve her şey kendi kendine ilgileniyor.
MegaMatt

2

Diğer cevaplardan bazılarını denedim ve hiçbiri tam istediğim gibi çalıştı. Durumumuz bir pencere başlığına sahip olduğumuz ve pencere gövdesindeki görüntülerle pencerenin yeniden boyutlandırılabildiği yerlerde çok benzerdi. Başlığın sabit boyutunu hesaba katmak için hesaplamalara eklemeye gerek kalmadan yeniden boyutlandırmanın en boy oranını kilitlemek ve görüntünün pencere gövdesini doldurmasını istedik.

Aşağıda, yaptığımız durumun iyi sonuç verdiğini ve çoğu tarayıcıda uyumlu olması gerektiğini gösteren çok basit bir snippet oluşturdum.

Pencere öğemize, ekrandaki diğer öğelere göre konumlandırmaya katkıda bulunan, ancak pencerenin "boyutuna" katkıda bulunmayan 20 piksellik bir kenar boşluğu ekledik. Pencere başlığı daha sonra kesinlikle konumlandırılır (diğer öğelerin akışından kaldırılır, bu nedenle sıralanmamış liste gibi diğer öğelerin kaydırılmasına neden olmaz) ve üst kısmı, başlığı kenar boşluğunun içine yerleştiren -20px konumlandırılır pencerenin. Son olarak ul elemanımız pencereye eklenir ve yükseklik% 100 olarak ayarlanabilir, bu da pencerenin gövdesini doldurmasına neden olur (kenar boşluğu hariç).

*,*:before,*:after
{
  box-sizing: border-box;
}

.window
{
  position: relative;
  top: 20px;
  left: 50px;
  margin-top: 20px;
  width: 150px;
  height: 150px;
}

.window-header
{
  position: absolute;
  top: -20px;
  height: 20px;
  border: 2px solid black;
  width: 100%;
}

ul
{
  border: 5px dashed gray;
  height: 100%;
}
<div class="window">
  <div class="window-header">Hey this is a header</div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
  </ul>
</div>


1

Teşekkürler, yardımınızla mayın çözdüm, çünkü bir div% 100 genişlik% 100 yükseklik (alt çubuğun daha az yüksekliği) ve vücutta kaydırma yok (kesmek / kaydırma çubukları olmadan).

CSS için:

 html{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 body{
  position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 div.adjusted{
  position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px;
 }
 div.the_bottom_bar{
  width:100%;height:31px;margin:0px;border:0px;padding:0px;
}

HTML için:

<body>
<div class="adjusted">
 // My elements that go on dynamic size area
 <div class="the_bottom_bar">
  // My elements that goes on bottom bar (fixed heigh of 31 pixels)
 </div>  
</div>  

Bu hile yaptı, oh evet ben div.t alt çubuk yüksekliği için daha alt ayarlanmış biraz daha büyük bir değer koymak, başka dikey kaydırma çubuğu görünür, ben en yakın değer olarak ayarlanmış.

Bu fark, dinamik alandaki öğelerden birinin nasıl kurtulacağımı bilmediğim ekstra bir alt delik eklemesi ... bir video etiketi (HTML5), lütfen bu video etiketini bu css ( bu nedenle bir alt delik açması için bir neden yoktur, ancak yapar):

 video{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

Amaç: Tarayıcının% 100'ünü alan (ve tarayıcı yeniden boyutlandırıldığında dinamik olarak yeniden boyutlandırılan, ancak en boy oranını değiştirmeden) daha az bazı metinler, düğmeler vb. w3c & css tabii ki).

EDIT: Ben nedenini buldum, video etiketi metin gibi bir blok öğesi değil, bu yüzden bu css ile sabit:

 video{
  display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

Not display:block;video etiketine üzerinde.


0

Bu durumun sizin özel durumunuzda olup olmadığından emin değilim, ancak içeren div sabit bir boyuttaysa, iç div üzerindeki dolgu, bir div içindeki içeriği itecektir. Üstbilgi öğenizi yüzdürmeniz veya kesinlikle konumlandırmanız gerekir, ancak aksi takdirde, değişken boyutlu div'ler için bunu denemedim.

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.