Абсолютно позиционируется родитель и поплавок: правый ребенок растягивается - PullRequest
12 голосов
/ 08 октября 2009

В IE6, IE7 и FF2 элемент .outer ниже растягивается к правому краю документа. Вот полный тестовый пример:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <style>
  .outer { position:absolute; border:1px solid red; }
  .outer .floater { float:right; }
  </style>
</head>
<body>
  <div class="outer">
      <div class="floater">Lorem ipsum</div>
  </div>
</body>

Как я понимаю position:absolute, внешний div должен быть удален из потока документа и (без указания ширины) должен занимать минимальное количество места, необходимое для отображения его содержимого. Однако float:right на любом ребенке нарушает это.

Ожидаемый результат (IE8, FF3 +, Chrome 2+, Safari 4, Opera 9 +):

Expected output - IE8, FF3+, Chrome 2+, Safari 4, Opera 9+

Фактический вывод (IE6, IE7, FF2):

Actual output - IE6, IE7, FF2

Как сделать так, чтобы внешний div не растягивался? Это происходит только в IE6, IE7 и Firefox 2.

Требования:

  • .outer не может быть установлен width (его необходимо оставить как "auto")
  • .outer должен оставаться абсолютно позиционированным
  • .floater должен оставаться смещенным вправо

Обновление

Я воспроизвел поведение как пример "реального мира", используя диалог jQuery. Характеристики одинаковы:

  1. Существует абсолютно позиционированный div (т. Е. Контейнер диалога, jQuery-UI создает его)
  2. Div от 1) имеет width="auto"
  3. В этом диалоге есть элемент, который всплывает вправо.

Смотрите здесь . Опять же, IE6, IE7 и FF2 являются единственными проблемными браузерами.

Это повторяет условия внутри моего приложения. Я пытался свести проблему к тому, что вы видите над этим обновлением, но у меня возникает ощущение, что люди могут использовать реальный пример, где мои требования имеют смысл. Я надеюсь, что сделал это.

Ответы [ 10 ]

2 голосов
/ 17 ноября 2009

Извиняюсь за отрицательный ответ, но я не думаю, что есть способ обойти это. Реализация CSS для этих старых браузеров просто неверна, когда дело доходит до описанного вами случая, и я не верю, что есть какой-то способ обойти это через другие свойства CSS в рамках ограничений, которые вы нам дали. Как ограниченное исправление вы можете теоретически установить max-width для внешнего div, чтобы ограничить степень его растяжения ... но, к сожалению, max-width не поддерживается во всех «старых» браузерах, упомянутых в любом случае.

Я знаю, что это не то, что вы хотите услышать, но я думаю, что вам придется кусать пулю и либо менять разметку, либо ослаблять требования к стилю (например, отказаться от поплавка).

0 голосов
/ 22 ноября 2009

У меня нет IE6, IE7 или FF2 для тестирования, поэтому я собираюсь сделать удар в темноте на этом. Если мне не изменяет память, вы захотите float:left на .outer. Это уменьшит ширину .outer при сохранении пропорций внутреннего div.

0 голосов
/ 21 ноября 2009

Так как я вижу в вашем рабочем примере, что вы используете jquery, вы можете сначала вычислить ширину контейнера, прежде чем плавать плавающий объект следующим образом:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
  <style>
  .outer { position:absolute; border:1px solid red;}
  </style>
</head>
<body>
  <div class="outer">
    <div class="floater">Lorem ipsum</div>
  </div>

  <script type="text/javascript">
    $(".outer")
      .css("width", $(".outer").width());
    $(".floater")
      .css("float", "right");
  </script>

</body>

Если указать ширину внешнего тега div, он будет вести себя во всех других браузерах

0 голосов
/ 16 ноября 2009

Да для элементов с абсолютным позиционированием, ширина не определена (как top и left ). Некоторые браузеры в этом случае используют эластичную ширину таблицы, а некоторые - ширину 100%, но это зависит от браузера. Лучше быть явным в этом случае.

Таблицы - действительно единственный хороший способ получить эластичную ширину кросс-браузерным способом. Один одноклеточный стол так же хорош, как DIV, если вы помните cellspacing=0.

<table cellspacing=0 cellpadding=0 style="position:absolute;top:0;right:0">
    <tr><td>Lorem ipsum</td></tr>
</table>
0 голосов
/ 17 ноября 2009

Ваш .outer div пуст, поэтому мы получаем разные результаты. Как только вы добавляете к нему контент, по крайней мере, в моем тесте он работает точно так же (мой тест был Chrome 3.0 как «работающий по назначению» и IE7 как сломанный).


<div class="outer">
  <div class="floater">Lorem ipsum</div>
Lorem ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit ipsum dolor sit amet consequetur elit 
</div>

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

Редактировать

Чтобы воспроизвести ваш код без растяжения (поймите, что после того, как вы это сделаете одинаково, у вас возникнут другие проблемы, такие как поля / отступы / вертикальное растяжение), вы можете ввести относительную «оболочку».


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <style>

  body { margin: 0; }
  #outer { position: absolute; border:1px solid red; }
  #wrapper { position: relative; }
  #floater { position: absolute; right:0; border: 1px blue solid;  }

  </style>
</head>
<body>

  <div id="outer">

    <div id="wrapper"> 
        <div id="floater">Lorem ipsumX</div> 
    </div>

    Lorem ipsum dolor sit amet consequetur elitipsum dolor sit amet consequetur elit
  </div>
</body>
0 голосов
/ 15 ноября 2009

Спецификация css2 содержит некоторую информацию о том, как пользовательский агент «должен» вычислять ширину, но реальность не является спецификацией: http://www.w3.org/TR/CSS2/visudet.html#Computing_widths_and_margins.

Я определенно рекомендую использовать строгий DOCTYPE вместо переходного один, http://www.w3.org/QA/2002/04/valid-dtd-list.html#DTD.

Без указания поля для вашего .outer div, пользовательский агент определит ширину, используя width: auto, которая выглядит как изменяющаяся в зависимости от пользовательского агента.

Почему вы не хотите указывать ширину родительского div?

Если вы можете, укажите ширину родительского div, даже если это width: 100%. Возможно, вы также захотите поместить * { margin: 0; padding: 0; } в таблицу стилей, чтобы избежать различий пользовательских агентов в этих атрибутах, особенно если для .outer указана ширина как 100%.

Это может быть тривиально, но вы должны быть в состоянии сократить выражение .outer .floater до .floater.

Если вам нужен эффект «сжимать до нужного размера» вокруг внутреннего поплавка и вам нужно поддерживать float-right, то добавьте direction: rtl; к классу .floater; в противном случае вы сможете использовать float-left;

0 голосов
/ 13 ноября 2009

Если вы измените float:right на clear:right, вы получите запрошенный вывод в вашем примере, но он не будет работать так, как ожидалось, если у вас действительно есть содержимое вне div плавающего элемента.

0 голосов
/ 09 ноября 2009

.outer {переполнение: скрыто; ясно: право; позиция: абсолютная; граница: 1px сплошной красный; } .outer .floater {float: right; } Lorem Ipsum Это действительно просто, вы должны только установить свойства overflow и clear для каждого объекта, который имеет дочерние объекты.

Если родительский объект также является плавающим, вам нужно только установить свой объект как плавающий.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <style>
  .outer { overflow:hidden; clear:right; position:absolute; border:1px solid red; }
  .outer .floater { float:right; }
  .outer .floater .child { float:right; }
  </style>
</head>
<body>
  <div class="outer">
      <div class="floater">Lorem ipsum 
                <span class="child">HI!</span>
      </div>
  </div>
</body>

Если есть какие-либо вопросы, просто спросите!

С уважением и GL. ;)

0 голосов
/ 08 ноября 2009

float должен иметь ширину в этом случае, и с другой точки зрения у вас должно быть top: 0; left: 0; для позиционированного элемента они не должны храниться так. примечание: это логика только для дизайна, если вы не пишете код, пожалуйста, спросите:)

0 голосов
/ 08 октября 2009

Вам нужно это, чтобы не допустить переполнения края страницы:

body {margin:0;padding:0}

Однако он по-прежнему будет занимать всю ширину страницы, просто не переполнится

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...