Les éléments en ligne se déplacent lorsqu'ils sont en gras lors du survol

J'ai créé un menu horizontal en utilisant des listes HTML et CSS. Tout fonctionne comme il se doit, sauf lorsque vous survolez les liens. Vous voyez, j'ai créé un État de survol gras pour les liens, et maintenant les liens de menu se déplacent en raison de la différence de taille en gras.

Je rencontre le même problème que ce post SitePoint . Cependant, le poste n'a pas de solution appropriée. J'ai cherché partout une solution et je n'en trouve pas. Je ne peux pas être le seul à essayer de le faire ce.

Quelqu'un a-t-il des idées?

P. S: Je ne connais pas la largeur du texte dans les éléments de menu, donc je ne peux pas simplement définir la largeur des éléments li.

C'est mon code:

HTML:

<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>

CSS:

.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: #ffffff; 
    margin-left: 8px; 
    margin-right: 5px; 
}
.nav li a:hover{ 
    text-decoration: none; 
    font-weight: bold; 
}
.nav li.first { border: none; }
147
demandé sur Alex Grin 2009-02-17 13:00:59

21 réponses

li, a {
    display:inline-block;
    text-align:center;
    font: normal 14px Open Sans;
    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>

Vérifiez l'exemple de travail sur JSfiddle . L'idée est de réserver de l'espace pour le contenu en caractères gras (ou tout type d'état :hover) dans le pseudo-élément :after et d'utiliser la balise title comme source de contenu.

307
répondu 350D 2017-09-11 23:14:52

Si vous ne pouvez pas définir la largeur, cela signifie que la largeur changera à mesure que le texte devient gras. Il n'y a aucun moyen d'éviter cela, sauf par des compromis tels que la modification du remplissage/des marges pour chaque État.

27
répondu Andrew Vit 2009-02-17 10:09:28

Une solution compromise consiste à simuler bold avec text-shadow, par exemple:

a:hover{
  text-shadow:0 0 1px black, 0 0 1px black, 0 0 1px black
}

Répéter 3 fois l'ombre le fait apparaître pas tellement blurred.

24
répondu Stefan J 2013-04-03 10:51:22

Une Autre idée est d'utiliser letter-spacing

a {
  letter-spacing: 0.05px
}

a:hover, a:focus {
  font-weight: bold;
  letter-spacing: 0
}
18
répondu John Magnolia 2014-10-20 22:37:49

Une Ligne dans jquery:

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

Modifier: Bien que cela puisse apporter la solution, il convient de mentionner que cela ne fonctionne pas en conjonction avec le code dans le message d'origine. "display: inline" doit être remplacé par des paramètres flottants pour qu'un réglage de largeur soit efficace et que le menu horizontal fonctionne comme prévu.

17
répondu Alex 2012-03-09 03:01:47

Vous pouvez utiliser quelque chose comme

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

Et puis dans votre css, définissez simplement le contenu span en gras et masquez-le avec visibility: hidden, de sorte qu'il conserve ses dimensions. Ensuite, vous pouvez ajuster les marges des éléments suivants pour le faire rentrer correctement.

Je ne suis pas sûr si cette approche est SEO friendly cependant.

5
répondu monk 2012-12-04 11:17:44

Je viens de résoudre le problème avec la solution "shadow". Il semble que le plus simple et efficace.

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

Pas besoin de répéter l'ombre trois fois (le résultat était le même pour moi).

5
répondu Daniele B 2013-09-04 13:20:44

J'ai eu un problème similaire au vôtre. Je voulais que mes liens deviennent gras lorsque vous les survolez, mais pas seulement dans le menu, mais aussi dans le texte. Comme vous le devinez cen ce serait une vraie corvée de trouver toutes les différentes largeurs. La solution est assez simple:

Créez une boîte qui contient le texte du lien En gras mais coloré comme votre arrière-plan et mais votre lien réel au-dessus. Voici un exemple de ma page:

CSS:

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

Bien sûr, vous devez remplacer #FFFFE0 par le la couleur de fond de votre page. Les indices z ne semblent pas nécessaires mais je les mets quand même (car l'élément "hypo" se produira après l'élément "hyper" dans le code HTML). Maintenant, pour mettre un lien sur votre page, incluez ce qui suit:

HTML:

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

Le deuxième " ici " sera invisible et caché sous votre lien. Comme c'est une boîte statique avec votre texte de lien En gras, le reste de votre texte ne sera plus décalé car il est déjà décalé avant de survoler le lien.

J'espère que j'ai pu aider :).

Au revoir

3
répondu 2009-09-29 13:23:24

Je conseillerais de ne pas changer de polices (°) en vol stationnaire. Dans ce cas, ce ne sont que les éléments de menu qui bougent un peu, mais j'ai vu des cas où le paragraphe complet est reformaté parce que l'élargissement provoque un enveloppement de mot supplémentaire. Vous ne voulez pas que cela se produise lorsque la seule chose que vous faites est de déplacer le curseur; si vous ne faites rien, la mise en page ne devrait pas changer.

Le décalage peut également se produire lors de la commutation entre normal et italique. J'essaierais de changer les couleurs, ou de basculer le soulignement si vous avez de la place sous le texte. (le soulignement doit rester clair à partir de la bordure inférieure)

Je serais boo'D si j'utilisais des polices de commutation pour ma classe de conception de Formulaire: -)

(°) la police de mots est souvent mal utilisée. "Verdana" est un caractères, "Verdana normal" et "Verdana bold" sont différents polices de la même police de caractères.

2
répondu stevenvh 2009-02-17 11:26:33

Vous pouvez travailler avec la propriété "margin":

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

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

Assurez-vous que les marges gauche et droite sont suffisamment gros pour l'espace supplémentaire peut contenir le texte en gras. Pour les mots longs, vous pouvez choisir des marges différentes. C'est juste une autre solution de contournement, mais faire le travail pour moi.

2
répondu Martin Horvath 2016-03-04 17:50:42

Solution CSS3-expérimentale

(fausse audace)

Pensé partager une solution différente que personne n'a suggéré ici. Il y a une propriété appelée text-stroke qui sera pratique pour cela.

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

Ici, je cible le texte à l'intérieur de la balise span et nous le caressons par un pixel avec black qui simulera le style bold pour ce texte particulier.

Notez que cette propriété n'est pas largement supportée, à ce jour (en écrivant ceci réponse), seuls Chrome et Firefox semblent soutenir cela. Pour plus d'informations sur le support du navigateur pour text-stroke, Vous pouvez vous référer à CanIUse.


Juste pour partager des trucs supplémentaires, vous pouvez utiliser -webkit-text-stroke-width: 1px; Si vous ne cherchez pas à définir un color pour votre course.

2
répondu Mr. Alien 2016-06-02 10:59:01

J'aime utiliser text-shadow à la place. Surtout parce que vous pouvez utiliser des transitions pour animer l'ombre de texte.

Tout ce dont vous avez vraiment besoin est:

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

Pour une navigation complète, consultez ce jsfiddle: https://jsfiddle.net/831r3yrb/

Prise en charge du navigateur et plus d'informations sur text-shadow: http://www.w3schools.com/cssref/css3_pr_text-shadow.asp

1
répondu Lightningsoul 2016-11-30 09:30:30

C'est la solution que je préfère. Cela nécessite un peu de JS mais vous n'avez pas besoin que votre propriété title soit exactement la même et votre CSS peut rester très simple.

$('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>
0
répondu lurkit 2015-03-23 20:27:32

Et ça? Une solution gratuite javascript-CSS3.

Http://jsfiddle.net/u1aks77x/1/

ul{}
li{float:left; list-style-type:none; }
a{position:relative; padding-right: 10px; text-decoration:none;}
a > .l1{}
a:hover > .l1{visibility:hidden;}
a:hover > .l2{display:inline;}
a > .l2{position: absolute; left:0; font-weight:bold; display:none;}

<ul>
  <li><a href="/" title="Home"><span class="l1">Home</span><span class="l2">Home</span></a></li>
  <li><a href="/" title="Contact"><span class="l1">Contact</span><span class="l2">Contact</span></a></li>
  <li><a href="/" title="Sitemap"><span class="l1">Sitemap</span><span class="l2">Sitemap</span></a></li>
</ul>
0
répondu user10099 2015-12-04 01:02:09

Solution pas très élégante, mais "fonctionne":

a
{
    color: #fff;
}

a:hover
{
    text-shadow: -1px 0 #fff, 0 1px #fff, 1px 0 #fff, 0 -1px #fff;
}
0
répondu Świeżu 2017-01-10 15:45:40

J'ai combiné un tas de techniques ci-dessus pour fournir quelque chose qui ne craint pas totalement avec js désactivé et qui est encore mieux avec un peu de jQuery. Maintenant que le support des navigateurs pour l'espacement des lettres sous-pixels s'améliore, c'est vraiment agréable de l'utiliser.

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
répondu squarecandy 2017-04-27 15:57:58

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
répondu Qwertiy 2017-05-16 22:32:54

Si vous n'êtes pas opposé à L'utilisation de Javascript, vous pouvez définir la largeur appropriée une fois la page affichée. Voici comment je l'ai fait (en utilisant le Prototype):

$$('ul.nav li').each(this.setProperWidth);

setProperWidth: function(li)
{
  // Prototype's getWidth() includes padding, so we 
  // have to subtract that when we set the width.
  var paddingLeft = li.getStyle('padding-left'),
      paddingRight = li.getStyle('padding-right');

  // Cut out the 'px' at the end of each padding
  paddingLeft = paddingLeft.substring(0,paddingLeft.length-2);
  paddingRight = paddingRight.substring(0,paddingRight.length-2);

  // Make the li bold, set the width, then unbold it
  li.setStyle({ fontWeight: 'bold' });
  li.setStyle({ width: (li.getWidth() - paddingLeft - paddingRight) + 'px'});
  li.setStyle({ fontWeight: 'normal', textAlign: 'center' });
}
-1
répondu Alex Grin 2009-12-10 16:46:11

Je ne peux vraiment pas le supporter quand quelqu'un vous dit de ne pas faire quelque chose de cette façon quand il y a une solution simple au problème. Je ne suis pas sûr des éléments li, Mais je viens de résoudre le même problème. J'ai un menu composé de balises div.

Définissez simplement la balise div sur "display: inline-block". En ligne de sorte qu'ils sont assis à côté de l'autre et le bloc à ce que vous pouvez définir une largeur. Il suffit de définir la largeur assez large pour accueillir le texte en gras et avoir le centre de texte aligné.

(Note: Il semble enlever mon html [ci-dessous], mais chaque élément de menu avait une balise div enroulée autour de lui avec l'ID corrasponding et le nom de classe SearchBar_Cateogory. c'est à dire: <div id="ROS_SearchSermons" class="SearchBar_Category">

HTML (J'avais des balises d'ancrage enroulées autour de chaque élément de menu, mais je n'étais pas en mesure de les soumettre en tant que nouvel utilisateur)

<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;
}
-1
répondu Jørn Schou-Rode 2011-03-22 19:15:12

Vous pouvez également essayer les marges négatives si le texte en gras est plus large que le texte normal. (pas toujours) L'idée est donc d'utiliser des classes à la place pour styliser l'état: 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;
}

J'espère pouvoir vous aider!

-2
répondu Robert Bokori 2014-08-07 17:39:15

Voici une idée pour un plugin jquery:

for all of the elements that you want bold mouse-over:
    - on mouseover:
        - calculate the width W and center C of the element
        - copy the element and hide the original with visibility:hidden (so it still takes up the same space)
        - make the text of the copied element bold and calculate the new width W2
        - position the element absolute left at C-(W2/2)

Vous pouvez facilement étendre cela pour la hauteur, ce qui permet d'augmenter légèrement la taille de la police sur mouseover sans avoir à vous soucier de sauter le contenu.

-4
répondu Jules Colle 2013-03-13 10:30:42