Позиція: абсолютна та батьківська висота?


100

У мене є кілька контейнерів, а їхні діти мають лише абсолютне / відносне розташування. Як встановити висоту контейнерів, щоб їх діти знаходилися всередині них?

Ось код:

HTML

<section id="foo">
    <header>Foo</header>
    <article>
        <div class="one"></div>
        <div class="two"></div>
    </article>
</section>    

<div style="clear:both">Clear won't do.</div>
<!-- I want to have a gap between sections here -->

<section id="bar">
    <header>bar</header>
    <article>
        <div class="one"></div><div></div>
        <div class="two"></div>
    </article>
</section>  

CSS

article {
    position: relative;
}

.one {
    position: absolute;
    top: 10px;
    left: 10px;
    background: red;
    width: 30px;
    height: 30px;
}

.two {
    position: absolute;
    top: 10px;
    right: 10px;
    background: blue;
    width: 30px;
    height: 30px;
}

Ось jsfiddle. Я хочу, щоб текст "бар" відображався між 4 квадратами, а не позаду них.

http://jsfiddle.net/Ht9Qy/

Якісь прості виправлення?

Зверніть увагу, що я не знаю висоти цих дітей, і я не можу встановити висоту: xxx для контейнерів.


Відповіді:


86

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

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

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

В якості альтернативи, просто використовуйте float: left/ float:rightта поля, щоб отримати однаковий ефект позиціонування, зберігаючи overflow: hiddenдочірні елементи в документообігу, а потім можна використовувати на батьківському (або будь-якому іншому методі чіткого виправлення), щоб збільшити його висоту до висоти її дочірніх.

article {
    position: relative;
    overflow: hidden;
}

.one {
    position: relative;
    float: left;
    margin-top: 10px;
    margin-left: 10px;
    background: red;
    width: 30px;
    height: 30px;
}

.two {
    position: relative;
    float: right;
    margin-top: 10px;
    margin-right: 10px;
    background: blue;
    width: 30px;
    height: 30px;
}

Для тих, хто тут спотикається, намагається зрозуміти, чому ваше поле зліва: -16px & overflow: hidden фокус не працює. Я не брав до уваги, що у мене також було правильне заповнення, тому мені потрібно було право на поле: -16px. Також я використовував ширину: 100vw для контейнера, не знаю, якщо потрібно.
TeemuK

24

Ось моє обхідне рішення.
У вашому прикладі ви можете додати третій елемент із "однаковими стилями" елементів .one & .two, але без абсолютного положення та з прихованою видимістю:

HTML

<article>
   <div class="one"></div>
   <div class="two"></div>
   <div class="three"></div>
</article>

CSS

.three{
    height: 30px;
    z-index: -1;
    visibility: hidden;
}

6
яка геніальна ідея!
Oh Chin Boon

Класний обхідний шлях, я майже збирався почати писати сценарій. Дякую.
JoSch

4

Це пізня відповідь, але, подивившись на вихідний код, я помітив, що коли відео є повноекранним, клас "mejs-container-fullscreen" додається до елемента "mejs-container". Таким чином, можна змінити стиль на основі цього класу.

.mejs-container.mejs-container-fullscreen {
    // This rule applies only to the container when in fullscreen
    padding-top: 57%;
}

Крім того, якщо ви хочете зробити свій флюїд MediaElement за допомогою CSS, нижче наведено чудовий фокус Кріса Койєра: http://css-tricks.com/rundown-of-handling-f гибкий-media/

Просто додайте це у свій CSS:

.mejs-container {
    width: 100% !important;
    height: auto !important;
    padding-top: 57%;
}
.mejs-overlay, .mejs-poster {
    width: 100% !important;
    height: 100% !important;
}
.mejs-mediaelement video {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    width: 100% !important;
    height: 100% !important;
}

Сподіваюся, це допоможе.


0

Цю проблему макета можна вирішити за допомогою flexbox зараз, уникаючи необхідності знати висоти або контролювати макет з абсолютним позиціонуванням або плаваючою точкою. Основним питанням OP було те, як змусити батьків утримувати дітей невідомого зросту, і вони хотіли це зробити в межах певного плану. Це робить установка висоти батьківського контейнера на "fit-content"; використання "display: flex" та "justify-content: space-between" створює макет розділу / стовпця, я думаю, що OP намагався створити.

<section id="foo">
    <header>Foo</header>
    <article>
        <div class="main one"></div>
        <div class="main two"></div>
    </article>
</section>    

<div style="clear:both">Clear won't do.</div>

<section id="bar">
    <header>bar</header>
    <article>
        <div class="main one"></div><div></div>
        <div class="main two"></div>
    </article>
</section> 

* { text-align: center; }
article {
    height: fit-content ;
    display: flex;
    justify-content: space-between;
    background: whitesmoke;
}
article div { 
    background: yellow;     
    margin:20px;
    width: 30px;
    height: 30px;
    }

.one {
    background: red;
}

.two {
    background: blue;
}

Я змінив скрипту OP: http://jsfiddle.net/taL4s9fj/

css-трюки на flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


-17

Це ще одна пізня відповідь, але я зрозумів досить простий спосіб розміщення тексту "бар" між чотирма квадратами. Ось зміни, які я вніс; У розділі рядка я загорнув текст "бар" у центр та теги div.

<header><center><div class="bar">bar</div></center></header>

А в розділі CSS я створив клас "bar", який використовується в тезі div вище. Після додавання цього текст рядка знаходився по центру між чотирма кольоровими блоками.

.bar{
    position: relative;
}

20
Не використовуйте <center>! Це застаріло.
Ян Девлін,

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