web-dev-qa-db-fra.com

CSS: display: inline-block et positionnement: absolu

Veuillez considérer le code suivant:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <style type="text/css">
        .section {
            display: block;
            width: 200px;
            border: 1px dashed blue;
            margin-bottom: 10px;
        }
        .element-left,
        .element-right-a,
        .element-right-b {
            display: inline-block;
            background-color: #ccc;
            vertical-align: top;
        }
        .element-right-a,
        .element-right-b {
            max-width: 100px;
        }
        .element-right-b {
            position: absolute;
            left: 100px;
        }
    </style>
    <title>test</title>
</head>
<body>
    <div class="section">
        <span class="element-left">some text</span>
        <span class="element-right-a">some text</span>
    </div>
    <div class="section">
        <span class="element-left">some text</span>
        <span class="element-right-a">some more text to force line wrapping</span>
    </div>
    <div class="section">
        <span class="element-left">some text</span>
        <span class="element-right-b">some text</span>
    </div>
    <div class="section">
        <span class="element-left">some text</span>
        <span class="element-right-b">some more text to force line wrapping</span>
    </div>
    <div class="section">
        <span class="element-left">some text</span>
        <span class="element-right-b">some more text to force line wrapping</span>
    </div>
</body>
</html>

L'élément de positionnement absolu fait apparemment apparaître dans la boîte contenant "la hauteur" dont il a besoin.

J'ai besoin du positionnement absolu dans la boîte "section", existe-t-il une autre solution à cela?

merci d'avance, geronimo

modifier

Utiliser des tables n’est pas vraiment une option, j’ai besoin d’une sorte de layout "multi-niveaux"/"imbriqué", où le second col est toujours à la même position:

 du texte dans la première colonne | du texte dans la 2e colonne 
 | du texte en retrait | 2ème colonne 
 | également en retrait | 2ème col 
 | encore plus indent | 2ème colonne avec beaucoup de texte que 
 | le rend enveloppant 
 | texte | ...
 | bla bla | ...

(bien sûr sans les "|" s)

28
geronimo

Lorsque vous utilisez position:absolute;, l'élément est retiré du flux de page normal. Par conséquent, cela n'affecte plus la présentation de son élément conteneur. Ainsi, l'élément conteneur ne prend pas en compte sa hauteur. Par conséquent, s'il n'y a rien d'autre pour définir la hauteur, le conteneur aura une hauteur nulle.

De plus, définir display:inline-block; n'a aucun sens pour un élément qui est position:absolute;. Encore une fois, cela est dû au fait que le positionnement absolu retire l'élément du flux de page. Ceci est en contradiction avec inline-block, qui n'existe que pour affecter la manière dont l'élément s'insère dans le flux de page. Tous les éléments qui sont position:absolute; sont automatiquement traités en tant que display:block, car il s'agit du seul mode d'affichage logique pour le positionnement absolu.

Si vous avez besoin un positionnement absolu, la seule solution à votre problème de hauteur consiste à définir la hauteur de la boîte.

Cependant, je suppose que vous pourriez vous passer du positionnement absolu.

Il semblerait que vous essayiez de placer le deuxième <span> de chaque bloc à une position fixe dans le bloc, de manière à ce qu'ils s'alignent.

C'est un problème de CSS classique. Dans le "mauvais vieux temps", les concepteurs Web l'auraient fait en utilisant un tableau, avec des largeurs fixes sur les cellules du tableau. Ce n’est évidemment pas la solution pour les concepteurs Web d’aujourd’hui, mais c’est quelque chose qui soulève de nombreuses questions.

Il y a plusieurs façons de le faire en utilisant CSS.

Le plus simple est de définir les deux éléments <span> sur display:inline-block; et de leur attribuer une largeur fixe.

par exemple:

<div class='section'>
    <span class="element-left">some text</span>
    <span class="element-right">some text</span>
</div>

avec le CSS suivant:

.section span  {display:inline-block;}
.element-left  {width:200px;}
.element-right {width:150px;}

[EDIT] après la mise à jour de la question

Voici comment je réaliserais ce que vous demandez maintenant:

<div class='section'>
    <span class="element-left"><span class='indent-0'>some text</span></span>
    <span class="element-right">some text</span>
</div>
<div class='section'>
    <span class="element-left"><span class='indent-1'>some text</span></span>
    <span class="element-right">some text</span>
</div>
<div class='section'>
    <span class="element-left"><span class='indent-2'>some text</span></span>
    <span class="element-right">some text</span>
</div>

avec le CSS suivant:

.section span  {display:inline-block;}
.element-left  {width:200px;}
.indent-1 {padding:10px;}
.indent-2 {padding:20px;}
.element-right {width:150px;}

Une petite quantité de balisage supplémentaire, mais elle produit l'effet que vous souhaitez.

51
Spudley

Non.

Vous pouvez absolument positionner alors une copie de l'élément dans la zone de section avec visible: none, mais le positionnement absolu en fait un élément "flottant" qui n'interagit pas avec les éléments situés au-dessus de celui-ci.

En supposant que votre mise en page soit corrigée, vous pouvez utiliser padding-left: #px; pour atteindre votre objectif, car je ne pense pas que le positionnement relatif soit ce que vous voulez.

Vous pouvez également utiliser display: table-* pour le forcer à conserver une forme plus stricte sans affecter la structure du document, comme indiqué ici

Toutefois, selon que vous souhaitiez que les cellules soient fluides ou non, vous devrez peut-être modifier les .section divs en display: table-row si vous n'aimez pas une configuration de largeur prédéterminée et si vous souhaitez que les sections distinctes s'alignent.

2
J V

Cela peut en fait être fait facilement et simplement avec des divs. Vous avez juste besoin de placer un div avec position: relative dans le div en inline ou block display. Définissez sa largeur et sa hauteur de la même façon que le div. Vous constaterez alors que vous pouvez placer une autre div à l'intérieur de celle-ci.

1
Twmprys