CSS: Встановлення ширини / висоти у відсотках мінус пікселів


479

Я намагаюся створити кілька повторно використовуваних CSS-класів для більшої узгодженості та менше захаращеності на своєму сайті, і я застряг у спробі стандартизувати одне, що часто використовую.

У мене є контейнер, для <div>якого я не хочу встановлювати висоту (тому що він буде змінюватися залежно від того, де на сайті він знаходиться), а всередині нього - заголовок <div>, а потім не упорядкований список елементів, усі з CSS, застосованими до їх.

Це виглядає приблизно так:

Віджет

Я хочу , щоб невпорядкований список , щоб зайняти залишилася кімнату в контейнері <div>, знаючи , що заголовок <div>є 18pxвисоким. Я просто не знаю, як вказати висоту списку як "результат 100%мінусу 18px".

Я бачив це запитання у кількох інших контекстах на SO, але я подумав, що варто було б запитати ще раз для мого конкретного випадку. Хтось має поради в цій ситуації?


6
Встановити маржу? __
kennytm

@KennyTM, я припускаю, що ви пропонуєте поставити маржинальний верх на мій не упорядкований список, скажімо, 17 пікселів. Але це просто відсуває весь список вниз; це не змушує його утримуватися в контейнері. По суті, поточна висота підтримується, але вона просто натискається на 17 пікселів. Це не вирішує мою проблему, але я думаю, що це крок у правильному напрямку, оскільки я бачив інші підходи в Інтернеті, які використовували цю методику.
MegaMatt

Я просто вирішив це питання у своєму питанні, яке я розмістив тут. stackoverflow.com/a/10420387/340947
Стівен Лу

Відповіді:


895

Я розумію, що це стара публікація, але, враховуючи, що не було запропоновано, варто згадати, що якщо ви пишете для браузерів, сумісних з CSS3, ви можете використовувати calc:

height: calc(100% - 18px);

Варто зазначити, що в даний час не всі браузери підтримують стандартну CSS3 функцію calc (), тому реалізація конкретних для браузера версій функції може знадобитися на зразок наступних:

/* Firefox */
height: -moz-calc(100% - 18px);
/* WebKit */
height: -webkit-calc(100% - 18px);
/* Opera */
height: -o-calc(100% - 18px);
/* Standard */
height: calc(100% - 18px);

5
Так, це нормально на даний момент.
Levi Botelho

1
Працює для мене в IE10 та Chrome 27. Ви, мій пан, ви мій вигадливий герой!
BrainSlugs83

3
@LeviBotelho Мій поганий. Не було місця навколо оператора.
користувач

20
Крім того, якщо ви використовуєте Менше, вам краще скомпілювати файл, lessc --strict-math=onщоб менше не оцінювати вираз всередині calc- просто проблема, з якою я зіткнувся і витратив багато часу (станом на менше 2.0.0)
Дмитро Войцеховський

34
Зверніть увагу , що прогалини навколо знака мінус не є додатковими: 100%-18px, 100%- 18pxі 100% -18pxне працює в браузерах я тестував с.
нісетама

71

Для трохи іншого підходу ви можете використати щось подібне у списку:

position: absolute;
top: 18px;
bottom: 0px;
width: 100%;

Це працює доти, доки має батьківський контейнер position: relative;


1
дякую людині. батьківський контейнер, що position: relative;мене відштовхує.
gthmb

Для тих, хто може дивуватись як я: положення повинно бути absoluteв дитячому контейнері, такого не може бути relative.
Грег

Продовження (вибачте): Однак батько просто потребує позиціонування (це absoluteтеж може бути ), і його також потрібно встановити на 100% висоти.
Грег

1
На жаль, він не працює на Safari iOS 8. (Тестовано ОК на Android 4.1 браузері та стандартному FF 34) :-(
Грег

Це може спрацювати в деяких випадках, але також може спричинити деякі проблеми, оскільки абсолютно розташовані елементи видаляються із звичайного потоку, див. Stackoverflow.com/a/12821537/4173303 .
Крістоф Вайс

26

Для цього я використовую Jquery

function setSizes() {
   var containerHeight = $("#listContainer").height();
   $("#myList").height(containerHeight - 18);
}

то я прив'язую розмір вікна до його повторного зміни кожного разу, коли розмір вікна веб-переглядача змінюється (якщо розмір контейнера змінювався на розмір вікна)

$(window).resize(function() { setSizes(); });

12
@puffpio, Безумовно, JS - це спосіб досягти цього в кожному конкретному випадку. Але, як я вже говорив, я намагаюсь зробити загальний CSS, який застосовуватимуться на декількох сторінках (це, до речі, успадковується з головної сторінки). Тому я вважаю за краще не використовувати JS. Але дякую за відповідь.
MegaMatt

7
Не ставте свій стиль всередині JavaScript.
Грег

8
@greg, добре, це допомогло б, якщо у CSS були ще кілька корисних функцій. Деякі речі, з яких потрібно робити хакі, смішні.
Джонатан.

1
@puffpio Приємне рішення. Але прив'язка подій у вікні не є гарним рішенням для мене. Якщо на моїй сторінці є 3-4 або більше таких елементів, я повинен оновити висоту та ширину кожного елемента в обробці розміру вікон. Це буде трохи повільніше, ніж рішення CSS.
sachinjain024

1
"Не ставте свій xyz в JavaScript" - це як сказати "не підтримуйте 80% ринку браузера".
Beejor

16

Не визначайте висоту у відсотках, просто встановіть top=0та bottom=0, як це:

#div {
   top: 0; bottom: 0;
   position: absolute;
   width: 100%;
}

Чи можете ви пояснити, чому б не встановити висоту на відсоток?
Шрікант Шарат

@ShrikantSharat Це частина специфікації візуального форматування для абсолютно розташованих елементів. Це рішення використовує можливість 5. "," висота "є" авто "," верх "і" знизу "не є" авто ", тоді встановлюються значення" авто "для" margin-top "і" margin-bottom ". до 0 і вирішити для 'висоти' ". Веб-переглядач може обчислити висоту елемента, оскільки він знає, наскільки далеко від верхньої та нижньої частини його батьківщини це повинно бути.
Росс Аллен

Схоже, це не працює, принаймні, у Firefox. Навіть із усіма батьківськими елементами, встановленими на height:100%та display:block. Інакше це було б дуже елегантне рішення. Цікаво, що margin:autoтакож не вдається центрувати об’єкт фіксованої ширини вертикально, хоча він працює добре в горизонтальному напрямку.
Beejor

8

Імовірна висота заголовка 17 пікселів

Список css:

height: 100%;
padding-top: 17px;

Css заголовка:

height: 17px;
float: left;
width: 100%;

Так, саме в це я потрапляв.
dclowd9901

1
Це не спрацювало так добре, як я сподівався. Мій не упорядкований список запускається під цим заголовком. Заголовок діва займає простір у контейнері, тому додавання padding-top 17px до списку просто збирається натиснути його вниз 17px з того місця, де вже є на малюнку вище, а не 17px зверху контейнера div. Ось малюнок того, що я отримую з CSS, наведеним у відповіді вище: i41.tinypic.com/mcuk1x.jpg . Я ціную ці зусилля, і якщо ви щось думаєте, що я пропускаю, будь ласка, повідомте мене про це. До речі, у мене є переповнення: автоматично і в неупорядкованому списку.
MegaMatt

2
Це було б набагато простіше усунути неполадки, якби ви опублікували фактичний css, щоб ми могли точно побачити, що відбувається. Ще одна річ, яку ви можете спробувати, це негативна максимальна націнка на ваш ul. ul { margin-top: -17px; }
ghoppe

7
  1. Використовуйте негативні поля на елементі, який ви хочете відключити до мінус пікселів. (бажаний елемент)
  2. Складіть overflow:hidden;на містить елемент
  3. Увімкніть overflow:auto;потрібний елемент.

Це працювало для мене!


3
Це спрацювало як шарм для мене (мені навіть не потрібно було змінювати переповнення). Чудове рішення, дякую!
Aaj

1
Цілком дивовижно! Насолоджувався ознайомленням із популярним рішенням «CSS calc», але це набагато простіше і має більш широку підтримку браузера. Негативні маржі в ідеалі!
Саймон Штейнбергер

Це дуже елегантне та сумісне рішення. Основний мінус полягає в тому, що елемент повинен мати фіксовану висоту. В іншому випадку вам потрібно буде використовувати JS або calc()централізувати його під час виконання. Але для багатьох випадків це не повинно бути проблемою. Інша річ, яку слід пам’ятати, - це те, що використання безлічі від’ємних значень для поля, прокладки та компенсації може спричинити плутанину при налагодженні коду пізніше, тому постарайтеся, щоб все було просто.
Beejor

5

Спробуйте встановити розміри коробки. Для списку:

height: 100%;
/* Presuming 10px header height */
padding-top: 10px;
/* Firefox */
-moz-box-sizing: border-box;
/* WebKit */
-webkit-box-sizing: border-box;
/* Standard */
box-sizing: border-box;

Для заголовка:

position: absolute;
left: 0;
top: 0;
height: 10px;

Звичайно, батьківський контейнер повинен мати щось на зразок:

position: relative;

3

Ще один спосіб досягти тієї ж мети: гнучкі коробки . Зробіть контейнер стовпчиком з гнучким стовпцем, і тоді ви маєте всю свободу дозволити деяким елементам мати фіксований розмір (поведінка за замовчуванням) або заповнювати / стискати до простору контейнера (з flex-зростання: 1 і flex- скорочення: 1).

#wrap {        
  display:flex;
  flex-direction:column;
}
.extendOrShrink {
  flex-shrink:1;
  flex-grow:1;
  overflow:auto;
}

Дивіться https://jsfiddle.net/2Lmodwxk/ (спробуйте розширити чи зменшити вікно, щоб помітити ефект)

Примітка. Ви також можете використовувати властивість скорочення:

   flex:1 1 auto;

Я вважаю, що це може бути найкращою відповіддю сьогодні, оскільки це означає, що не потрібно вказувати задану висоту для заголовка div (18px в моєму первісному запитанні), а це означає, що не потрібно віднімати такі речі, як padding та margin. Не встановлено пікселів, і все подбає про себе.
MegaMatt

2

Я спробував деякі інші відповіді, і жодна з них не працювала так, як я хотіла. Наша ситуація була дуже схожа, коли у нас був заголовок вікна, і вікно було змінено з розмірами зображень у корпусі вікна. Ми хотіли заблокувати співвідношення сторін зміни розміру, не потребуючи додавання в обчислення, щоб врахувати фіксований розмір заголовка і все-таки зображення заповнити тіло вікна.

Нижче я створив дуже простий фрагмент, який показує, що ми закінчили, що, здається, працює добре для нашої ситуації і має бути сумісним у більшості браузерів.

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

*,*:before,*:after
{
  box-sizing: border-box;
}

.window
{
  position: relative;
  top: 20px;
  left: 50px;
  margin-top: 20px;
  width: 150px;
  height: 150px;
}

.window-header
{
  position: absolute;
  top: -20px;
  height: 20px;
  border: 2px solid black;
  width: 100%;
}

ul
{
  border: 5px dashed gray;
  height: 100%;
}
<div class="window">
  <div class="window-header">Hey this is a header</div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
  </ul>
</div>


1

Дякую, я вирішив мою з вашою допомогою, трохи підкоригувавши її, оскільки я хочу дів 100% ширини 100% висоти (менша висота нижньої смуги) і без прокрутки на корпусі (без злому / ховання смуг прокрутки).

Для CSS:

 html{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 body{
  position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }
 div.adjusted{
  position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px;
 }
 div.the_bottom_bar{
  width:100%;height:31px;margin:0px;border:0px;padding:0px;
}

Для HTML:

<body>
<div class="adjusted">
 // My elements that go on dynamic size area
 <div class="the_bottom_bar">
  // My elements that goes on bottom bar (fixed heigh of 31 pixels)
 </div>  
</div>  

Це зробило трюк, о так, я поставив значення, дещо більше, на div.adjucted для нижнього, ніж для висоти нижньої смуги, інакше з'явиться вертикальна смуга прокрутки, я скоригований як найближче значення.

Ця різниця полягає в тому, що один з елементів динамічної області додає додатковий нижній отвір, якого я не знаю, як позбутися ... це відеотег (HTML5), будь ласка, зверніть увагу, що я помістив цей відеотег із цим css ( тому немає ніяких причин для того, щоб зробити нижній отвір, але це є):

 video{
  width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

Об'єктив: Майте відео, яке займає 100% веб-переглядача (і динамічно змінюється, коли розмір браузера змінюється, але не змінюючи співвідношення сторін), менший простір внизу, який я використовую для діва з деякими текстами, кнопками тощо (та валідаторами) w3c & css звичайно).

EDIT: Я знайшов причину, відеотег схожий на текст, а не на блоковий елемент, тому я виправив це за допомогою цього css:

 video{
  display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px;
 }

Зверніть увагу display:block;на тег відео.


0

Я не впевнений, чи спрацює це у вашій конкретній ситуації, але я виявив, що накладка на внутрішньому діві підштовхне вміст всередині діла, якщо містить div фіксований розмір. Вам доведеться або плавати, або абсолютно розміщувати елемент заголовка, але в іншому випадку я не пробував цього для дівок змінного розміру.

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