CSS 100% высота с отступом / полем


813

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


Я нашел эти два решения наиболее надежными: http://www.xs4all.nl/~peterned/examples/csslayout1.html http://themaninblue.com/experiment/footerStickAlt/ У вас есть какой-либо конкретный HTML, который мы можем видеть и играть с?
Ник Преста

Ответы:


755

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

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


42
Превосходное решение, это закладка для этого. Просто быстро добавьте его в jsfiddle.net/Rpdr9 для всех, кто хочет живую демоверсию. Надеюсь, ты не возражаешь.
Nooshu

16
Хотя @Toji не заботился о совместимости с IE, я, к сожалению, должен. Это решение изначально не работало под IE6. Добавление IE9js Дина Эдвардса на страницу сделало эту работу. Теперь мне остается только надеяться и молиться о том, чтобы относительное / абсолютное позиционирование не связывало что-либо с дочерним элементом ...
Кристофер Паркер

24
-1 (хотя похоже, что я здесь меньшинство: P). Это предполагает, что коробка может быть абсолютно позиционирована; Люди уже злоупотребляют pos: abs, они не нуждаются в этих боеприпасах. Возьмите этот пример: div "panel" с несколькими элементами div класса "panel" внутри. "панели" имеет {переполнение: скрыто; height: 300px;} и «панель» имеют различное содержимое / content-height, с {border: # 000 solid 1px; плыть налево; Маржа направо: 10px;}. Сделайте всю «панель» высотой «панели», не теряя границ ни в одной точке. Div "панели" не может быть pos: abs'd здесь. Однако решение @ Marco работает для этого сценария.
Eternicode

8
Ого, я понял. top:0, bottom:0По существу «растянуть» из элемента. Я могу только заставить его работать, position:absoluteхотя
Мэтт

7
Не могли бы вы просто сделать top:20px;bottom:20px;left:20px;right:20px;вместо того, чтобы использовать поля вообще?
Чоуи

391

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

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

box-sizing: border-box;

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


45
В заключение! Я ждал этой возможности около 10 лет. Жаль, что IE7 не поддерживает его, но я всегда думаю, что люди, которые все еще используют IE, не заслуживают красивого макета.
cronoklee

2
Для меня это работало на iPhone / Safari и браузере Android по умолчанию, тогда как абсолютно позиционированное решение выше не сработало.
Спуд

18
По сути, это то же самое, что и модель блочного режима в IE . Я нахожу забавным то, что все ненавидят IE, но теперь они border-boxвсе герои :)
Мэтт Грир

14
К вашему сведению, префикс браузера для определения размера ящика теперь пропущен для всех, кроме -moz. Смотрите paulirish.com/2012/box-sizing-border-box-ftw и комментарии для хорошего обсуждения
aponzani

3
Да! Это правильный ответ! 100% рост теперь корректно масштабирует вещи по отношению к родителям, не перетекая. Я бы дал миллион +1, если бы мог.
Андрей Мао

65

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

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


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

39

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

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

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


6
Хорошее решение. Только не забудьте проверить поддержку браузера: Могу ли я использовать calc ()
Бретт Постин

5
Разве это не даст вам 100% ширины и высоты каждого отступа PLUS 5px, так как заполнение эффективно сделает элемент на 10px шире и больше соответственно?

Наконец, хорошее решение, и не так, как все остальные, вы устанавливаете верхний, правый, нижний и левый значения на 0, что будет работать только с position: absolute;
Гил Эпштейн

Я думаю, что правильно: #myDiv {width: calc (100% - 10px); высота: calc (100% - 10px); обивка: 5px; } 5 слева и 5 справа = 10, 5 сверху и 5 снизу = 10
Крис П

21

Согласно спецификации 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>

4
@ Алекс: Но что делает внутренний div (дополненный) 100% высоты внешнего div. Мой опыт показывает, что вы просто получаете небольшой короткий div в большем полном div.
Лоуренс Дол

8

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>


7

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

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

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


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

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


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

Проголосовал за использование правильного термина. Tex и любой менеджер компоновки, который я видел, поняли это правильно, просто CSS должен быть особенным.
Maaartinus

5

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

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

JSBIN

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


4

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

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

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


3

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


2

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

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


0

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

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

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

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

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

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

0

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


0

Добавить -webkit и -moz было бы более уместно

-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.