web-dev-qa-db-fra.com

xHTML/CSS: Comment obtenir une div interne de 100% largeur moins une autre largeur

J'ai 2 divs imbriqués à l'intérieur externe, qui a la largeur: 100%. Les deux divs imbriquées doivent être sur une ligne et la première doit en obtenir la taille à partir de son contenu:

<div id="#outer" style="width:100%; border:1px">
  <div id="#inner1" style="border:1px; display:inline">
    inner div 1. Some text...
  </div>
  <div id="#inner2" style="width:100%????; border:1px; display:inline">
    inner div 2...
  </div>
</div>

La question est de savoir comment faire # inner2 div pour obtenir le reste de l’espace horizontal si la largeur de la # inner1 div n’est pas spécifiée et dépend de son contenu.

P.S. Tous les styles sont dans des classes séparées dans mon cas, ici j'ai mis CSS dans des attributs de style juste pour simplifier.

Je veux que les résultats fonctionnent dans IE7 + et FF 3.6

En plus de détails pour moi, il ressemble à ceci:

 <style type="text/css">
.captionText
{
 float:left;
} 

.captionLine
{
 height: 1px;
 background-color:black;
 margin: 0px;
 margin-left: 5px;
 margin-top: 5px;
 border: 0px;
 padding: 0px;
 padding-top: 1px;
}
 </style>
<table style="width:300px;">
<caption width="100%">
     <div class="captionText">Some text</div>
     <div class="captionLine"> </div>
</caption>
     <tr>
           <td>something</td>
     </tr>
</table>

Voici l'image de ce que je veux:Image of what I want

48
Artem

Le mystérieux _overflow: hidden;_ est votre ami ici. Il empêche les éléments adjacents aux flotteurs de s’étendre derrière le flotteur. Je pense que c’est la disposition que vous recherchez.

Voici du code HTML légèrement modifié: je ne pense pas que vous puissiez avoir _#_ caractères __ dans votre ids:

_<div id="outer">
    <div id="inner1">
        inner div 1. Some text...
    </div>
    <div id="inner2">
        inner div 2...
    </div>
</div>
_

Et voici le CSS pour réaliser la mise en page souhaitée.

(J'ai mis des CSS supplémentaires pour IE 6 avec HTML commentaires conditionnels . Je viens de remarquer que vous n'en aviez pas réellement besoin pour fonctionner dans IE 6 aussi, mais si vous voulez être gentil avec les IE 6 utilisateurs ...)

_<style type="text/css">
#outer {
    overflow: hidden;/* Makes #outer contain its floated children */
    width: 100%;

    /* Colours and borders for illustration purposes */
    border: solid 3px #666;
    background: #ddd;
}

#inner1 {
    float: left;/* Make this div as wide as its contents */

    /* Colours and borders for illustration purposes */
    border: solid 3px #c00;
    background: #fdd;
}

#inner2 {
    overflow: hidden;/* Make this div take up the rest of the horizontal space, and no more */

    /* Colours and borders for illustration purposes */
    border: solid 3px #00c;
    background: #ddf;
}
</style>

<!--[if lte IE 6]>
<style type="text/css">
#inner2 {
    zoom: 1;/* Make this div take up the rest of the horizontal space, and no more, in IE 6 */
}

#inner1 {
    margin-right: -3px;/* Fix the 3-pixel gap that the previous rule introduces. (Shit like this is why web developers hate IE 6.) */
}
</style>
<![endif]-->
_

Testé et fonctionnant dans IE 6, 7 et 8; Firefox 3.5; et Chrome 4.

85
Paul D. Waite

Si vous lisez ceci, vous pouvez probablement utiliser calc , alors soyez reconnaissant.

HTML

<div class="universe">
  <div class="somewidth">
  </div>
  <div class="everythingelse">
  </div>
</div>

CSS

.universe {
  width: 100%;
  height: 100%;
}

.somewidth {
  width: 200px;
  height: 100%;
}

.everythingelse {
  width: 800px; /* fallback for emergencies */
  width: calc(100% - 200px);
  width: -moz-calc(100% - 200px);
  width: -webkit-calc(100% - 200px);
  height: 100%;
}

Voir le exemple de travail sur JSFiddle .

2
fiatjaf

Votre premier problème est que vous préfixez vos identifiants avec un '#'. Le # n'est utilisé que dans CSS pour faire référence à l'élément avec cet identifiant, par exemple. la règle CSS #outer {width: 100%} fait référence à votre élément:

<div id="outer"></div>

De plus, vous n'avez pas besoin d'utiliser width sur les div (ou tout autre élément de bloc) qui ne sont pas flottants, car ils occupent déjà automatiquement 100% de la largeur disponible. 

Si vous souhaitez que les 2 DIV apparaissent sur la même ligne, vous devez faire flotter la première à gauche. La DIV adjacente apparaîtra alors sur le côté, encore une fois, vous n'avez pas besoin de spécifier widthd pour le deuxième élément. Voici votre exemple complet incluant une bordure de couleur différente pour chaque div.

J'ai agrandi les frontières pour que vous puissiez voir ce qui se passe.

<html><body>
<style type="text/css">
#outer {
    border: solid 5px #c00;
}
#inner1 {
    border: solid 5px #0c0;
    float: left;
    width: 200px;
    height: 300px;
}
#inner2 {
    border: solid 5px #00c;
    height: 300px;
    margin-left: 210px; /* 200px left width + 2 x 5px borders */
}
</style>

<div id="outer">
  <div id="inner1">
    inner div 1. Some text...
  </div>
  <div id="inner2">
    inner div 2...
  </div>
</div>

</body></html>
0
mythz

Une autre solution consiste à exécuter un script javascript qui redimensionne la classe captionLine lorsque le document est chargé de la sorte.
Il a fallu du temps pour que cela fonctionne sous IE8, je n'ai pas essayé IE7, mais cela devrait fonctionner.
2 choses à noter.

  1. IE ne prend pas en charge getElementsByClassName, cette fonction est donc réécrite .
  2. IE gère les marges différemment lorsque les objets sont redimensionnés et déplacés avec style.marginLeft. IE semble conserver la marge dans la déclaration de classe et l'ajouter au nouveau style.margin .
<body onload="resizeCaptionLine()">
<style>
caption {
 border: 1px solid blue;
 padding: 0px;
}
.captionText {
 border: 1px solid red;
 float: left;
}
.captionLine {
 background-color:black;
 margin: 0px;
 margin: 5px 0px 0px 5px;
 border: 0px;
 padding: 0px;
 padding-top: 1px;
}
</style>

<table style="width:300px;">
<caption width="100%" name="caption1">
     <div class="captionText">Some text</div>
     <div class="captionLine"> </div>
</caption>
     <tr>
           <td>something</td>
     </tr>
</table>
<table style="width:300px;">
<caption width="100%" name="caption2">
     <div class="captionText">Some text</div>
     <div class="captionLine"> </div>
</caption>
     <tr>
           <td>something</td>
     </tr>
</table>

<script type="text/javascript">

function getElementsByClassName(node, class_name) {
  elems = node.all || node.getElementsByTagName('*');
  var arr = new Array();
  for(j = 0; j < elems.length; j++)
  {
    if (elems[j].className == class_name)
       arr[arr.length] = elems[j];
  }
  return arr;
}

function resizeCaptionLine()
{
 var elems = getElementsByClassName(document, 'captionLine');
 for(i = 0; i < elems.length ; i++)
 {
   var parent = elems[i].parentNode;
   var sibling = getElementsByClassName(parent, 'captionText');
   var width = parent.offsetWidth - sibling[0].offsetWidth;

    if(elems[i].currentStyle)
   {
     var currentMargin = elems[i].currentStyle.marginLeft;
     var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
     elems[i].style.marginLeft = (sibling[0].offsetWidth) + "px";
   }
   else if (document.defaultView && document.defaultView.getComputedStyle)
   {
     var currentStyle = document.defaultView.getComputedStyle(elems[i], '');
     var currentMargin = currentStyle.marginLeft;
     var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
     elems[i].style.marginLeft = (sibling[0].offsetWidth + margin) + "px";
   }
   else
   {
     var currentMargin = elems[i].style.marginLeft;
     var margin = parseInt(currentMargin.substr(0,currentMargin.length-2));
     elems[i].style.marginLeft = (sibling[0].offsetWidth) + "px";
   }
   elems[i].style.width = (width - margin)+"px";
 } 
}
</script>
</body>
0
Erik

Essayez ceci: nest inner1 dans inner2, et supprimez le display:inline dans inner2, comme ceci:

<div id="#outer" style="width:100%; border:1px solid red">
  <div id="#inner2" style="width:100%; border:1px solid black;">
     <div id="#inner1" style="border:1px solid blue; display:inline">
      inner div 1. Some text...
     </div>
  inner div 2...
  </div>
</div>

Vous pouvez le voir fonctionner ici: http://jsbin.com/adiwi

0
graphicdivine

La réponse est vraiment simple! Si vous avez fixé div (menu) sur le côté gauche, indiquez div float: left et votre div flexible droite margin-left plus grande que la largeur de la première div fixe.

0
Domen

Vous auriez besoin de placer la division inner1 à gauche, comme ceci:

<div id="#outer" ....>
    <div id='#inner1" style="float:left; border: 1px solid #000;">
        blabla
    </div>
    <div id="#inner2" style="... DON'T USE WIDTH AND DISPLAY HERE! ...">
        gnihihi
    </div>
</div>

Cela devrait faire l'affaire. Check it out! Au revoir

0
aefxx

En développant la réponse de @Nasser Hajloo, cela fonctionne pour moi (même dans IE6)

 <div style="width: 400px; border: solid 1px red;"> 
     <span style="float:left;width: auto;border: solid 1px black;"> 
            hey you 
     </span> 
     <div style="display:inline-block;margin: 0px 2px;border: solid 1px black;">always use proper tools.</div> 
 </div> 

Essayez avec la division principale inférieure à 400px pour voir comment elle s’ajuste. (Cela fonctionne aussi avec des divs plutôt que des span - la clé est le width: auto dans le premier div/span.)

0
Traingamer

D'après votre code, il semblerait que vous essayiez d'obtenir une ligne horizontale pour remplir l'espace vide de votre div. Si je ne me trompe pas, vous cherchez à créer un effet visuel avec des balises. Corrige moi si je me trompe.

(Ce serait bien de voir une image de ce que vous voulez)

Exemple:

Title ---------------------------

or

Title: Caption ------------------

Ce n'est pas la meilleure pratique. Vous devriez essayer d'obtenir cet effet avec CSS.

Essayez de rendre votre code plus sémantique en premier:

<div id="#outer" style="width:100%; border:1px">
  <h3 style="border:1px; display:inline">
    Caption
  </h3>
</div>

Pour obtenir la ligne:

  1. créer une image avec la couleur que vous voulez
  2. faire en sorte que sa hauteur soit la même que vous voudriez que la ligne soit en px
  3. positionnez-le avec la propriété background__

.

#outer h3 {
display: inline;
background-color: #000;
color: #FFF;
}

#outer {
width: 100%; /* is the default of block element but just for celerity */
background: #000 url('image path') center left; /* position the image */
}
0
Kevin

Vous n'avez pas besoin d'utiliser div pour l'élément imbriqué, utilisez simplement SPAN comme ceci

 <div>
     <span style="display:inline-block;width: auto;border: solid 1px black;">
            hey you
     </span>
     <span style="display:inline-block;marging: 0px 2px;border: solid 1px black;">
           always use proper tools.
     </span>
 </div>
0
Nasser Hadjloo