CSS: Как получить позицию: абсолютный div внутри позиции: относительный div не должен быть обрезан переполнением: скрыт в контейнере

144

У меня есть 3 уровня div:

  • (Зеленым цветом внизу) Верхний уровень divс overflow: hidden. Это потому, что я хочу, чтобы некоторый контент (не показанный здесь) внутри этого блока был обрезан, если он превышает размер блока.
  • (Красным внизу) Внутри у меня есть divс position: relative. Единственное использование для этого для следующего уровня.
  • (Выделено синим цветом ниже) Наконец-то divя вынимаю из потока, position: absoluteно хочу, чтобы он располагался относительно красного div(а не на странице).

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

Тем не менее, с кодом ниже, я получаю:

И, удалив position: relativeкрасный флажок, теперь синий прямоугольник может выйти из зеленого прямоугольника, но больше не позиционируется относительно красного прямоугольника:

Есть ли способ:

  • Держите overflow: hiddenна зеленой коробке.
  • Расширилось ли синее поле за зеленое поле и будет ли оно расположено относительно красного поля?

Полный источник:

#d1 {
  overflow: hidden;
  background: #efe;
  padding: 5px;
  width: 125px;
}

#d2 {
  position: relative;
  background: #fee;
  padding: 2px;
  width: 100px;
  height: 100px;
}

#d3 {
  position: absolute;
  top: 10px;
  background: #eef;
  padding: 2px;
  width: 75px;
  height: 150px;
}
<br/><br/><br/>
<div id="d1" >
  <div id="d2" >
    <div id="d3"></div>
  </div>
</div>

avernet
источник
44
+1 за хорошо отформатированный вопрос и исходный код
graphicdivine
Пояснение: То есть вы хотите, чтобы синий прямоугольник (самый внутренний элемент Div) мог переполняться из зеленого прямоугольника (самый внешний элемент Div), но при этом скрыть переполнение в зеленом блоке? Итак, в основном, переполнение скрыто на всем в зеленом поле, кроме синего поля, это верно?
Энтони,
Энтони, да, это именно так. И мне все равно, что происходит с красной рамкой (# 2), которая как раз там влияет на верхнюю / правую часть синей рамки (# 3).
Авернет
2
+1 за правильное объяснение вопроса, который я считал слишком сложным, но на самом деле хотел получить ответ.
Эндрю Мао
position: fixedбудет игнорировать overflow:hiddenлюбой содержащий элемент.
Кевин Бил

Ответы:

48

Уловка, которая работает, состоит в том, чтобы поместить поле № 2 position: absoluteвместо position: relative. Обычно мы помещаем position: relativeвнешний блок (здесь блок № 2), когда хотим, чтобы внутренний блок (здесь блок № 3) position: absoluteрасполагался относительно внешнего блока. Но помните: для блока № 3 нужно расположить относительно блока № 2, блок № 2 просто необходимо позиционировать. С этим изменением мы получаем:

И вот полный код с этим изменением:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <style type="text/css">

            /* Positioning */
            #box1 { overflow: hidden }
            #box2 { position: absolute }
            #box3 { position: absolute; top: 10px }

            /* Styling */
            #box1 { background: #efe; padding: 5px; width: 125px }
            #box2 { background: #fee; padding: 2px; width: 100px; height: 100px }
            #box3 { background: #eef; padding: 2px; width: 75px; height: 150px }

        </style>
    </head>
    <body>
        <br/><br/><br/>
        <div id="box1">
            <div id="box2">
                <div id="box3"/>
            </div>
        </div>
    </body>
</html>
avernet
источник
5
Я фактически использовал, position: staticи это работало лучше для меня
Джейсон
@ Джейсон, очень интересно; так что вы говорите, что вы используете position: staticна поле № 2 вместо position: absolute.
авернет
1
Можете ли вы объяснить, почему absoluteне обрезает, но relativeделает?
Эндрю Мао
1
Это решение не будет работать, если вы не сделаете все между # 1 и # 3 абсолютными. На практике это невозможно.
windmaomao
1
Хотите знать, какова цель, чтобы объяснить что-то
настолько
5

Не существует волшебного решения для отображения чего-либо за пределами скрытого контейнера.

Подобный эффект может быть достигнут, если иметь абсолютный позиционированный div, который соответствует размеру его родителя, поместив его внутри вашего текущего относительного контейнера (div, который вы не хотите обрезать, должен находиться вне этого div):

#1 .mask {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1;
  overflow: hidden;
}

Имейте в виду, что если вам нужно только обрезать содержимое по оси x (что, по-видимому, соответствует вашему случаю, поскольку вы только установили ширину div), вы можете использовать overflow-x: hidden.

тиски
источник
0

Я действительно не вижу способа сделать это как есть. Я думаю, что вам может понадобиться удалить overflow:hiddenиз div # 1 и добавить еще один div в div # 1 (то есть, как родственный элемент для div # 2), чтобы удерживать ваше неуказанное «содержимое» и overflow:hiddenвместо этого добавить к нему. Я не думаю, что переполнение может быть (или должно быть) переопределенным.

graphicdivine
источник
0

Если внутри внешнего элемента div (зеленого поля) не отображается другое содержимое, почему бы не поместить это содержимое в другой элемент div, давайте назовем его "content". Переполнение скрыто в этом новом внутреннем div-элементе, но его переполнение должно отображаться в зеленом поле.

Единственная загвоздка в том, что вам придется возиться, чтобы убедиться, что div содержимого не мешает расположению красной рамки, но, похоже, вы сможете исправить это с небольшой головной болью.

<div id="1" background: #efe; padding: 5px; width: 125px">
    <div id="content" style="overflow: hidden;">
    </div>
    <div id="2" style="position: relative; background: #fee; padding: 2px; width: 100px; height: 100px">
        <div id="3" style="position: absolute; top: 10px; background: #eef; padding: 2px; width: 75px; height: 150px"/>
    </div>
</div>
Энтони
источник