xHTML / CSS: как заставить внутренний div получить ширину 100% минус другая ширина div - PullRequest
49 голосов
/ 04 февраля 2010

У меня есть 2 вложенных элемента div внутри внешнего, ширина которого составляет 100%. Оба вложенных элемента div должны быть в одной строке, и сначала они должны получить размер из своего содержимого:

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

Вопрос в том, как сделать # inner2 div, чтобы получить остаток от горизонтального пространства, если ширина # inner1 div не указана и зависит от того, что внутри?

P.S. В моем случае все стили находятся в отдельных классах, здесь я поместил CSS в атрибуты стилей просто для упрощения.

Я хочу, чтобы результат работал в IE7 + и FF 3.6

Более подробно для меня это выглядит так:

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

Вот изображение того, что я хочу: Image of what I want

Ответы [ 10 ]

85 голосов
/ 12 февраля 2010

Таинственный overflow: hidden; ваш друг здесь. Он не позволяет элементам, смежным с поплавками, простираться за поплавком - я думаю, что это макет, который вы ищете.

Вот немного отредактированный HTML: я не думаю, что вы можете иметь # символов в ваших id s:

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

А вот CSS для достижения желаемого макета.

(Я добавил дополнительный CSS для IE 6 с HTML условные комментарии . Я просто заметил, что вам на самом деле он не нужен и в IE 6, но если вы хотите быть вежливым с IE 6 пользователи там ...)

<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]-->

Проверено и работает в IE 6, 7 и 8; Firefox 3.5; и Chrome 4.

3 голосов
/ 05 ноября 2013

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

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%;
}

См. Рабочий пример для JSFiddle .

0 голосов
/ 27 января 2012

Ответ действительно прост!Если у вас есть фиксированный div (меню) с левой стороны, тогда задайте фиксированный div float: left и правый гибкий div margin-left , который больше ширины первого фиксированного div.

0 голосов
/ 13 февраля 2010

Другое решение - запустить javascript, который изменяет размер класса captionLine, когда документ загружается следующим образом.
Потребовалось некоторое время, чтобы заставить его работать под IE8, не пробовал IE7, но должно работать.
2 вещи на заметку.

  1. IE не поддерживает getElementsByClassName, поэтому эта функция переписана.
  2. IE обрабатывает поля по-разному, когда объекты изменяются и перемещаются с помощью style.marginLeft, так или иначе IE сохраняет поле в объявлении класса и добавляет это в новый 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 голосов
/ 13 февраля 2010

Ваша первая проблема заключается в том, что вы начинаете с префикса «#». Знак # используется только в CSS для ссылки на элемент с таким идентификатором, например, правило CSS # external {width: 100%} относится к вашему элементу:

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

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

Если вы хотите, чтобы 2 DIV появлялись в одной строке, вам нужно переместить первый слева. Соседний DIV появится на стороне, опять же, вам не нужно указывать widthd для второго элемента. Вот ваш полный пример, включающий разные цветные рамки для каждого элемента.

Я сделал границы больше, чтобы вы могли видеть более ясно, что происходит.

<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 голосов
/ 12 февраля 2010

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

(было бы приятно увидеть изображение того, что вы хотите)

Пример:

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

or

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

Это не лучшая практика.Вы должны попытаться получить этот эффект с помощью CSS.

Попробуйте сначала сделать ваш код более семантическим:

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

Чтобы получить строку:

  1. создайте изображениес нужным цветом
  2. сделайте его высоту такой же, как вы хотите, чтобы линия была в px
  3. , поместите ее с помощью свойства 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 голосов
/ 09 февраля 2010

Попробуйте это: гнездо inner1 внутри inner2 и удалите display:inline из inner2, вот так:

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

Вы можете увидеть, как это работает здесь: http://jsbin.com/adiwi

0 голосов
/ 04 февраля 2010

Расширяя ответ @Nasser Hajloo, это работает для меня (даже в 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> 

Попробуйте его с основным div меньше 400px, чтобы увидеть, как он настраивается. (Он также работает с элементами div, а не span - ключом является width: auto в первом div / span.)

0 голосов
/ 04 февраля 2010

Вам не нужно использовать div для вложенного элемента, просто используйте SPAN вот так

 <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 голосов
/ 04 февраля 2010

Вам нужно переместить элемент inner1 влево, например, так:

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

Это должно сработать.Проверьте это!прощай

...