CSS 100% высота с заполнением / маржей

это сводит меня с ума уже пару дней, но на самом деле это проблема, которую я ударил и в течение последних нескольких лет: с HTML/CSS как я могу сделать элемент, который имеет ширину и/или высоту, которая составляет 100% от его родительского элемента и все еще имеет правильное заполнение или поля?

под "правильным" я имею в виду, что если мой родительский элемент 200px высокий, и я указать height = 100% С padding = 5px Я ожидал бы, что я должен получить 190px высокий элемент с border = 5px со всех сторон, красиво центрирован в родительском элементе.

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

#myDiv {
    width: 100%
    height: 100%;
    padding: 5px;
}

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

EDIT: поскольку был запрошен пример, вот самый простой, который я могу придумать:

<html style="height: 100%">
    <body style="height: 100%">
        <div style="background-color: black; height: 100%; padding: 25px"></div>
    </body>
</html>

задача состоит в том, чтобы заставить черный ящик отображаться с 25-пиксельным заполнением по всем краям без страницы, достаточно большой, чтобы требовать полос прокрутки.

13 ответов


Я научился делать такие вещи, читая" PRO HTML и CSS шаблоны дизайна". The display:block - это значение по умолчанию для div, но я хотел бы сделать это явным. Контейнер должен быть правильного типа; и fixed, relative или absolute.

.stretchedToMargin {
  display: block;
  position:absolute;
  height:auto;
  bottom:0;
  top:0;
  left:0;
  right:0;
  margin-top:20px;
  margin-bottom:20px;
  margin-right:80px;
  margin-left:80px;
  background-color: green;
}
<div class="stretchedToMargin">
  Hello, world
</div>

Скрипка по Nooshu это комментарий


есть новое свойство в CSS3 что вы можете использовать, чтобы изменить способ, которым модель коробки вычисляет ширину/высоту, это называется box-sizing.

установив это свойство со значением "border-box", он делает любой элемент, который вы применяете, чтобы не растягиваться при добавлении отступа или границы. Если вы определяете что-то с шириной 100px и заполнением 10px, оно все равно будет шириной 100px.

box-sizing: border-box;

см. здесь для поддержки браузера. Это не работает для IE7 и ниже, однако, я считаю, что Дин Эдвард IE7.js добавлена поддержка для него. Наслаждайтесь :)


решение состоит в том, чтобы не использовать высоту и ширину вообще! Прикрепите внутреннюю коробку, используя верхнюю, левую,правую, нижнюю, а затем добавьте поле.

.box {margin:8px; position:absolute; top:0; left:0; right:0; bottom:0}
<div class="box" style="background:black">
  <div class="box" style="background:green">
    <div class="box" style="background:lightblue">
      This will show three nested boxes. Try resizing browser to see they remain nested properly.
    </div>
  </div>
</div>

лучший способ - это свойство calc (). Таким образом, ваш случай будет выглядеть так:

#myDiv {
    width: calc(100% - 5px);
    height: calc(100% - 5px);
    padding: 5px;
}

простой, чистый, без обходных путей. Просто убедитесь, что вы не забыли пространство между значениями и оператором (например, (100%-5px), который нарушит синтаксис. Наслаждайтесь!


в соответствии с высотой спецификации w3c относится к высоте видимой области, например, на мониторе разрешения пикселей 1280x1024 100% высота = 1024 пикселя.

min-height относится к общей высоте страницы, включая содержимое, поэтому на странице, где содержимое больше, чем 1024px min-height:100% растянется, чтобы включить все содержимое.

другая проблема заключается в том, что заполнение и граница добавляются к высоте и ширине в большинстве современных браузеров, кроме ie6(ie6 на самом деле вполне логично, но не соответствует спецификации). Это называется моделью коробки. Поэтому, если вы укажете

min-height: 100%;
padding: 5px; 

это фактически даст вам 100% + 5px + 5px для высоты. Чтобы обойти это, вам нужен контейнер-обертка.

<style>
    .FullHeight { 
       height: auto !important; /* ie 6 will ignore this */
       height: 100%;            /* ie 6 will use this instead of min-height */
       min-height: 100%;        /* ie 6 will ignore this */
    }

    .Padded {
       padding: 5px;
    }
</style>

<div class="FullHeight">
   <div class="Padded">
      Hello i am padded.
   </div
</div>

Это один из откровенных идиотизмов CSS - мне еще предстоит понять рассуждения (если кто-то знает, пожалуйста. объяснять.)

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

обратите внимание также, что установка высоты, как известно, несовместима между браузерами.


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

В настоящее время блоки VH и VW viewport более полезны, но все же не особенно полезны ни для чего, кроме контейнеров верхнего уровня.


1. Полный рост с padding

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  padding: 50px;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>

2. Полный рост с margin

body {
  margin: 0;
}
.container {
  min-height: calc(100vh - 100px);
  margin: 50px;
  background: silver;
}
<div class="container">Hello world.</div>

3. Полный рост с border

body {
  margin: 0;
}
.container {
  min-height: 100vh;
  border: 50px solid pink;
  box-sizing: border-box;
  background: silver;
}
<div class="container">Hello world.</div>

другое решение-использовать display: table, который имеет другое поведение модели коробки.

вы можете установить высоту и ширину родителя и дополнения, не расширяя его. Ребенок имеет 100% высоту и ширину минус отступы.

JSBIN

другой вариант-использовать box-sizing propperty. Единственная проблема с обоими - они не работают в IE7.


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

.fullWidthPlusMargin {
    width: 98%;
    margin: 1%;
}

основная проблема здесь заключается в том, что поля будут немного увеличиваться/уменьшаться с размером родительского элемента. Предположительно, вы бы предпочли, чтобы поля оставались постоянными, а дочерний элемент рос/сжимался для заполнения изменений в интервале. Таким образом, в зависимости от того, насколько плотно вам нужен ваш дисплей, это может быть проблематично. (Я бы также пошел на меньший маржа, как 0.3%).


вот пример, где дочернее заполнение и граница-использует абсолютное позиционирование для заполнения родительского 100%. Родитель использует относительное позиционирование, чтобы обеспечить точку ссылка на положение ребенка, оставаясь в нормальном потоке-следующий элемент "больше-содержание"не влияет:

#box {
    position: relative;
    height: 300px;
    width: 600px;
}

#box p {
    position: absolute;
    border-style: dashed;
    padding: 1em;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
<div id="box">
  <p>100% height and width!</p>
</div>
<div id="more-content">
</div>

полезное ссылке для быстрого изучения позиционирования CSS


Это 2018 сейчас, новое горячее дерьмо должно быть упомянуто здесь, поскольку вопрос продолжает появляться в Google.

решение flexbox (работа над IE11): (или посмотреть на jsfiddle)

<html>
  <style>
    html, body {
      height: 100%; /* fix for IE11, not needed for chrome/ff */
      margin: 0; /* CSS-reset for chrome */
    }
  </style>
  <body style="display: flex;">
    <div style="background-color: black; flex: 1; margin: 25px;"></div>
  </body>
</html>

(том CSS-reset Не обязательно важно для реальной проблемы.)

и flex: 1 (в сочетании с display: flex на родительском). Как ни странно, самое правдоподобное объяснение, которое я знаю, как Flex property works происходит из react-родной документации,поэтому я все равно ссылаюсь на него.


граница вокруг div, а не поле тела страницы

другое решение-я просто хотел простую границу по краю моей страницы, и я хотел 100% высоты, когда содержимое было меньше, чем это.

Border-box не работал, и фиксированное позиционирование казалось неправильным для такой простой необходимости.

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

body, html {
    height: 100%;
    margin: 0;
}

.container {
    width: 100%;
    min-height: 100%;
    border: 8px solid #564333;
}

  <style type="text/css">
.stretchedToMargin {
    position:absolute;
    width:100%;
    height:100%;

}
</style>