2013-07-11 1 views
16

У меня есть основное меню, сделанные из горизонтально выровненного списка (<li>), каждый из которых содержит значок изображение и текст:Элемент с дисплеем CSS: нет; разрывные расположение - вызывают перекосы

Menu bar

Один из <li> содержит дополнительное изображение с display: none;, так что значок может быть переключен (от зеленого до красного перца, в этом примере). Проблема заключается в том, что он не выравнивается правильно в некоторых браузерах, как показано на рисунке выше. Мое понимание было то, что в отличие от visibilty: hidden;, элемент с display: none; не должен влиять на положение любого другого элемента и должен быть как будто его там нет?

браузеры, где не делают правильно в Google Chrome и Safari - но только на MacOS и IE7 (я знаю, я знаю ...) на Windows, (!?). Каждая другая комбинация браузера/ОС, которую я тестировал, отлично работает.

Вот HTML:

<ul class="menu"> 
    <li><img alt="Green Pepper" src="/green.png">li</li> 
    <li><img alt="Green Pepper" src="/green.png">li</li> 
    <li><img alt="Green Pepper" src="/green.png">li</li> 
    <li id="change"> 
     <img alt="Red Pepper" src="/red.png" style="display: none;"> 
     <img alt="Green Pepper" src="/green.png"> 
     li 
    </li> 
    <li><img alt="Green Pepper" src="/green.png">li</li> 
</ul> 

Вот CSS:

.menu li { 
    cursor: default; 
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-size: 10pt; 
    list-style-type: none; 
    position: relative; 
    text-align:center; 
    margin: 0 0 0 -25px; 
    padding: 8px 0 0 0; 
    width: 144px; 
    height: 35px; 
    display: inline-block; 
    background-image: url(../bct-white.png); 
    background-repeat: no-repeat; 
    color: #0091c1; 
} 

И иконка изображений:

.menu img { 
    display: inline; 
    vertical-align: -25%; 
    padding-right: 6px; 
} 

Я также должен был включать в себя браузер взломать для IE7, поскольку он не распознает встроенный блок, исходящий из отдельной таблицы стилей на основе условного импорта (<!--[if lte IE 7]>):

.menu li { 
    zoom: 1; 
    display: inline; 
} 

Хотя, очевидно, что стиль не загружен на Chrome и Safari независимо от операционной системы, поэтому не может быть причиной моего вопроса на Маках.

Я знаю, что самым быстрым решением было бы рефакторинг HTML и JavaScript манипуляции с отображением/скрытием значков, но мне очень хотелось бы знать, что вызывает эту проблему и как ее решить.


Update

Я отслеживал дело вниз. В принципе, стиль элемента display: none; на элементе <img> переопределяет inline из правила .menu img. Снимая это, затем переключение между block и inline позволяет воспроизвести проблему. Очевидно, это ошибка браузера, и пока элемент не отображается, поскольку элемент в строке или блоке не должен влиять на макет.


jsFiddles

Issue with Chrome and Safari on Macs only

Issue with extra CSS for IE7 only

Примечание!Для меня страница Fiddle не загружалась должным образом с использованием IE7, но прямая ссылка для результата iFrame равна http://fiddle.jshell.net/z4dU7/3/show/

Bounty update !!!

Я разместил одно исправление ниже, но на самом деле он вводит ту же самую проблему размещения в IE9! Пожалуйста, не стесняйтесь меняться или улучшать свой ответ - или приходите к столу с чем-то совершенно другим! :)

+0

Думаю, нам нужно увидеть это в действии, чтобы быть в состоянии помочь вам. Я сделал быструю скрипку и не смог воспроизвести это поведение - отображение: ни один из них не удалил изображение из макета (как и должно быть). Может быть, '# change' использует некоторые другие стили? – David

+0

Эта демонстрация демонстрирует это в IE7: http://jsfiddle.net/z4dU7/3/ Чтобы увидеть проблему на Mac, просто удалите последнее правило стиля (которое вытащили из специальной таблицы стилей IE в моей системе). – Mikaveli

+0

@David Я обновил свой вопрос со ссылками на оба сценария. – Mikaveli

ответ

10

Scrap подход и использование фоновых изображений

http://jsfiddle.net/P5CKC/2/

<ul class="menu"> 
    <li><span>Li</span></li> 
    <li><span>Li</span></li> 
    <li><span>Li</span></li> 
    <li class="change"><span>Li</span></li> 
    <li><span>Li</span></li> 
</ul> 

CSS

ul.menu { 
    overlflow: hidden; 
} 
ul.menu li { 
    float: left; 
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-size: 10pt; 
    text-align:center; 
    margin: 0 0 0 -25px; 
    width: 152px; 
    line-height: 35px; 
    height: 35px; 
    background: url(../bct-white.png) no-repeat; 
    color: #0091c1; 
} 
ul.menu li span { 
    background: url(/green.png) no-repeat 5px 6px; 
    display: block; 
} 
ul.menu li.change span { 
    background-image: url(/red.png); 
} 

Совместимость с CSS2.0 и браузером

Приложение кода, которое я предоставил, является Css2.0 и должно легко работать в IE7 и выше.

  1. Удалены img метки и implemmented эстетики (изображений) в качестве фона
  2. Экстра span должны были быть добавлены, поскольку CSS2 позволяет только один фоновое изображение для каждого элемента
  3. Ли тег содержит фон со стрелкой; span tag содержит перечный фон
  4. Обновлено id="change" до class="change". ЕСЛИ вы на 100% уверены, что у вас будет только один элемент #change, используйте класс. Это чисто стилизация, и это мешает вам иметь два списка меню на одной странице.
  5. Оптимального вашего CSS укладки немного следующим образом:

Удален верхний отступ и увеличил высоту. Таким образом, ваши элементы li имеют одинаковую высоту, но затем добавлены line-height: 35px -> это лучший способ вертикального центра текста. Утилизация верхнего заполнения работает, но она подвержена плохой несогласованности браузера.

Изменение li элементы для поплавков. Плавающие элементы - самый удобный для IE7 метод! Даже IE6 не будет ошибкой, но у меня нет этой старой версии, чтобы протестировать вашу веб-страницу. FYI - ul.menu должен иметь overflow: hidden, чтобы очистить поплавки.

position: relative; 
cursor: default; 

Если вы не изменили значения по умолчанию, вы можете сохранить эти два свойства. курсор должен быть по умолчанию. Позиция: относительная не нужна - вы не используете абсолютное позиционирование или что-либо, что оправдывает его потребность. Теперь вы можете сохранить их в своей декларации. Мне просто нравится код как «тонкий», насколько это возможно.

заключительные слова:

Взгляните на мой CSS. Обратите внимание, как я использовал ul.menu во всей своей декларации. Вы можете захотеть привыкнуть к тому же; это дает разработчику некоторое представление о том, как выглядит HTML и что более важно - ваш css не будет отменен, если вы решите добавить <div class=menu> позже. Специфически .menu img применим к любому тегу изображения в меню div.

Хорошо, все. Дайте мне знать, если есть какие-либо разъяснения.

FYI - видя, что у этого вопроса есть щедрость, если вы предоставите мне фоновое изображение, я могу отполировать свой код в соответствии с вашими потребностями на 100% - возможно, загрузить их в редактирование вашего ответа.

+0

+1 Мне нравится это решение, и это хорошо объяснено. Использование внутренних пространств позволяет избежать необходимости многократного использования нескольких фоновых изображений и не является большой модификацией для HTML. – Mikaveli

+2

+1.[Правильный подход] (http://stackoverflow.com/questions/492809/when-to-use-img-vs-css-background-image). Для меня использование '' 'для макета похоже на использование'

'' для макета. – Artyom

0

Для решения (появление) проблемы, изменить вертикальное выравнивание иконок изображений, содержащихся в меню:

.menu img { 
    display: inline; 
    vertical-align: top; 
    margin-top: 2px; 
    padding-right: 6px; 
} 

На пораженных браузерах, дополнительные изображения (с display: none;) было изменение высота содержащего элемента. Установка <img> на display: none; означала, что установка display: inline; больше не применяется и была помещена под первым изображением.

Просто наличие дополнительного <img>, отображающего строку в строке, фиксирует вертикальное выравнивание, но, очевидно, не устраняет проблему, так как изображение должно быть скрыто без изменения положения текста.

Это исправление изменяет вертикальное выравнивание от процента (-25%) до фиксированного положения, избегая любых (ложных) различий в высоте содержащего элемента. Затем я установил верхний край изображения, чтобы получить желаемый интервал от верхнего края элемента.

Update

Это исправление разбивает экран в IE9 - такой же вид, как IE7 без исправления.

+1

вы можете попытаться установить ширину и высоту скрытых изображений, чтобы сказать 1 или 0. Таким образом, даже если они каким-то образом влияют на макет, это не видно. –

2

Это странно, но я мог бы воссоздать проблему в Firefox v22. Очень странная часть заключалась в том, что в jsFiddle, если я просто ударил «Tidy Up», а затем ударил «Run», и проблема была решена. Как Matthew R mentioned это, вероятно, связано с удалением дополнительного пробела.

Сломанный: enter image description here

Tidy Up, Run и Fixed enter image description here

Вот альтернативный метод с использованием фоновых изображений:

Working Example

.menu li { 
    cursor: default; 
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-size: 10pt; 
    list-style-type: none; 
    position: relative; 
    text-align: center; 
    margin: 0 0 0 -25px; 
    padding: 8px 0 0 10px; 
    width: 118px; 
    height: 20px; 
    display: inline-block; 
    background-image: url(http://modmyi.com/attachments/forums/iphone-4-4s-new-skins-themes-launches/465481d1282224308-classified-hd-cydia-released-goldborder.png), url(http://i.stack.imgur.com/dmHl0.png); 
    background-position: 0% 0%, 44% 75%; 
    background-size: 128px, 18px; 
    background-repeat: no-repeat; 
    color: #0091c1; 
} 

.menu img { 
    display: inline; 
    vertical-align: -25%; 
    padding-right: 6px; 
} 

#change:hover { 
    background-image: url(http://modmyi.com/attachments/forums/iphone-4-4s-new-skins-themes-launches/465481d1282224308-classified-hd-cydia-released-goldborder.png), url(http://www.chiletownhotsauce.com/images/stories/Red%20bell%20pepper.jpg); 
    background-repeat: no-repeat; 
    background-position: 0% 0%, 44% 75%; 
    background-size: 128px, 18px; 
} 
<ul class="menu"> 
    <li>li</li> 
    <li>li</li> 
    <li>li</li> 
    <li id="change">li</li> 
    <li>li</li> 
</ul> 
3

Между вашими элементами есть пробел. Ни один из ваших других элементов списка не имеет этого пробела. Попробуйте удалить все пробелы между этими элементами и посмотреть, устраняет ли это вашу проблему.

Если это так, это означает, что ваш HTML анализирует содержимое вашего <li> как имеющего разрыв строки - вот почему вы видите проблему. Чтобы решить эту проблему, оберните текст в <li> с помощью <span>.Когда ваш браузер анализирует HTML будет автоматически обрезать пробелы между HTML-теги и автоматически исправить эту проблему (без потери форматирования)

+0

Исправлено это для Chrome для меня. http://jsfiddle.net/z4dU7/8/ – MiniRagnarok

1

Я думаю, что ваша проблема связана с box model и display:inline-block.Когда я использую display:inline-block в горизонтальных меню, я также использую четкое исправление для родителя и float:left; с детьми.
В этом примере css я поместил некоторые значения в .menu, которые могут быть унаследованы, и я использовал overflow:hidden; для устранения ясного исправления. Затем я использовал float:left; в li, чтобы закрепить их плотно и избежать любого странного интервала, вызванного по умолчанию браузерами. И затем я изменил значение vertical-align на middle для изображения. При переключении display:none; с inline все это выглядело правильно. Я не тестировал во всех перечисленных браузерах. Я также использовал первый фрагмент CSS для css reset, который может быть избыточным, но я всегда считаю его полезным для JSFiddle.

* { 
    margin:0; 
    padding:0; 
} 
.menu { 
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-size: 10pt; 
    list-style-type: none; 
    color: #0091c1; 
    overflow:hidden; 
} 
.menu li { 
    cursor: default; 
    position: relative; 
    text-align:center; 
    /* margin: 0 0 0 -25px; */ 
    padding: 8px 0 0 0; 
    width: 118px; 
    height: 20px; 
    display: inline-block; 
    float:left; 
    background-image: url(http://modmyi.com/attachments/forums/iphone-4-4s-new-skins-themes-launches/465481d1282224308-classified-hd-cydia-released-goldborder.png); 
    background-repeat: no-repeat; 
} 

.menu img { 
    display: inline; 
    /* vertical-align: -25%; */ 
    padding-right: 6px; 
    vertical-align:middle; 
} 
+0

И я также полностью поддерживаю всех людей, говорящих, чтобы использовать 'background-image' ... –

0

Вы сделали ошибку с линией высоты вместо 35px 23px отдавания

<ul class="menu"> 
    <li><span>Li</span></li> 
    <li><span>Li</span></li> 
    <li><span>Li</span></li> 
    <li class="change"><span>Li</span></li> 
    <li><span>Li</span></li> 
</ul> 
ul.menu { 
    overlflow: hidden; 
} 
ul.menu li { 
    float: left; 
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-size: 10pt; 
    text-align: center; 
    margin: 0 0 0 -25px; 
    width: 152px; 
    line-height: 23px; 
    list-style: none; 
    height: 35px; 
    background: #ccc; 
    color: #0091c1; 
} 
ul.menu li span { 
    background: url(http://i.stack.imgur.com/dmHl0.png) no-repeat 5px 6px; 
    display: block; 
} 
ul.menu li.change span { 
    background-image: url(/red.png); 
} 

проверить выходной

jsfiddle-link

enter image description here

Смежные вопросы