CSS: Comment avoir position: div absolu à l'intérieur d'une position: div relatif ne pas être rogné par un débordement: caché sur un conteneur

144

J'ai 3 niveaux de div:

  • (En vert ci-dessous) Un niveau supérieur divavec overflow: hidden. C'est parce que je veux que du contenu (non montré ici) à l'intérieur de cette boîte soit rogné s'il dépasse la taille de la boîte.
  • (En rouge ci-dessous) À l'intérieur, j'ai divavec position: relative. La seule utilisation pour cela est pour le niveau suivant.
  • (En bleu ci-dessous) Enfin un divje sors du flux avec position: absolutemais que je veux positionner par rapport au rouge div(pas à la page).

J'aimerais que la boîte bleue soit retirée du flux et s'étende au-delà de la boîte verte, mais soit positionnée par rapport à la boîte rouge comme dans:

Cependant, avec le code ci-dessous, j'obtiens:

Et en supprimant le position: relativesur la boîte rouge, maintenant la boîte bleue est autorisée à sortir de la boîte verte, mais n'est plus positionnée par rapport à la boîte rouge:

Existe-t-il un moyen de:

  • Gardez le overflow: hiddensur la boîte verte.
  • La boîte bleue s'est-elle étendue au-delà de la boîte verte et est-elle positionnée par rapport à la boîte rouge?

La source complète:

#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
la source
44
+1 pour une question et un code source bien formatés
graphicdivine
Clarification: Vous voulez donc que la boîte bleue (la div la plus intérieure) puisse déborder de la boîte verte (la div la plus extérieure) mais gardez le débordement caché sur la boîte verte? Donc, fondamentalement, avez un débordement caché sur tout dans la boîte verte SAUF la boîte bleue, est-ce exact?
Anthony
Anthony, oui, c'est exactement ça. Et je me fiche de ce qui arrive à la boîte rouge (n ° 2), qui est juste là pour influencer le haut / à droite de la boîte bleue (n ° 3).
avernet
2
+1 pour avoir correctement expliqué une question que je pensais trop difficile à expliquer mais à laquelle je voulais vraiment une réponse.
Andrew Mao
position: fixedignorera le overflow:hiddende tout élément contenant.
Kevin Beal

Réponses:

48

Une astuce qui fonctionne est de positionner la case n ° 2 avec position: absoluteau lieu de position: relative. Nous mettons généralement un position: relativesur une boîte extérieure (ici la boîte # 2) lorsque nous voulons qu'une boîte intérieure (ici la boîte # 3) position: absolutesoit positionnée par rapport à la boîte extérieure. Mais rappelez-vous: pour que la case n ° 3 soit positionnée par rapport à la case n ° 2, la case n ° 2 doit juste être positionnée. Avec ce changement, nous obtenons:

Et voici le code complet avec ce changement:

<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
la source
5
j'ai utilisé position: staticet cela a mieux fonctionné pour moi
Jason
@Jason, très intéressant; vous dites donc que vous utilisez la position: staticcase n ° 2 au lieu de position: absolute.
avernet
1
Pouvez-vous expliquer pourquoi absolutene coupe pas mais relativefait?
Andrew Mao
1
Cette solution ne fonctionnera pas à moins que vous ne fassiez que tout entre le n ° 1 et le n ° 3 soit absolu. En pratique, cela est impossible.
windmaomao
1
Vous vous demandez quel est le but d'expliquer quelque chose d'aussi visuel en utilisant des couleurs comme ça ...
ed1nh0
5

Il n'y a pas de solution magique pour afficher quelque chose en dehors d'un conteneur caché de débordement.

Un effet similaire peut être obtenu en ayant un div positionné absolu qui correspond à la taille de son parent en le positionnant à l'intérieur de votre conteneur relatif actuel (le div que vous ne souhaitez pas couper doit être en dehors de ce div):

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

N'oubliez pas que si vous n'avez qu'à découper le contenu sur l'axe des x (ce qui semble être votre cas, car vous n'avez défini que la largeur du div), vous pouvez utiliser overflow-x: hidden.

vice
la source
0

Je ne vois pas vraiment de moyen de le faire tel quel. Je pense que vous devrez peut-être supprimer le overflow:hiddende div # 1 et ajouter un autre div dans div # 1 (c'est-à-dire en tant que frère de div # 2) pour contenir votre «contenu» non spécifié et ajouter le overflow:hiddenà la place. Je ne pense pas que le débordement puisse être (ou devrait pouvoir être) surchargé.

graphicdivine
la source
0

S'il y a un autre contenu qui n'est pas affiché à l'intérieur de la div externe (la boîte verte), pourquoi ne pas avoir ce contenu enveloppé dans une autre div, appelons-le "content". Avoir le débordement caché sur ce nouveau div interne, mais garder le débordement visible sur la boîte verte.

Le seul hic, c'est que vous devrez ensuite déconner pour vous assurer que le contenu div n'interfère pas avec le positionnement de la boîte rouge, mais il semble que vous devriez être en mesure de résoudre ce problème avec peu de maux de tête.

<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
la source