CSS: Como ter posição: div absoluta dentro de uma posição: div relativa não ser cortada por um estouro: oculto em um contêiner

143

Eu tenho 3 níveis de div:

  • (Em verde abaixo) Um nível superior divcom overflow: hidden. Isso ocorre porque eu quero que algum conteúdo (não mostrado aqui) dentro dessa caixa seja cortado se exceder o tamanho da caixa.
  • (Em vermelho abaixo) Dentro disso, eu tenho divcom position: relative. O único uso para isso é para o próximo nível.
  • (Em azul abaixo) Finalmente, diveu retiro o fluxo com o position: absolutequal quero posicionar em relação ao vermelho div(não à página).

Gostaria que a caixa azul fosse retirada do fluxo e expandida além da caixa verde, mas posicionada em relação à caixa vermelha, como em:

No entanto, com o código abaixo, recebo:

E removendo a position: relativecaixa vermelha, agora a caixa azul pode sair da caixa verde, mas não está mais posicionada em relação à caixa vermelha:

Existe uma maneira de:

  • Mantenha o overflow: hiddenna caixa verde.
  • A caixa azul se expandiu além da caixa verde e foi posicionada em relação à caixa vermelha?

A fonte completa:

#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
fonte
44
+1 para o bem formatado questão e código-fonte
GraphicDivine
Esclarecimento: Então, você deseja que a caixa azul (a div mais interna) possa transbordar da caixa verde (a div mais externa), mas mantenha o excesso oculto na caixa verde? Então, basicamente, o estouro oculto em tudo na caixa verde, EXCETO a caixa azul, está certo?
11117 Anthony
Anthony, sim, é exatamente isso. E não me importo com o que acontece com a caixa vermelha (# 2), que existe apenas para influenciar a parte superior / direita da caixa azul (# 3).
11118 avernet
2
+1 por explicar adequadamente uma pergunta que eu achava muito difícil de explicar, mas realmente queria uma resposta.
Andrew Mao
position: fixedirá ignorar o overflow:hiddende qualquer elemento que contenha.
22615 Kevin Beal

Respostas:

48

Um truque que funciona é posicionar a caixa # 2 em position: absolutevez de position: relative. Geralmente, colocamos um position: relativeem uma caixa externa (caixa 2 aqui) quando queremos que uma caixa interna (caixa 3) position: absoluteseja posicionada em relação à caixa externa. Mas lembre-se: para que a caixa nº 3 seja posicionada em relação à caixa nº 2, a caixa nº 2 só precisa ser posicionada. Com essa alteração, obtemos:

E aqui está o código completo com essa alteração:

<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
fonte
5
i realmente utilizados position: statice que funcionou melhor para mim
Jason
@ Jason, muito interessante; então você está dizendo que usa position: staticna caixa 2 em vez de position: absolute.
avernet
1
Você pode explicar por absoluteque não recorta, mas relativerecorta?
Andrew Mao
1
Essa solução não funcionará, a menos que você faça com que tudo entre os itens 1 e 3 seja absoluto. Na prática, isso é impossível.
windmaomao
1
Quer saber o que é o propósito de explicar algo tão visual usando cores assim ...
ed1nh0
5

Não há solução mágica de exibir algo fora de um contêiner oculto.

Um efeito semelhante pode ser obtido com uma div posicionada absoluta que corresponda ao tamanho de seu pai, posicionando-a dentro de seu contêiner relativo atual (a div que você não deseja cortar deve estar fora dessa div):

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

Lembre-se de que, se você precisar apenas recortar o conteúdo no eixo x (que parece ser o seu caso, pois você definiu apenas a largura da div), poderá usá-lo overflow-x: hidden.

torno
fonte
0

Eu realmente não vejo uma maneira de fazer isso como está. Eu acho que você pode precisar remover o overflow:hiddenda div # 1 e adicionar outra div dentro da div # 1 (ou seja, como um irmão da div # 2) para manter o seu 'conteúdo' não especificado e adicionar a overflow:hiddenisso em seu lugar. Não acho que o estouro possa ser (ou deveria ser) substituído.

graphicdivine
fonte
0

Se outro conteúdo não estiver sendo mostrado dentro da div externa (a caixa verde), por que não colocar esse conteúdo dentro de outra div, vamos chamá-lo "content" . Tenha o overflow oculto nesta nova div interna, mas mantenha o overflow visível na caixa verde.

O único problema é que você precisará mexer para garantir que a div de conteúdo não interfira no posicionamento da caixa vermelha, mas parece que você deve consertar isso com pouca dor de cabeça.

<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>
Anthony
fonte