CSS 100% висота з підкладкою / запасом


813

Як за допомогою 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-піксельним накладкою на всіх краях, не зростаючи, щоб сторінка зростала достатньо великою, щоб вимагати прокрутки.


Ці два рішення я визнав найбільш надійними: http://www.xs4all.nl/~peterned/examples/csslayout1.html http://themaninblue.com/experiment/footerStickAlt/ Чи є у вас конкретний HTML, який ми можемо бачити і грати?
Нік Преста

Відповіді:


755

Я навчився робити такі речі, читаючи " Шаблони дизайну PRO HTML та CSS ". Значення 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 для всіх, хто хоче демо-версію. Сподіваюся, ви не заперечуєте.
Ноошу

16
Хоча @Toji не переймався сумісністю IE, я, на жаль, маю це зробити. Це рішення спочатку не працювало під IE6. Додавання IE9.js Діна Едвардса до сторінки зробило цю роботу. Тепер я просто сподіваюся і молюся, щоб відносне / абсолютне позиціонування не заграло щось у дитячій стихії ...
Крістофер Паркер

24
-1 (хоча, схоже, я тут меншість: P). Це передбачає, що ящик може бути абсолютно розміщений; люди вже зловживають поз: абс, як це є, їм боєприпаси не потрібні. Візьмемо цей приклад: div "панелі" з декількома ключами класу "панель" всередині нього. "панелі" має {переповнення: приховано; висота: 300 пікселів;} і "панель" мають різний вміст / висоту вмісту, з {межами: # 000 твердого 1px; поплавок: зліва; margin-right: 10px;}. Зробіть усі "панелі" висотою "панелей", не втрачаючи меж у будь-якій точці. Діви на панелі не можуть бути позиційними: abs'd тут. @ Але рішення Марко працює і за цим сценарієм.
eternicode

8
О, вау, я розумію. Елемент top:0, bottom:0по суті, "розтягує" елемент. Я можу змусити його працювати, position:absoluteхоча
Метт,

7
Чи не могли ви просто зробити top:20px;bottom:20px;left:20px;right:20px;замість того, щоб взагалі використовувати маржі?
chowey

391

У CSS3 є нова властивість, яку ви можете використовувати для зміни способу обчислення ширини / висоти моделі коробки, її називають розміром коробки.

Встановивши це властивість зі значенням "border-box", це робить який би елемент ви застосували, щоб він не розтягувався, коли ви додаєте прокладку або облямівку. Якщо ви визначите щось із шириною 100 пікселів та накладкою 10 пікселів, воно все одно буде шириною 100 пікселів.

box-sizing: border-box;

Дивіться тут для підтримки браузера . Це не працює для IE7 і нижче, проте я вважаю, що IE7.js Діна Едуарда додає підтримку. Насолоджуйтесь :)


45
Нарешті! Я чекав на цю точну функцію вже близько 10 років. Шкода, що IE7 не підтримує це, але я завжди думаю, що люди, які все ще використовують IE, не заслуговують на гарний макет.
cronoklee

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

18
Це в основному те саме, що модель вікна режиму примх IE . Мені здається смішним, як всі ненавидять на IE, але зараз border-boxгерой кожного :)
Метт Грір,

14
FYI, префікс браузера для розміру коробки тепер випав для всіх, крім -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
Голосуйте за те, що ви технічно правильні, але це в основному така ж відповідь, як і у Франка (що, на мою думку, трохи привітніше до браузерів-скатперів)
Toji

39

Кращий спосіб - з властивістю calc (). Так ваш вигляд виглядав би так:

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

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


6
Приємне рішення. Просто пам’ятайте, щоб перевірити підтримку браузера: Чи можу я використовувати calc ()
Brett Postin

5
Невже це не дасть тобі 100% ширини та висоти для кожної прокладки PLUS 5px, оскільки накладка ефективно зробить елемент 10px ширшим та більшим відповідно?

Зрештою, гарне рішення, і не так, як решта з них, ви підсуньте верх, праворуч, знизу і зліва 0, це буде працювати лише з положення: абсолютний;
Гіл Епштейн

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

21

Відповідно висота специфікації w3c відноситься до висоти області видимості, наприклад, на моніторі з роздільною здатністю 1280x1024 пікселів 100% висота = 1024 пікселів.

мінімальна висота означає загальну висоту сторінки, включаючи вміст, тому на сторінці, де вміст перевищує 1024 пікселів, мінімальна висота: 100% буде розтягнуто, щоб включити весь вміст.

Інша проблема тоді полягає в тому, що в більшості сучасних веб-переглядачів додаються накладки та облямівка, за винятком ie6 (тобто6 насправді цілком логічно, але не відповідає специфікації). Це називається коробковою моделлю. Тож якщо ви вкажете

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
@ Алекс: Але те, що робить внутрішній дів (Підкладка) 100% висоти зовнішнього діва. Мій досвід полягав у тому, що ви просто отримуєте невеличкий короткий дів всередині більшого дива на повну висоту.
Лоуренс Дол

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%. Батько використовує відносне позиціонування, щоб забезпечити точку відліку для позиції дитини, залишаючись у нормальному потоці - наступний елемент "більше вмісту" не впливає:

#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'батьківський елемент і накладки, наприклад, 20 пікселів, тоді всі його діти матимуть 100% висоти відносно його висоти.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.