Смещение встроенных элементов при выделении жирным шрифтом при наведении - PullRequest
166 голосов
/ 17 февраля 2009

Я создал горизонтальное меню, используя списки HTML и CSS. Все работает как надо, кроме случаев, когда вы наводите курсор мыши на ссылки. Видите ли, я создал состояние полужирного наведения для ссылок, и теперь ссылки меню меняются из-за разницы в полужирном размере.

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

У кого-нибудь есть идеи?

P.S .: Я не знаю ширину текста в пунктах меню, поэтому я не могу просто установить ширину элементов li.

.nav { margin: 0; padding: 0; }
.nav li { 
    list-style: none; 
    display: inline; 
    border-left: #ffffff 1px solid; 
}
.nav li a:link, .nav li a:visited { 
    text-decoration: none; 
    color: #000; 
    margin-left: 8px; 
    margin-right: 5px; 
}
.nav li a:hover{ 
    text-decoration: none; 
    font-weight: bold; 
}
.nav li.first { border: none; }
<ul class="nav">
    <li class="first"><a href="#">item 0</a></li>
    <li><a href="#">item 1</a></li>
    <li><a href="#">item 2</a></li>
    <li><a href="#">item 3</a></li>
    <li><a href="#">item 4</a></li>
</ul>

Ответы [ 24 ]

2 голосов
/ 07 апреля 2012

Вы можете работать со свойством margin:

li a {
  margin: 0px 5px 0px 5px;
}

li a:hover {
  margin: 0;
  font-weight: bold;
}

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

1 голос
/ 30 ноября 2016

Мне нравится использовать вместо текста тень. Тем более, что вы можете использовать переходы для анимации тени текста.

Все, что вам действительно нужно, это:

a {
  transition: text-shadow 1s;
}
a:hover {
  text-shadow: 1px 0 black;
}

Для полной навигации проверьте это jsfiddle: https://jsfiddle.net/831r3yrb/

Поддержка браузера и дополнительная информация о тени текста: http://www.w3schools.com/cssref/css3_pr_text-shadow.asp

0 голосов
/ 17 мая 2017

ul {
  list-style-marker: none;
  padding: 0;
}

li {
  display: inline-block;
}

li + li {
  margin-left: 1em;
}

a {
  display: block;
  position: relative;
  text-align: center;
}

a:before, a:after {
  content: attr(aria-label);
  text-decoration: inherit;
}

a:before {
  font-weight: bold;
  visibility: hidden;
}

a:after {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}

a:hover:before {
  visibility: visible;
}

a:hover:after {
  display: none;
}
<ul>
  <li>
    <a href="" aria-label="Long-long-long"></a>
  </li><li>
    <a href="" aria-label="or"></a>
  </li><li>
    <a href="" aria-label="Short"></a>
  </li><li>
    <a href="" aria-label="Links"></a>
  </li><li>
    <a href="" aria-label="Here"></a>
  </li>
</ul>
0 голосов
/ 27 апреля 2017

Я объединил кучу методов, приведенных выше, чтобы обеспечить что-то, что не полностью отстой при отключенном js и даже лучше с небольшим количеством jQuery. Теперь, когда поддержка браузерами субпиксельного межбуквенного интервала улучшается, его очень приятно использовать.

jQuery(document).ready(function($) {
  $('.nav a').each(function(){
      $(this).clone().addClass('hoverclone').fadeTo(0,0).insertAfter($(this));
    var regular = $(this);
    var hoverclone = $(this).next('.hoverclone');
    regular.parent().not('.current_page_item').hover(function(){
      regular.filter(':not(:animated)').fadeTo(200,0);
      hoverclone.fadeTo(150,1);
    }, function(){
      regular.fadeTo(150,1);
      hoverclone.filter(':not(:animated)').fadeTo(250,0);
    });
  });
});
ul {
  font:normal 20px Arial;
  text-align: center;
}
li, a {
  display:inline-block;
  text-align:center;
}
a {
  padding:4px 8px;
  text-decoration:none;
  color: #555;
}

.nav a {
  letter-spacing: 0.53px; /* adjust this value per font */
}
.nav .current_page_item a,
.nav a:hover {
  font-weight: bold;
  letter-spacing: 0px;
}
.nav li {
  position: relative;
}
.nav a.hoverclone {
  position: absolute;
  top:0;
  left: 0;
  white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="nav">
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a></li>
  <li class="current_page_item"><a  href="#">Item 3</a></li>
  <li><a href="#">Item 4</a></li>
  <li><a href="#">Item 5</a></li>
</ul>
0 голосов
/ 10 января 2017

Не очень элегантное решение, но «работает»:

a
{
    color: #fff;
}

a:hover
{
    text-shadow: -1px 0 #fff, 0 1px #fff, 1px 0 #fff, 0 -1px #fff;
}
0 голосов
/ 15 мая 2019

Альтернативным подходом было бы «эмулировать» жирный текст с помощью text-shadow. Это имеет бонус (/ malus, в зависимости от вашего случая), чтобы работать также на иконки шрифтов.

   nav li a:hover {
      text-decoration: none;
      text-shadow: 0 0 1px; /* "bold" */
   }

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

0 голосов
/ 07 августа 2014

Вы можете попробовать и отрицательные поля, если полужирный текст шире обычного. (не всегда) Поэтому идея состоит в том, чтобы вместо этого использовать классы для стилизации состояния: hover.

JQuery:

 $(".nav-main .navbar-collapse > ul > li > a").hover(function() {
    var originalWidth = $(this).outerWidth();

    $(this).parent().addClass("hover");
    $(this).css({
       "margin-left": -(($(this).outerWidth() - originalWidth) / 2),
       "margin-right": -(($(this).outerWidth() - originalWidth) / 2)
    });
 },
 function() {
    $(this).removeAttr("style");
    $(this).parent().removeClass("hover");
 });

CSS:

ul > li > a {
    font-style: normal;
}

ul > li > a.hover {
    font-style: bold;
}

Я надеюсь, что смогу помочь!

0 голосов
/ 10 июня 2009

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

Просто установите тег div на «display: inline-block». Встроенный, чтобы они сидели рядом друг с другом и заблокировать, чтобы вы могли установить ширину. Просто установите ширину, достаточную для размещения текста, выделенного жирным шрифтом, и выровняйте текстовый центр по центру.

(Примечание. Кажется, что он удаляет мой html [ниже], но каждый элемент меню имеет тег div, обернутый вокруг него с соответствующим идентификатором и именем класса SearchBar_Cateogory. Т.е.

HTML (У меня были привязанные теги вокруг каждого пункта меню, но я не смог отправить их как новый пользователь)

<div id="ROS_SearchSermons" class="SearchBar_Cateogry bold">Sermons</div>|
<div id="ROS_SearchIllustrations" class="SearchBar_Cateogry">Illustrations</div>|
<div id="ROS_SearchVideos" class="SearchBar_Cateogry">Videos</div>|
<div id="ROS_SearchPowerPoints" class="SearchBar_Cateogry">PowerPoints</div>|
<div id="ROS_SearchScripture" class="SearchBar_Cateogry">Scripture</div>|

CSS:

#ROS_SearchSermons { width: 75px; }
#ROS_SearchIllustrations { width: 90px; }
#ROS_SearchVideos { width: 55px; }
#ROS_SearchPowerPoints { width: 90px; }
#ROS_SearchScripture { width: 70px; }

.SearchBar_Cateogry
{
    display: inline-block;
    text-align:center;
}
0 голосов
/ 07 октября 2018

попробуйте это:

.nav {
  font-family: monospace;
}
0 голосов
/ 23 марта 2015

Это решение, которое я предпочитаю. Требуется немного JS, но вам не нужно, чтобы ваше свойство title было таким же, и ваш CSS может оставаться очень простым.

$('ul a').each(function() {
  $(this).css({
    'padding-left': 0,
    'padding-right': 0,
    'width': $(this).outerWidth()
  });
});
li, a { display: inline-block; }
a {
  padding-left: 10px;
  padding-right: 10px;
  text-align: center; /* optional, smoother */
}
a:hover { font-weight: bold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
  <li><a href="#">item 1</a></li>
  <li><a href="#">item 2</a></li>
  <li><a href="#">item 3</a></li>
</ul>
...