Как я могу переопределить "display:inline-block "с" display: block " в IE7?

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

<div class="normal">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib blockbyclass">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib">
    <a href="#" style="display: block;">Test</a>
    <a href="#" style="display: block;">Test longer</a>
</div>
body{background-color: gray;}
div{float:left; margin: 5px;}
a {background-color: black; color: white;}
div.ib a {display: inline-block;}
div.normal > a {display: block;}
div.blockbyclass> a {display: block; }

у меня есть определенный тип ссылки, которая в большинстве случаев должна отображаться как встроенный блок, но в определенном случае должна отображаться как элементы блока. В частности, я хочу, чтобы каждый из них появился на своей собственной линии и занял всю область содержащего div. В этом конкретном случае div содержит ссылки имеет значение float, поэтому он будет изменять размер на основе самой большой из ссылок внутри него. IE8, IE9, Firefox и Chrome отображают эти ссылки правильно, но независимо от того, что я делаю IE7 отказывается забывать display: inline-block правило.

как я могу сделать IE7 показать эти элементы в режиме "блок"?

11 ответов


ваша проблема-это hasLayout пуск inline-block настройка. Цитировать http://www.satzansatz.de/cssd/onhavinglayout.html (Курсив мой):

"свойство display-отличается: в то время как' inline-block ' устанавливает haslayout = true, флаг не будет сброшен на false позже, переопределив значение с помощью "block" или "inline" в другом наборе правил."

это не похоже на большинство hasLayout триггеры, которые можно сбросить. Поэтому я думаю, что исправьте вашу проблему, вам нужно думать в обратном направлении. Вы должны иметь block быть по умолчанию для a тег, а затем добавьте класс, чтобы получить ваш inline-block когда вам это нужно.

вроде как http://jsfiddle.net/mmpX3/33/ где blockbyclass Я заменить inlinebyclass (которая на самом деле inline-block).

Обновленная Объяснение: вы, вероятно, заметили это, когда переключились на block после выхода из inline-block что он " вроде работал "(строки текст все еще двигается вниз). Это потому, что он отображается как блок, но тот, который hasLayout в отличие от того, который этого не делает. Я не знаю вашей конкретной ситуации, но если вы можете установить a width на содержание div тогда вторичное решение того, что я предложил выше "думать наоборот", - это установить width: 100% в сочетании с вашим "сброс" к block, вот так: http://jsfiddle.net/mmpX3/64/.

обновление Внимание: я не знаю, есть ли у вас другой css, который вы планируете применить к a теги, но если какой-либо из этих триггеров hasLayout тогда вам нужно будет следить за этим (и, возможно, найти другой метод). См., например, эту скрипку http://jsfiddle.net/mmpX3/69/ в котором все установлено на block но потому что я поставил min-height на a tag, он по-прежнему имеет те же проблемы, что и ваша оригинальная проблема.


Update: перемещено из комментариев здесь:

проблема div плавающий. Когда вы плаваете элемент, который будет вне обычного потока страниц, так что,IE возьму за него width:0; height:0; и когда вы поместите в него некоторые элементы, они создадут свои собственные height и width и плавающий элемент будет отображаться, как их можно подтолкнуть (мой английский очень плохой, так что извините). Первый шаг, A и inline-block это height к примеру x. когда вы сделаете это block он должен заполнить своего родителя, но, в IE ум, его родителей width:0. поэтому вы должны удалить первый С div.ib a или вы можете создать фиксированной ширины атрибут для floated div элемент.

div { float: left; margin: 5px; width: 80px; } 

кроме того, насколько я знаю,W3C по рекомендует плавающие элементы должны иметь фиксированную ширину. - IE 6 нужна фиксированная высота тоже работать правильно!!!

другой способ -если вы можете, и ваше решение позволяет вам- это изменение первого inline-block to inline только на IE:

display: inline-block; 
*display: inline; 

но width решение (для div) является более стандартным и гибким.

ОБНОВЛЕНИЯ

однако, для переопределения css-attribute только в IE, у вас есть 3 вариант для этого:

  1. The первый способ-использовать условные комментарии это делает его содержание видимым для IE только. Полный пример примерно таков:

    <!-- visible to IE less that 7 (6, 5, etc) -->
    <!--[if lt IE 7]> <link href="/Content/ie6.css" rel="stylesheet" type="text/css" /> <![endif]-->
    
    <!-- visible to IE 7 only -->
    <!--[if IE 7]> <link href="/Content/ie7.css" rel="stylesheet" type="text/css" /> <![endif]-->
    
    <!-- visible to IE 8 only -->
    <!--[if IE 8]> <link href="/Content/ie8.css" rel="stylesheet" type="text/css" /> <![endif]-->
    
    <!-- visible to IE 9 and above and also visible to other browsers -->
    <!--[if gt IE 8]><!--> <link href="/Content/normal.css" rel="stylesheet" type="text/css" /> <!--<![endif]-->
    

    Как видите, у вас есть много вариантов использования условные комментарии.

  2. другой способ-использовать CSS специально селекторы, которые делают некоторые селекторы видна IE и скрывать их от других браузеров. Полный пример есть:

    /* normal */
    your-selector{
    }
    
    /* visible to IE 6 only */
    * html your-selector{
    }
    
    /* visible to IE 7  only */
    *:first-child + html your-selector{
    }
    
    /* visible to IE 7 and above */
    html > body your-selector{
    }
    
    /* visible to IE 8 and above */
    html > /**/ body your-selector{
    }
    
  3. третий способ, который я знаю, использует IE специализированные css-свойства:

    /* normal selector */
    your-selector{
        /* normal property, visible to all browsers */
        color: #FF0;
        padding: 20px auto 35px;
    
        /* use special properties in name/value for IE */
    
        /* visible to ie 6 only */
        _color: #FF0;
        _padding: 15px auto 30px;
    
        /* visible to ie 7 and below (7, 6, 5, ...) */
        *color:#FF0;
        *padding: 15px auto 30px;
    }
    

Дайте мне знать, если у вас есть какие-либо вопросы или нужны разъяснения по любой части.


в соответствии с этим статьи display:inline-block имеет аналогичное поведение, что display:inline в IE7, поэтому вы можете сделать небольшое изменение только для поддержки IE7 (с простой хак для IE):

div.ib a {
   display: inline-block; 
   *display: inline; /* IE7 and below */ 
}

надеюсь этой работает, как вы ожидали.


EDIT:

ОК. Проблема заключается в свойстве hasLayout explaining здесь. Оба!--3--> и height:any_value активирует hasLayout, так что пока display:inline-block; *display:inline работает, чтобы перезаписать следующий display:block заявления, поставив height:30px (например) возвращает свойство hasLayout. Так что нужно сделать, это удалить hasLayout, как говорится в в этой статье.

я демо чтобы показать, как работает. Потому что height практически неприкасаемый я использую padding-bottom и font-size для того чтобы сымитировать height в других браузерах. Обратите внимание, что width широчайшей элемент поддерживается.


EDIT2:

вы тактичны jQuery решений? (Только элементы разные widths в IE7)


вы можете поместить стили для IE7 в отдельный CSS и использовать условные комментарии включить его только для IE7.

<!--[if IE 7]>
<link ...your IE7 specific stylesheet goes here ... >
<![endif]-->

убедитесь, что этот фрагмент кода находится ниже ссылки на обычный файл css.


display: inline-block 

для IE7 выглядит так:

*display: inline;
zoom: 1

display: inline-block не совместим в IE7 для элементов, которые не являются встроенными по умолчанию, поэтому IE будет игнорировать это правило для DIVs. Если вы измените DIV на SPAN, например, то этот пример должен работать.


вот что: если вам нужно a якоря тегов для отображения на своих собственных линиях, они являются блочными элементами, а не встроенными... На самом деле, нет ничего о том, что вы говорите, что указывает на необходимость встроенного блока. Ваш divs плавают, поэтому они будут складываться слева, в строку (но не в линию; они находятся вне потока документа, таким образом float).

попробуйте это... давайте снимем все это. Вот HTML, который Вы нам дали:

<div class="normal">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib blockbyclass">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>
<div class="ib">
    <a href="#" style="display: block;">Test</a>
    <a href="#" style="display: block;">Test longer</a>
</div>

С CSS вы предоставили, в Safari и Firefox, я вижу три блока с двумя ссылками каждый, каждый на своей линии. Что вы видите в IE7, однако, не два inline-block элементы, но только два inline элементы-причина этого в том, что inline-block Не поддерживается в IE7 из-за hasLayout ошибка (что-то, что Microsoft создала, чтобы усложнить простую проблему). Другими словами, он не может забыть inline-block, потому что он просто не понимает inline-block (который вы неправильно поняли, как необходимо), и лечит a по умолчанию поведение отображения (т. е. inline).

если они должны быть на отдельных строках и ширину контейнера, все, что вам нужно сделать, это (показал на .ib a, полностью игнорируя blockbyclass который, кажется, просто отвлекает в этом случае):

.ib a {display:block;}

Тада! Ширина наследуется от родительского контейнера,a принимает значение по умолчанию a stylings, и все счастливо. Так что взгляните на это:

<div class="ib">
    <a href="#" style="display: block;">Test</a>
    <a href="#" style="display: block;">Test longer</a>
</div>

это, в данном случае, становится излишним и, следовательно, ненужным. Ты уже блокируешь эти элементы.

<div class="ib">
    <a href="#">Test</a>
    <a href="#">Test longer</a>
</div>

вы просто усложняете что-то действительно очень простое.

вот скрипка:http://jsfiddle.net/dhYjZ/1/


получается, что float вины здесь нет. Дело не в том, что IE7 не помечает элемент как block, Я думаю, это связано с div float не имея ширину. Это можно увидеть здесь:

http://jsfiddle.net/mmpX3/129/

как правило, при работе со старыми браузерами я обнаружил, что плавающие элементы в

в вашем случае, я бы предложил добавить фиксированную ширину JS скрипка, или удалить float Если это не требуется. Если я вижу вариант использования для floated div, Я, возможно, смогу придумать альтернативу.

почему комбинация float и display:inline-block остановка display:block от повторного instanted, я не знаю. Это звучит как типичная ошибка IE7, с которой можно работать.


Я не совсем уверен, какой конечный результат вам нужен. Вы пытаетесь сделать черный фон целым прямоугольником, который инкапсулирует обе ссылки вместо 2 прямоугольников (1 для каждой ссылки)?

если да, то почему бы не применить фон к DIV вместо ссылки?

изменить: Кажется, что есть ошибка с IE7, которая заставляет его отображать элементы в смеси block и inline-block когда одно из правил, которое применяется к элементу и display: inline-block даже если другое значение display берет верх.

если вы видите http://jsfiddle.net/P2N5c/16/ , Это не имеет значения, если правила display: block является первым (например, с помощью #blocky правило) или если это последний.

до сих пор я не уверен, как предотвратить эту ошибку, но вы можете обойти ее, не давая ссылки как ib и blockbyclass и просто давая ему классы, которые делают их блоками. Т. е. не давайте им ib. Вместо добавления класса для переключения состояний DIV замените один класс на другой.


проще говоря, я заменяю все мои display:inline-block; обычаи с display:inline;, и я также делаю это условно, как и с ответами, приведенными выше.

С вашим примером я нахожу успех со следующим:

body{background-color: gray;}
div{float:left; margin: 5px;}
a {background-color: black; color: white;display:block;}

Jsfiddle: http://jsfiddle.net/zL3Ea/


похоже на работу. Я вилка ваш код, попробуйте:http://jsfiddle.net/Lkwzx/1/

секрет в этой строке: div.ib a { display: inline-block; *display: inline; }