Смещение встроенных элементов при выделении жирным шрифтом при наведении - 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 ]

341 голосов
/ 27 ноября 2013

li {
    display: inline-block;
    font-size: 0;
}
li a {
    display:inline-block;
    text-align:center;
    font: normal 16px Arial;
    text-transform: uppercase;
}
a:hover {
    font-weight:bold;
}
a::after {
    display: block;
    content: attr(title);
    font-weight: bold;
    height: 0;
    overflow: hidden;
    visibility: hidden;
}
<ul>
    <li><a href="#" title="height">height</a></li>
    <li><a href="#" title="icon">icon</a></li>
    <li><a href="#" title="left">left</a></li>
    <li><a href="#" title="letter-spacing">letter-spacing</a></li>
    <li><a href="#" title="line-height">line-height</a></li>
</ul>

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

34 голосов
/ 03 апреля 2013

Скомпрометированное решение состоит в том, чтобы подделать жирный шрифт с текстовой тенью, например:

text-shadow: 0 0 0.01px чёрный;

Для лучшего сравнения я создал следующие примеры:

a, li {
  color: black;
  text-decoration: none;
  font: 18px sans-serif;
  letter-spacing: 0.03em;
}
li {
  display: inline-block;
  margin-right: 20px;
  color: gray;
  font-size: 0.7em;
}
.bold-x1 a.hover:hover,
.bold-x1 a:not(.hover) {
  text-shadow: 0 0 .01px black;
}
.bold-x2 a.hover:hover,
.bold-x2 a:not(.hover){
  text-shadow: 0 0 .01px black, 0 0 .01px black;
}
.bold-x3 a.hover:hover,
.bold-x3 a:not(.hover){
  text-shadow: 0 0 .01px black, 0 0 .01px black, 0 0 .01px black;
}
.bold-native a.hover:hover,
.bold-native a:not(.hover){
  font-weight: bold;
}

.bold-native li:nth-child(4),
.bold-native li:nth-child(5){
 margin-left: -6px;
 letter-spacing: 0.01em;
}
<ul class="bold-x1">
  <li><a class="hover" href="#">Home</a></li>
  <li><a class="hover" href="#">Products</a></li>
  <li><a href="#">Contact</a></li>
  <li><a href="#">About</a></li>
  <li>Bold (text-shadow x1)</li>
</ul>
<ul class="bold-x2">
  <li><a class="hover" href="#">Home</a></li>
  <li><a class="hover" href="#">Products</a></li>
  <li><a href="#">Contact</a></li>
  <li><a href="#">About</a></li>
  <li>Extra Bold (text-shadow x2)</li>
</ul>
<ul class="bold-native">
  <li><a class="hover" href="#">Home</a></li>
  <li><a class="hover" href="#">Products</a></li>
  <li><a href="#">Contact</a></li>
  <li><a href="#">About</a></li>
  <li>Bold (native)</li>
</ul>
<ul class="bold-x3">
  <li><a class="hover" href="#">Home</a></li>
  <li><a class="hover" href="#">Products</a></li>
  <li><a href="#">Contact</a></li>
  <li><a href="#">About</a></li>
  <li>Black (text-shadow x3)</li>
</ul>

Переход к text-shadow действительно низкому значению для blur-radius сделает эффект размытия не столь очевидным.

В целом, чем больше вы повторяете text-shadow, тем смелее будет получать ваш текст, но в то же время теряет первоначальную форму букв.

Я должен предупредить вас, что установка дроби blur-radius не будет отображаться одинаково во всех браузерах! Например, для Safari нужны большие значения, чтобы отобразить его так же, как в Chrome.

27 голосов
/ 17 февраля 2009

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

19 голосов
/ 21 октября 2014

Другая идея использует letter-spacing

a {
  letter-spacing: 0.05px
}

a:hover, a:focus {
  font-weight: bold;
  letter-spacing: 0
}
17 голосов
/ 29 октября 2010

Одна строка в jquery:

$('ul.nav li a').each(function(){
    $(this).parent().width($(this).width() + 4);
});

редактирование: Хотя это может привести к решению, следует отметить, что оно не работает в сочетании с кодом в исходном посте. «display: inline» должен быть заменен плавающими параметрами, чтобы настройка ширины была эффективной и чтобы горизонтальное меню работало как задумано.

5 голосов
/ 04 сентября 2013

Я только что решил проблему с "теневым" решением. Кажется, самый простой и эффективный.

nav.mainMenu ul li > a:hover, nav.mainMenu ul li.active > a {
    text-shadow:0 0 1px white;
}

Нет необходимости повторять тень три раза (результат был для меня одинаковым).

5 голосов
/ 04 декабря 2012

Вы можете использовать что-то вроде

<ul>
   <li><a href="#">Some text<span><br />Some text</span></a></li>
</ul>

, а затем в вашем CSS просто установите содержимое диапазона жирным шрифтом и скрыть его с видимостью: скрытый, чтобы он сохранял свои размеры. Затем вы можете отрегулировать поля следующих элементов, чтобы они правильно поместились.

Я не уверен, что этот подход оптимизирован для SEO.

4 голосов
/ 02 июня 2016

Решение CSS3 - Экспериментальное

(Поддельная смелость)

Мысль поделиться другим решением, которое никто не предложил здесь. Для этого подойдет свойство text-stroke.

p span:hover {
  -webkit-text-stroke: 1px black;
}
<p>Some stuff, <span>hover this,</span> it's cool</p>

Здесь я нацеливаюсь на текст внутри тега span и обводим его пикселем с помощью black, который будет имитировать стиль bold для этого конкретного текста.

Обратите внимание, что это свойство широко не поддерживается, и на данный момент (при написании этого ответа) только Chrome и Firefox поддерживают это. Для получения дополнительной информации о поддержке браузера для text-stroke, вы можете обратиться к CanIUse .


Просто для того, чтобы поделиться некоторыми дополнительными вещами, вы можете использовать -webkit-text-stroke-width: 1px;, если вы не хотите устанавливать color для своего удара.

4 голосов
/ 29 сентября 2009

У меня была проблема, похожая на вашу. Я хотел, чтобы мои ссылки выделялись жирным шрифтом, когда вы наводите курсор на них, но не только в меню, но и в тексте. Как вы можете догадаться, это была бы настоящая рутина, вычисляющая все ширины. Решение довольно простое:

Создайте коробку, которая содержит текст ссылки, выделенный жирным шрифтом, но цветной, как фон, но реальная ссылка над ним. Вот пример с моей страницы:

CSS:

.hypo { font-weight: bold; color: #FFFFE0; position: static; z-index: 0; }
.hyper { position: absolute; z-index: 1; }

Конечно, вам нужно заменить # FFFFE0 на цвет фона вашей страницы. По-видимому, z-индексы не нужны, но я все равно их помещаю (так как элемент «гипо» будет появляться после элемента «гипер» в HTML-коде). Теперь, чтобы разместить ссылку на своей странице, добавьте следующее:

HTML:

You can find foo <a href="http://bar.com" class="hyper">here</a><span class="hypo">here</span>

Второе «здесь» будет невидимым и скрытым под вашей ссылкой. Так как это статическая коробка с текст ссылки выделен жирным шрифтом, остальная часть текста больше не будет смещаться, поскольку она уже смещена до того, как вы наведете курсор на ссылку.

Надеюсь, я смог помочь:).

Так долго

2 голосов
/ 17 февраля 2009

Я бы не советовал переключать шрифты (°) при наведении курсора. В этом случае это просто перемещение пунктов меню, но я видел случаи, когда полный абзац переформатируется, потому что расширение вызывает дополнительную перенос слов. Вы не хотите, чтобы это произошло, когда единственное, что вы делаете, это перемещаете курсор; если вы ничего не делаете, макет страницы не должен меняться.

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

Мне бы понравилось, если бы я использовал переключающие шрифты для своего класса дизайна форм: -)

(°) Слово шрифт часто используется неправильно. «Verdana» - это гарнитура , «Verdana normal» и «Verdana bold» - это разные шрифты одного шрифта.

...