CSS: установка ширины / высоты в процентах минус пиксели - PullRequest
435 голосов
/ 12 марта 2010

Я пытаюсь создать несколько CSS-классов многократного использования для большей согласованности и меньшего количества помех на моем сайте, и я застрял при попытке стандартизировать одну вещь, которую я часто использую.

У меня есть контейнер <div>, для которого я не хочу устанавливать высоту (потому что он будет варьироваться в зависимости от того, где на сайте он находится), и внутри него есть заголовок <div>, а затем неупорядоченный список элементов, все с примененным к ним CSS.

Это выглядит примерно так:

Widget

Я хочу, чтобы неупорядоченный список занимал оставшуюся комнату в контейнере <div>, зная, что заголовок <div> имеет высоту 18px. Я просто не знаю, как указать высоту списка как «результат 100% минус 18px».

Я видел, как этот вопрос задавался в нескольких других контекстах SO, но я подумал, что стоило бы спросить еще раз для моего конкретного случая. У кого-нибудь есть советы в этой ситуации?

Ответы [ 11 ]

811 голосов
/ 31 декабря 2012

Я понимаю, что это старый пост, но, учитывая, что он не был предложен, стоит упомянуть, что если вы пишете для CSS3-совместимых браузеров, вы можете использовать calc:

height: calc(100% - 18px);

Стоит отметить, что не все браузеры в настоящее время поддерживают стандартную функцию CSS3 calc (), поэтому может потребоваться реализация специфических для браузера версий этой функции, например:

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);
68 голосов
/ 30 марта 2011

Для немного другого подхода вы можете использовать что-то вроде этого в списке:

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

Это работает до тех пор, пока родительский контейнер имеет position: relative;

25 голосов
/ 12 марта 2010

Я использую Jquery для этого

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

затем я привязываю изменение размера окна, чтобы пересчитать его при каждом изменении размера окна браузера (если размер контейнера изменился с изменением размера окна)

$(window).resize(function() { setSizes(); });
16 голосов
/ 01 августа 2012

Не определяйте высоту в процентах, просто установите top=0 и bottom=0, например:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}
8 голосов
/ 12 марта 2010

Предполагая высоту заголовка 17px

Список css:

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

Заголовок css:

height: 17px;
float: left;
width: 100%;
7 голосов
/ 30 августа 2011
  1. Используйте отрицательные поля на элементе, который вы хотели бы отключить без пикселей. (желаемый элемент)
  2. Сделать overflow:hidden; на вмещающем элементе
  3. Переключитесь на overflow:auto; на желаемом элементе.

Это сработало для меня!

5 голосов
/ 21 мая 2014

Попробуйте размер коробки. Для списка:

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;

Для заголовка:

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

Конечно, родительский контейнер должен иметь что-то вроде:

position: relative;
2 голосов
/ 28 апреля 2016

Я попробовал некоторые другие ответы, и ни один из них не работал так, как я хотел. Наша ситуация была очень похожа, когда у нас был заголовок окна, а размер окна можно было изменять с помощью изображений в теле окна. Мы хотели заблокировать соотношение сторон для изменения размера, не прибегая к дополнительным вычислениям для учета фиксированного размера заголовка, и чтобы изображение по-прежнему заполняло тело окна.

Ниже я создал очень простой фрагмент, который показывает, что мы в итоге сделали, и, кажется, хорошо работает в нашей ситуации и должен быть совместим с большинством браузеров.

В нашем элементе окна мы добавили поле размером 20 пикселей, которое способствует позиционированию относительно других элементов на экране, но не влияет на «размер» окна. Затем заголовок окна позиционируется абсолютно (что удаляет его из потока других элементов, поэтому он не вызывает смещение других элементов, таких как неупорядоченный список), а его верхняя часть позиционируется на -20px, что размещает заголовок внутри поля окна. Наконец, наш элемент ul добавляется к окну, и высота может быть установлена ​​на 100%, что заставит его заполнить тело окна (исключая поле).

*,*: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 голос
/ 25 июня 2018

Еще один способ достижения той же цели: flex box . Сделайте контейнер гибким блоком столбца, и тогда вы будете иметь полную свободу, позволяя некоторым элементам иметь фиксированный размер (поведение по умолчанию) или заполнять / уменьшать пространство контейнера (с помощью flex-grow: 1 и flex- термоусадочные:. 1)

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

См. https://jsfiddle.net/2Lmodwxk/ (попробуйте увеличить или уменьшить окно, чтобы заметить эффект)

Примечание: вы также можете использовать сокращенное свойство:

   flex:1 1 auto;
1 голос
/ 13 мая 2016

Спасибо, я решил мою с вашей помощью, немного подправив, так как я хочу, чтобы div 100% ширина 100% высоты (меньше высота нижней панели) и не было прокрутки на теле (без взлома / скрытия полос прокрутки).

Для 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;
}

Для 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>  

Это помогло, да, я поставил значение немного больше на div.adjoted для bottom, чем для высоты нижнего бара, в противном случае появляется вертикальная полоса прокрутки, я настроен на ближайшее значение.

Это различие заключается в том, что один из элементов в динамической области добавляет дополнительную нижнюю дыру, от которой я не знаю, как избавиться ... это видео-тег (HTML5), обратите внимание, я поставил этот видео-тег с этот css (так что нет никаких оснований для того, чтобы сделать нижнее отверстие, но это так):

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

Цель: иметь видео, которое занимает 100% размера браузера (и динамически изменяет размер при изменении размера браузера, но без изменения соотношения сторон), за исключением нижнего пространства, которое я использую для div с некоторыми текстами, кнопками и т. Д. (и валидаторы w3c & css конечно).

РЕДАКТИРОВАТЬ: Я нашел причину, видео тег похож на текст, а не элемент блока, поэтому я исправил это с помощью этой CSS:

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

Обратите внимание на display:block; на видео теге.

...