Зробіть, щоб div (зріст) займав батьківський залишок висоти


107

http://jsfiddle.net/S8g4E/

У мене є контейнер divз двома дітьми. Перша дитина має заданий зріст. Як я можу змусити другу дитину зайняти «вільний простір» контейнера, divне надаючи конкретної висоти?

У прикладі рожевий divповинен займати також білий простір.


Подібно до цього питання: Як змусити діву займати залишився висоту?

Але я не хочу давати позицію абсолютною .


Я спробував als дати другому зросту дитині 100%, але не працює: jsfiddle.net/S8g4E/1
Альваро

Відповіді:


156

Розширення #downдитини для заповнення залишкового простору #containerможе здійснюватися різними способами залежно від підтримки браузера, яку ви хочете досягти, і від того, чи #upмає певну висоту.

Зразки

Сітка

gridМакет CSS пропонує ще один варіант, хоча він може бути не таким простим, як модель Flexbox. Однак вимагає лише стилізації елемента контейнера:

.container { display: grid; grid-template-rows: 100px }

grid-template-rowsВизначає перший рядок в якості фіксованої 100px висоти, і залишаються рядки будуть автоматично розтягуватися , щоб заповнити простір, що залишився.

Я впевнений, що IE11 вимагає -ms-префіксів, тому переконайтесь, що перевірити функціональність у веб-переглядачах, які ви хочете підтримувати.

Flexbox

Модуль гнучкої компоновки модуляflexbox CSS3 ( ) зараз добре підтримується і може бути дуже простим у виконанні. Оскільки він гнучкий, він працює навіть тоді, коли #upне має визначеної висоти.

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

Важливо зауважити, що підтримка IE10 та IE11 для деяких властивостей flexbox може бути помилковою, а IE9 або нижче не має жодної підтримки.

Розрахована висота

Ще одне просте рішення - використовувати функціональний блок CSS3calc , як вказує Альваро у своїй відповіді , але для цього потрібно, щоб висота першої дитини була відомою цінністю:

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

Він досить широко підтримується, єдиними помітними винятками є <= IE8 або Safari 5 (відсутність підтримки) та IE9 (часткова підтримка). Деякі інші проблеми включають використання calc у поєднанні з трансформацією або полем-тінню , тому не забудьте протестувати в декількох браузерах, якщо це стосується вас.

Інші альтернативи

Якщо потрібна підтримка старшого віку, ви можете додати, height:100%;щоб #downзробити рожевий дів на повний зріст, з одним застереженням. Це призведе до переповнення контейнера, тому що #upштовхає його вниз.

Тому ви можете додати overflow: hidden;його до контейнера, щоб виправити це.

Крім того, якщо висота #upфіксована, ви можете розмістити її абсолютно в контейнері і додати набивний верх #down.

І ще одним варіантом буде використання дисплея таблиці:

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

4
Я хотів би, щоб у #down була висота #container - #up висота. Так що переповнення приховано - це не те, що я шукаю. А також не хочу використовувати абсолютну позицію. Дякую!
Альваро

@Alvaro, я додав ще один варіант, використовуючи дисплеї таблиць. Недоліком тут є сумісність. PS Елемент, розташований абсолютно всередині контейнера, position: relative;розташовуючи його відносно контейнера, а не вікна. Отже, це має бути життєздатним варіантом.
користувач

2
Табличний рядок повинен працювати для вас, див. Цей jsFiddle для доказу. Метод абсолютної позиції не зможе отримати ті ж результати, що і ця скрипка, тому ми можемо викреслити це зі списку (#down та #container матимуть однакову висоту в цьому сценарії).
користувач

3
Ви багато просите, @Alvaro. CSS - це не сценарій мови; він не може обчислити речі. Ви застрягли або з ілюзіями, або з js.
Єзен Томас

1
@Quantastical, дякую за допомогу, але в останній редакції ви просто скопіювали відповідь, яку я опублікував. Деякі згадки про це, принаймні, було б непогано.
Альваро

24

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

http://jsfiddle.net/S8g4E/955/

Ось css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

І більше інформації про це тут: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Підтримка веб-переглядачів: http://caniuse.com/#feat=calc


1
Я теж використовував CSS3, calcде широка підтримка браузера не так важлива (IE8 і нижче, а Safari 5 не підтримує його).
користувач

3
Будь-який спосіб зробити подібне з динамічною #upвисотою?
Адам Уейт

@AdamWaite, з динамічною висотою #up, ви хочете використовувати рішення переливу, описане в іншій відповіді.
користувач

5

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

html

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

css

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; height: 63px; float:left; width: 100% }
#down { background:pink; padding-top: 63px; height: 100%; box-sizing: border-box; }

http://jsfiddle.net/S8g4E/288/


2

перевірити демонстрацію - http://jsfiddle.net/S8g4E/6/

використовувати css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}

Ви повинні додати, height: 1pxщоб #upпереконатися, що вона займає мінімальну висоту. Ось підтримка браузера для display: table: caniuse.com/css-table
thirtydot

Скажіть, будь ласка, як можна досягти цього рішення на цьому "більш складному" прикладі, будь ласка: jsfiddle.net/fyNX4 Дуже дякую
Альваро

2

Якщо мене не непорозуміння, ви можете просто додати height: 100%;і overflow:hidden;до #down.

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

Live DEMO

Редагувати: оскільки ви не хочете використовувати overflow:hidden;, ви можете використовувати display: table;для цього сценарій; однак він не підтримується до IE 8. ( display: table;підтримка )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

Live DEMO

Примітка. Ви сказали, що хочете, щоб #downвисота була #containerвисотою мінус #upвисотою. display:table;Рішення робить саме те, що і це jsfiddle буде зображувати , що досить ясно.


1
Я не хочу, щоб #down перевищував висоту #container
Альваро

Я щойно це помітив. Ви можете додати, overflow:hiddenщоб приховати додатковий вміст.
Джош Мейн

1
Я скопіюю / вставте те, що я сказав для MrSlayer: Я хотів би, щоб у #down була висота #container - #up висота. Так що переповнення приховано - це не те, що я шукаю. А також не хочу використовувати абсолютну позицію. Дякую!
Альваро

Проблема в цьому полягає в тому, що якщо ви повернете два діви у своєму прикладі, то зелений дів знаходиться поза.
Ced

Це зовсім не відповідає на питання. У ньому зазначено "Зайняти всю висоту, що залишилася", якщо ця подія займає всю решту висоти, буде переповнення.
Гіріджар Карник

2

Анотація

Я не знайшов повністю задоволеної відповіді, тому мені довелося сам її з’ясувати.

Мої вимоги:

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

Рішення

  • Перетворіть у флексі всі прямі батьки з обчисленою висотою (якщо такі є) та наступний батько, висота якого вказана ;
  • Вкажіть flex-grow: 1для всіх прямих батьків з обчисленої висоти (якщо такі є) і елемент , таким чином вони будуть займати все залишився , коли розмір утримання елемента менше;
  • Вкажіть flex-shrink: 0для всіх гнучких елементів з фіксованою висотою , щоб вони не стануть менше , якщо розмір вмісту елемента більше , ніж решти розмір простору;
  • Вкажіть overflow: hiddenдля всіх прямих батьків з обчисленої висоти (якщо такі є) , щоб відключити скролінг і заборонити відображення вмісту переповнення;
  • Вказівка overflow: autoна елемент , щоб включити прокрутку всередині нього.

JSFiddle (елемент має прямих батьків з обчисленою висотою)

JSFiddle (простий випадок: немає прямих батьків з обчисленою висотою)


1

Ви можете використовувати поплавці для натискання вмісту вниз:

http://jsfiddle.net/S8g4E/5/

У вас є контейнер із фіксованим розміром:

#container {
    width: 300px; height: 300px;
}

Вміст дозволяється текти поруч із поплавком. Якщо ми не встановимо поплавок на повну ширину:

#up {
    float: left;
    width: 100%;
}

Поки #upі #downділити верхню позицію, #downвміст може починатися лише після того, як нижня частина плаває #up:

#down {
    height:100%;
}​

Зауважте, що #upнасправді охоплює верхню частину #down: jsfiddle.net/thirtydot/S8g4E/9
тридцятьдесят

Так, це працює. Але якщо ОП не потрібна округлена межа або щось інше #up, то це, мабуть, прийнятно.
biziclop

Це рішення близьке, але я хотів би, щоб у #down була висота #container - #up висота. (У вашому рішенні #down height = #container height). Дякую '
Альваро

1
@Alvaro: Чому це потрібно бути таким? Це рішення виглядає правильним у більшості випадків, навіть якщо це лише ілюзія.
тридцятьдот

Ну, це питання є спрощеним прикладом із цього більш "складного" прикладу: jsfiddle.net/fyNX4 Не працювало б, ні?
Альваро

-3

Я не впевнений, що це можна зробити виключно за допомогою CSS, якщо тільки вам не зручно підробляти це ілюзіями. Можливо, скористайтеся відповіддю Джоша Мена та встановіть #containerна overflow:hidden.

Для чого це варто, ось рішення jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);

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