Элемент с дисплеем CSS: нет; разбивка макета - причина несоосности
У меня есть основное меню, сделанное из горизонтально выровненного списка (<li>
), каждый из которых содержит изображение значка и некоторый текст:
Один из <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 независимо от ОС, поэтому не может быть причиной моей проблемы на компьютерах Mac.
Я знаю, что самым быстрым решением было бы рефакторинг HTML и JavaScript манипуляции с отображением/скрытием значков, но мне очень хотелось бы знать, что вызывает эту проблему и как ее решить.
Обновить
Я отследил причину. В принципе, стиль элемента display: none;
на элементе <img>
переопределяет .menu img
inline
из .menu img
. Удалив это, переключение между block
и inline
позволяет воспроизвести проблему. Очевидно, это ошибка браузера, и пока элемент не отображается, поскольку элемент в строке или блоке не должен влиять на макет.
jsFiddles
Проблема с Chrome и Safari только на компьютерах Mac
Проблема с дополнительным CSS для IE7 только
Заметка! Для меня страница Fiddle неправильно загружалась с использованием IE7, но прямая ссылка для результата iFrame - http://fiddle.jshell.net/z4dU7/3/show/
Обновление Bounty !!!
Я опубликовал одно исправление ниже, но на самом деле он вводит ту же макетную проблему в IE9! Пожалуйста, не стесняйтесь меняться или улучшать свой ответ - или приходите к столу с чем-то совершенно другим! :)
Ответы
Ответ 1
Лом-подход и использование фоновых изображений
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 и выше.
- Удалены теги
img
и реализованы эстетика (изображения) в качестве фона - Дополнительный
span
должен был быть добавлен, потому что CSS2 допускает только 1 фоновое изображение на элемент - Знак Li держит фон стрелки; тег span держит фон перца
- Обновлен
id="change"
to class="change"
. ЕСЛИ вы на 100% уверены, что у вас будет только один элемент #change, используйте класс. Это чисто стилизация, и это мешает вам иметь два списка меню на одной странице. - Измените свой стиль CSS немного следующим образом:
Удалено верхнее заполнение и увеличена высота. Таким образом, ваши элементы li имеют одинаковую высоту, но затем добавили line-height: 35px
→ это лучший способ вертикального центра текста. Утилизация верхнего заполнения работает, но она подвержена плохой несогласованности браузера.
Измените элементы li
на float. Плавающие элементы - самый удобный для IE7 метод! Даже IE6 не будет ошибкой, но у меня нет этой старой версии, чтобы протестировать вашу веб-страницу. FYI - ul.menu должен иметь overflow: hidden
чтобы очистить поплавки.
position: relative;
cursor: default;
Если вы не изменили значения по умолчанию, вы можете сохранить эти два свойства. курсор должен быть по умолчанию. Позиция: относительная не нужна - вы не используете абсолютное позиционирование или что-либо, что оправдывает его потребность. Теперь вы можете сохранить их в своей декларации. Мне просто нравится код как "тонкий", насколько это возможно.
заключительные слова:
Взгляните на мой CSS. Обратите внимание, как я использовал ul.menu
во всей моей декларации. Вы можете захотеть привыкнуть к тому же; это дает разработчику некоторое представление о том, как выглядит HTML и что более важно - ваш css не будет отменен, если вы решите добавить <div class=menu>
позже. В частности .menu img
будет применяться к любому тегу изображения в меню div.
Хорошо, это так. Дайте мне знать, если есть какие-либо разъяснения.
FYI - видя, что у этого вопроса есть щедрость, если вы предоставите мне фоновые изображения, я могу отполировать свой код в соответствии с вашими потребностями на 100% - возможно, загрузить их в редактирование вашего ответа.
Ответ 2
Между вашими элементами есть пробел. Ни один из ваших других элементов списка не имеет этого пробела. Попробуйте удалить все пробелы между этими элементами и посмотреть, устраняет ли это вашу проблему.
Если это так, это просто означает, что ваш HTML анализирует содержимое вашего <li>
как имеющее разрыв строки - вот почему вы видите проблему. Чтобы решить эту проблему, оберните текст в <li>
с помощью <span>
. Когда ваш браузер анализирует HTML, он автоматически обрезает пробелы между тегами HTML и автоматически исправляет проблему (без потери форматирования)
Ответ 3
Это странно, но я могу воссоздать проблему в Firefox v22. Очень странная часть заключалась в том, что в jsFiddle, если я просто ударил "Tidy Up", а затем ударил "Run", и проблема была решена. Как заметил Мэтью R, это, вероятно, связано с удалением дополнительного белого пространства.
Сломанный:
Tidy Up, Run и Fixed
Здесь альтернативный метод с использованием фоновых изображений:
Рабочий пример
.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>
Ответ 4
Я думаю, что ваша проблема связана с 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;
}
Ответ 5
Чтобы устранить проблему (появление), измените вертикальное выравнивание изображений значков, содержащихся в меню:
.menu img {
display: inline;
vertical-align: top;
margin-top: 2px;
padding-right: 6px;
}
В затронутых браузерах дополнительное изображение (с display: none;
) изменяло высоту содержащего элемента. Установка display: none;
<img>
display: none;
означало, что display: inline;
установка больше не применяется и была помещена под первым изображением.
Просто наличие дополнительного <img>
отображения в строке исправляет вертикальное выравнивание, но, очевидно, не устраняет проблему, так как изображение нужно скрывать, не изменяя положение текста.
Это исправление изменяет вертикальное выравнивание от процента (-25%) до фиксированной позиции, избегая любых (ложных) различий в высоте содержащего элемента. Затем я установил верхний край изображения, чтобы получить желаемый интервал от верхнего края элемента.
Обновить
Это исправление нарушает отображение в IE9 - такое же появление, как IE7, без этого исправления.
Ответ 6
Вы допустили ошибку с линией высоты вместо 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-ссылка