CSS: Ustawianie szerokości/wysokości jako procent minus piksele

Widziałem to pytanie zadawane w kilku innych kontekstach NA SO, ale pomyślałem, że warto byłoby zapytać ponownie w moim konkretnym przypadku. Próbuję stworzyć kilka klas CSS do wielokrotnego użytku, aby uzyskać większą spójność i mniej bałaganu na mojej stronie, i utknąłem na próbach standaryzacji jednej rzeczy, której często używam.

Mam kontener div, dla którego nie chcę ustawiać wysokości (ponieważ będzie się różnić w zależności od tego, gdzie na stronie jest), a wewnątrz niego znajduje się header div, a następnie unordered lista elementów, wszystkie z CSS zastosowanym do nich. Wygląda to tak:

Widget

Chcę, aby nieuporządkowana lista zajmowała Pozostałe miejsce w kontenerze div, wiedząc, że nagłówek div ma wysokość 18px. Po prostu nie wiem jak określić wysokość listy jako "wynik 100% minus 18px". Czy ktoś ma jakieś rady w tej sytuacji?

Author: Martijn Pieters, 2010-03-12

11 answers

Zdaję sobie sprawę, że to stary post, ale biorąc pod uwagę, że nie został zasugerowany, warto wspomnieć, że jeśli piszesz dla przeglądarek zgodnych z CSS3, możesz użyć calc:

height: calc(100% - 18px);

Warto zauważyć, że nie wszystkie przeglądarki obecnie obsługują standardową funkcję CSS3 calc (), więc implementacja specyficznych dla przeglądarki wersji funkcji może być wymagana jak poniżej:

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);
 753
Author: Levi Botelho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 11:31:29

Dla nieco innego podejścia przydałoby się coś takiego na liście:

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

Działa tak długo, jak długo kontener macierzysty ma position: relative;

 66
Author: Nicolas Galler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 07:36:21

Używam do tego Jquery

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

Następnie wiążę okno resize, aby ponownie skalować je za każdym razem, gdy okno przeglądarki jest zmieniane (jeśli rozmiar kontenera został zmieniony przez window resize)

$(window).resize(function() { setSizes(); });
 22
Author: puffpio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 18:56:05

Nie Definiuj wysokości jako procent, po prostu ustaw top=0 i bottom=0, tak:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}
 14
Author: kaleazy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-01 17:16:12

17px header height

Lista css:

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

Header css:

height: 17px;
float: left;
width: 100%;
 8
Author: ghoppe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 19:03:15
  1. Użyj ujemnych marginesów na elemencie, który ma być wyłączony. (pożądany element)
  2. Make overflow:hidden; on the containing element
  3. Przełącz na overflow:auto; na żądany element.
U mnie zadziałało!
 7
Author: desbest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-30 15:03:48

Spróbuj dobrać rozmiar pudełka. Do listy:

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;

Dla nagłówka:

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

Oczywiście, kontener nadrzędny powinien mieć coś w stylu:

position: relative;
 5
Author: Light,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 12:27:09

Próbowałem innych odpowiedzi i żadna z nich nie zadziałała tak, jak chciałem. Nasza sytuacja była bardzo podobna, gdy mieliśmy nagłówek okna i okno można było zmienić rozmiar z obrazami w korpusie okna. Chcieliśmy zablokować proporcje zmiany rozmiaru bez konieczności dodawania w obliczeniach, aby uwzględnić stały rozmiar nagłówka i nadal mieć obraz wypełniający korpus okna.

Poniżej stworzyłem bardzo prosty fragment, który pokazuje, co zrobiliśmy, co wydaje się działać dobrze dla naszej sytuacji i powinny być kompatybilne w większości przeglądarek.

Na naszym elemencie okna dodaliśmy margines 20px, który przyczynia się do pozycjonowania względem innych elementów na ekranie, ale nie przyczynia się do" rozmiaru " okna. Nagłówek okna jest następnie ustawiany bezwzględnie (co usuwa go z przepływu innych elementów, więc nie spowoduje przesunięcia innych elementów, takich jak lista nieuporządkowana), a jego góra jest ustawiona-20px, co umieszcza nagłówek wewnątrz margines okna. Na koniec dodajemy do okna nasz element ul, a wysokość można ustawić na 100%, co spowoduje, że wypełni on korpus okna (bez marginesu).

*,*: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>
 2
Author: TJ Rockefeller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-28 14:00:23

Dzięki, rozwiązałem mój z twoją pomocą, poprawiając go trochę, ponieważ chcę div 100% Szerokość 100% wysokość (mniejsza wysokość dolnego paska) i bez przewijania na ciele (bez hack / ukrywanie pasków przewijania).

Dla CSS:

 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;
}

Dla HTML:

<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>  

That did the trick, oh yes I put a value little greatter on div.dostosowano dla dołu niż dla dolnej wysokości paska, w przeciwnym razie pojawi się pionowy pasek przewijania, dostosowałem do najbliższej wartości.

Ta różnica polega na tym, że jeden z elements on dynamic area to dodanie dodatkowego dolnego otworu, którego Nie wiem, jak się pozbyć... jest to tag wideo (HTML5), proszę zauważyć, że umieściłem ten tag wideo z tym css (więc nie ma powodu, aby zrobić dolny otwór, ale tak jest):

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

Obiektowy: mieć film, który zajmuje 100% przeglądarki (i zmienia rozmiar dynamicznie, gdy przeglądarka jest zmieniana, ale bez zmiany proporcji) mniej dolnej przestrzeni, której używam do div z niektórymi tekstami, przyciskami itp. (i walidatorów w3c & css oczywiście).

EDIT: znalazłem powód, tag wideo jest jak tekst, a nie element blokowy, więc naprawiłem go za pomocą tego css:

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

Zwróć uwagę na display:block; na znaczniku wideo.

 1
Author: Claudio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 12:10:07

Inny sposób na osiągnięcie tego samego celu: flex boxes . Aby kontener stał się elastycznym polem kolumnowym, możesz zezwolić niektórym elementom na stały rozmiar (zachowanie domyślne) lub na wypełnianie/zmniejszanie do przestrzeni kontenera (za pomocą Flex-grow:1 i flex-shrink:1).

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

Zobacz https://jsfiddle.net/2Lmodwxk / (spróbuj rozszerzyć lub zmniejszyć okno, aby zauważyć efekt)

Uwaga: Możesz również użyć właściwości shorthand:

   flex:1 1 auto;
 1
Author: tarulen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 22:18:13

Nie jestem pewien, czy to działa w twojej konkretnej sytuacji, ale odkryłem, że padding wewnątrz div będzie przesuwać zawartość wewnątrz div, jeśli zawierający div jest stały rozmiar. Musiałbyś albo float lub absolutnie pozycjonować swój element nagłówka, ale poza tym, nie próbowałem tego dla divów o zmiennej wielkości.

 0
Author: dclowd9901,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 19:05:26