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 пикселей по всем краям, при этом страница не становилась достаточно большой, чтобы требовать полосы прокрутки.

811 css
27.01.2009 23:28:18
Я считаю, что эти два решения являются наиболее надежными: http://www.xs4all.nl/~peterned/examples/csslayout1.html http://themaninblue.com/experiment/footerStickAlt/ У вас есть какой-либо конкретный HTML, который мы можем видеть и играть с?
Nick Presta 27.01.2009 23:32:19
Ben 13.04.2012 02:37:53
14 ОТВЕТОВ
РЕШЕНИЕ

Я научился делать такие вещи, читая " 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>

Скрипка от комментария Ноошу

754
23.05.2017 12:02:56
Превосходное решение, это закладка для этого. Просто быстро добавьте его в jsfiddle.net/Rpdr9 для всех, кто хочет живую демоверсию. Надеюсь, ты не возражаешь.
Nooshu 4.03.2010 14:08:30
Хотя @Toji не заботился о совместимости с IE, я, к сожалению, должен. Это решение изначально не работало под IE6. Добавление IE9js Дина Эдвардса на страницу сделало эту работу. Теперь мне остается только надеяться и молиться о том, чтобы относительное / абсолютное позиционирование не связывало что-либо с дочерним элементом ...
Christopher Parker 19.05.2010 18:34:33
-1 (хотя похоже, что я здесь меньшинство: P). Это предполагает, что коробка может быть абсолютно позиционирована; Люди уже злоупотребляют pos: abs, они не нуждаются в этих боеприпасах. Возьмите этот пример: div "panel" с несколькими элементами div класса "panel" внутри. "панели" имеет {переполнение: скрыто; height: 300px;} и «панель» имеют различное содержимое / content-height, с {border: # 000 solid 1px; плыть налево; Маржа направо: 10px;}. Сделайте всю «панель» высотой «панели», не теряя границ ни в одной точке. Div "панели" не может быть pos: abs'd здесь. Однако решение @ Marco работает для этого сценария.
eternicode 3.06.2011 01:50:49
Ого, я понял. top:0, bottom:0По существу «растянуть» из элемента. Я могу только заставить его работать, position:absoluteхотя
Matt 12.09.2011 08:42:41
Не могли бы вы просто сделать top:20px;bottom:20px;left:20px;right:20px;вместо того, чтобы использовать поля вообще?
chowey 13.03.2013 01:50:11

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

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

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


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

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

7
19.07.2018 01:20:02
Нет никаких рассуждений, только то, что произошло, когда браузеры начали сходиться к последовательному поведению. Проверьте книгу, упомянутую в моем ответе.
Frank Schwieterman 27.01.2009 23:55:40
Проголосовал за использование правильного термина. Tex и любой менеджер компоновки, который я видел, поняли это правильно, просто CSS должен быть особенным.
maaartinus 18.07.2018 16:03:06

Согласно спецификации 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>
21
19.09.2011 06:31:53
@ Алекс: Но что делает внутренний div (дополненный) 100% высоты внешнего div. Мой опыт показывает, что вы просто получаете небольшой короткий div внутри большего div в полный рост.
Lawrence Dol 28.01.2009 03:19:16

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

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

65
4.08.2016 09:13:25
Проголосуйте, потому что вы технически правы, но это также в основном тот же ответ, что и у Фрэнка (который, я думаю, немного более дружелюбен для браузеров с небрежным доступом).
Toji 10.04.2010 01:03:42

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

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

box-sizing: border-box;

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

386
7.10.2018 21:24:54
В заключение! Я ждал этой точной функции около 10 лет. Жаль, что IE7 не поддерживает его, но я всегда думаю, что люди, которые все еще используют IE, не заслуживают красивого макета.
cronoklee 16.01.2012 11:14:11
Для меня это работало на iPhone / Safari и браузере Android по умолчанию, тогда как абсолютно позиционированное решение выше не сработало.
Spud 26.03.2012 07:03:23
По сути, это то же самое, что и модель блочного режима в IE . Я нахожу забавным то, как все ненавидят IE, но теперь border-boxвсе они герои :)
Matt Greer 13.04.2012 02:58:28
К вашему сведению, префикс браузера для определения размера ящика теперь пропущен для всех, кроме -moz. Смотрите paulirish.com/2012/box-sizing-border-box-ftw и комментарии для хорошего обсуждения
aponzani 2.08.2012 20:06:58
Да! Это правильный ответ! Высота 100% теперь корректно масштабирует вещи по отношению к родителям, не перетекая. Я бы дал миллион +1, если бы мог.
Andrew Mao 5.07.2013 21:39:32
  <style type="text/css">
.stretchedToMargin {
    position:absolute;
    width:100%;
    height:100%;

}
</style>
-2
20.01.2012 13:10:13

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

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

#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

2
30.07.2015 11:15:31

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

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

JSBIN

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

5
31.07.2015 09:07:03

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

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

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

39
15.04.2020 17:09:20
Хорошее решение. Только не забудьте проверить поддержку браузера: могу ли я использовать calc ()
Brett Postin 17.06.2013 08:12:08
Разве это не даст вам 100% ширину и высоту каждого отступа PLUS 5px, так как заполнение фактически сделает элемент на 10px шире и больше соответственно?
user3476725 1.11.2014 15:50:41
Наконец, хорошее решение, и не так, как все остальные, вы устанавливаете верхний, правый, нижний и левый значения на 0, что будет работать только с position: absolute;
Gil Epshtain 20.01.2018 17:57:32
Я думаю, что правильно: #myDiv {width: calc (100% - 10px); высота: calc (100% - 10px); обивка: 5px; } 5 слева и 5 справа = 10, 5 сверху и 5 снизу = 10
Chris P 15.03.2019 09:10:27

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

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

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

4
29.10.2013 19:12:38

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>

8
15.01.2017 23:06:41

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

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

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

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

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

.container {
    width: 100%;
    min-height: 100%;
    border: 8px solid #564333;
}
0
18.12.2017 03:19:13

Решение с 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, который указывает компоненту заполнить все доступное пространство, равномерно распределенное между другими компонентами с тем же родителем

3
25.07.2019 14:36:39

Это поведение по умолчанию. display: blockСамый быстрый способ исправить это в 2020 году - установить display: 'flex'родительский элемент и отступ, например, 20px, тогда все его дочерние элементы будут иметь 100% высоты относительно его высоты.

0
26.02.2020 16:02:52