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 пикселей по всем краям, при этом страница не становилась достаточно большой, чтобы требовать полосы прокрутки.
13 ответов
Я научился делать такие вещи, читая " 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>
Скрипка от комментария Ноошу
В 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>
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>
Это одна из явных идиотий CSS - мне еще предстоит понять причину (если кто-то знает, пожалуйста, объясните).
100% означает 100% высоты контейнера, к которой добавляются любые поля, границы и отступы. Таким образом, фактически невозможно получить контейнер, который заполняет его родительский объект и у которого есть поля, границы или отступы.
Также обратите внимание, что установка высоты, как известно, несовместима и между браузерами.
Еще одна вещь, которую я узнал после публикации, - это то, что процент является относительным к длине контейнера, то есть его ширине, что делает процент еще более бесполезным для высоты.
В настоящее время блоки просмотра vh и vw более полезны, но все же не особенно полезны для чего-либо, кроме контейнеров верхнего уровня.
Другое решение заключается в использовании display:table, который имеет другое поведение блочной модели.
Вы можете установить высоту и ширину родительского элемента и добавить отступы, не расширяя его. У ребенка 100% высота и ширина минус отступы.
Другим вариантом будет использование свойства размера ящика. Единственная проблема с обоими - они не работают в IE7.
Другое решение: Вы можете использовать процентные единицы для полей и размеров. Например:
.fullWidthPlusMargin {
width: 98%;
margin: 1%;
}
Основной проблемой здесь является то, что поля будут немного увеличиваться / уменьшаться с размером родительского элемента. Предположительно, функциональность, которую вы бы предпочли, заключается в том, чтобы поля оставались постоянными, а дочерний элемент увеличивался / уменьшался для заполнения изменений в интервале. Таким образом, в зависимости от того, насколько плотно вам нужен дисплей, это может быть проблематично. (Я бы также пошел на меньшую маржу, например, 0,3%).
Сейчас 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 не обязательно важен для реальной проблемы.)
Важная часть flex: 1
(В комбинации с display: flex
у родителя). Как ни странно, самое правдоподобное объяснение того, как работает свойство Flex, я знаю из реактивной документации, поэтому я все равно на нее ссылаюсь.
Было бы более уместно добавить -webkit и -moz
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
Пример Фрэнка меня немного смутил - в моем случае это не сработало, потому что я еще недостаточно хорошо разбирался в позиционировании. Важно отметить, что родительский элемент контейнера должен иметь нестатическую позицию (он упоминал об этом, но я упустил это из виду, и это не было в его примере).
Вот пример, где дочерний элемент - заданный отступ и граница - использует абсолютное позиционирование, чтобы заполнить родительский элемент на 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
Это поведение по умолчанию display: block
Самый быстрый способ исправить это в 2020 году - установить display: 'flex'
родительского элемента и отступа, например, 20 пикселей, тогда все его дочерние элементы будут иметь высоту 100% относительно его высоты.
Граница вокруг div, а не поля страницы
Другое решение - я просто хотел простую рамку по краю моей страницы и 100% высоты, когда содержимое было меньше этого.
Граница не работала, и фиксированное положение казалось неправильным для такой простой необходимости.
Я закончил тем, что добавил контейнер в свой контейнер, вместо того, чтобы полагаться на поля тела страницы - это выглядит так:
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>