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

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

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

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

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

Но мне кажется, что должен быть НЕКОТОРЫЙ способ надежного создания этого эффекта для родителя произвольного размера. Кто-нибудь знает способ выполнения этой (казалось бы простой) задачи?

Да, и для записи, я не очень заинтересован в совместимости IE, так что это (надеюсь) должно немного облегчить ситуацию.

ОБНОВЛЕНИЕ: Так как пример был запрошен, вот самый простой, который я могу придумать:

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

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

Ответ 1

Я научился делать такие вещи, читая " PRO HTML и CSS Design Patterns". display:block является отображаемым значением по умолчанию для div, но мне нравится делать его явным. Контейнер должен быть правильного типа; position - 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>

Ответ 2

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

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

box-sizing: border-box;

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

Ответ 3

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

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

Ответ 4

Лучший способ заключается в свойстве calc(). Итак, ваше дело будет выглядеть так:

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

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

Ответ 5

В соответствии с высотой спецификации 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>

Ответ 6

1. Полная высота с padding

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

Ответ 7

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

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

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


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

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

Ответ 8

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

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

JSBIN

Другой вариант - использовать опцию box-sizing. Только проблема с обоими была бы, они не работают в IE7.

Ответ 9

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

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

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

Ответ 10

Решение с 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 не обязательно важен для реальной проблемы.)

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

(...) flex: 1, который указывает компоненту заполнить все доступное пространство, равномерно распределенное между другими компонентами с тем же родителем

Ответ 11

Пример Фрэнка немного смутил меня - в моем случае это не сработало, потому что я еще недостаточно понимал позиционирование. Важно отметить, что элемент родительского контейнера должен иметь нестационарное положение (он упомянул об этом, но я его не заметил, и это не было в его примере).

Здесь пример, где дочернее задание и граница - использует абсолютное позиционирование, чтобы заполнить родительский 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

Ответ 12

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

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

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

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

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

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

Ответ 13

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

}
</style>