Los elementos en línea se desplazan cuando se hacen en negrita al flotar


He creado un menú horizontal usando listas HTML y CSS. Todo funciona como debería, excepto cuando pasas el cursor sobre los enlaces. Verás, creé un estado de desplazamiento en negrita para los enlaces, y ahora los enlaces del menú cambian debido a la diferencia de tamaño en negrita.

Encuentro el mismo problema que este post de SitePoint. Sin embargo, el puesto no tiene solución adecuada. He buscado por todas partes una solución y no puedo encontrar una. Seguramente no puedo ser el único tratando de hacer este.

¿alguien tiene alguna idea?

P.d.: No conozco el ancho del texto en los elementos del menú, así que no puedo simplemente establecer el ancho de los elementos li.

Este es mi código:

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; }
Author: Alex Grin, 2009-02-17

21 answers

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>

Compruebe el ejemplo de trabajo en JSfiddle. La idea es reservar espacio para el contenido en negrita (o cualquier estilo de estado :hover) en el pseudo elemento :after y usar la etiqueta de título como fuente de contenido.

 307
Author: 350D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-11 23:14:52

Si no puede establecer el ancho, entonces eso significa que el ancho cambiará a medida que el texto se ponga en negrita. No hay manera de evitar esto, excepto por compromisos como modificar el relleno/márgenes para cada estado.

 27
Author: Andrew Vit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-17 10:09:28

Una solución comprometida es falsificar negrita con sombra de texto, por ejemplo:

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

Repetir 3 veces la sombra hace que no parezca mucho azulado.

 24
Author: Stefan J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-03 10:51:22

Otra idea es usar letter-spacing

a {
  letter-spacing: 0.05px
}

a:hover, a:focus {
  font-weight: bold;
  letter-spacing: 0
}
 18
Author: John Magnolia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-20 22:37:49

Una línea en jquery:

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

editar: Si bien esto puede traer la solución, uno debe mencionar que no funciona en conjunto con el código en el post original. "display: inline" tiene que ser reemplazado con parámetros flotantes para que un ajuste de ancho sea efectivo y ese menú horizontal funcione como se pretende.

 17
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-09 03:01:47

Podrías usar algo como

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

Y luego en tu css simplemente establece el contenido span en negrita y escóndelo con visibility: hidden, para que mantenga sus dimensiones. Luego puede ajustar los márgenes de los siguientes elementos para que se ajusten correctamente.

Sin embargo, no estoy seguro de si este enfoque es amigable con el SEO.

 5
Author: monk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-04 11:17:44

Acabo de resolver el problema con la solución "sombra". Parece el más simple y eficaz.

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

No es necesario repetir la sombra tres veces (el resultado fue el mismo para mí).

 5
Author: Daniele B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-04 13:20:44

Tuve un problema similar al tuyo. Quería que mis enlaces se pusieran en negrita al pasar el cursor sobre ellos, pero no solo en el menú sino también en el texto. Como usted cen supongo que sería una verdadera tarea averiguar todos los diferentes anchos. La solución es bastante simple:

Cree un cuadro que contenga el texto del enlace en negrita pero coloreado como su fondo y pero su enlace real por encima de él. He aquí un ejemplo de mi página:

CSS:

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

Por supuesto, debe reemplazar #FFFFE0 por el color de fondo de su página. Los índices z no parecen ser necesarios, pero los pongo de todos modos (ya que el elemento "hypo" ocurrirá después del elemento "hyper" en el código HTML). Ahora, para poner un enlace en su página, incluya lo siguiente:

HTML:

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

El segundo "aquí" será invisible y oculto debajo de tu enlace. Como esta es una caja estática con el texto del enlace en negrita, el resto del texto ya no cambiará, ya que ya está desplazado antes de pasar el cursor sobre el enlace.

Espero haber sido capaz de ayudar :).

Hasta luego

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-29 13:23:24

Aconsejaría no cambiar las fuentes(°) en el hover. En este caso, solo los elementos del menú se mueven un poco, pero he visto casos en los que el párrafo completo se reformatea porque la ampliación causa un ajuste de línea adicional. No quieres que esto suceda cuando lo único que haces es mover el cursor; si no haces nada, el diseño de la página no debería cambiar.

El cambio también puede ocurrir cuando se cambia entre normal y cursiva. Intentaría cambiar los colores, o cambiar el subrayado si tienes espacio debajo del texto. (el subrayado debe permanecer claro desde el borde inferior)

Sería abucheado si usara cambiar fuentes para mi clase de Diseño de Formulario: -)

(°) La fuente de la palabra es a menudo mal utilizada. "Verdana" es una tipografía , "Verdana normal" y "Verdana bold" son diferentes fuentes de la misma tipografía.

 2
Author: stevenvh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-17 11:26:33

Puede trabajar con la propiedad" margin":

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

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

Solo asegúrese de que los márgenes izquierdo y derecho sean lo suficientemente grandes para que el espacio adicional pueda contener el texto en negrita. Para palabras largas, puede elegir diferentes márgenes. Es solo otra solución, pero haciendo el trabajo por mí.

 2
Author: Martin Horvath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-04 17:50:42

Solución de CSS3 - Experimental

(Audacia falsa)

Pensó compartir una solución diferente que nadie sugirió aquí. Hay una propiedad llamada text-stroke que será útil para esto.

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

Aquí, estoy apuntando al texto dentro de la etiqueta span y lo trazo por un píxel con black que simulará el estilo bold para ese texto en particular.

Tenga en cuenta que esta propiedad no está ampliamente soportada, a partir de ahora (mientras escribe esto respuesta), solo Chrome y Firefox parece apoyar esto. Para obtener más información sobre el soporte del navegador para text-stroke, puede consultar CanIUse.


Solo para compartir algunas cosas adicionales, puede usar -webkit-text-stroke-width: 1px; si no está buscando establecer un color para su trazo.

 2
Author: Mr. Alien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-02 10:59:01

Me gusta usar sombra de texto en su lugar. Especialmente porque puede usar transiciones para animar la sombra de texto.

Todo lo que realmente necesitas es:

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

Para una navegación completa echa un vistazo a este jsfiddle: https://jsfiddle.net/831r3yrb /

Soporte del navegador y más información sobre text-shadow: http://www.w3schools.com/cssref/css3_pr_text-shadow.asp

 1
Author: Lightningsoul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-30 09:30:30

Esta es la solución que prefiero. Requiere un poco de JS, pero no necesita que su propiedad de título sea exactamente la misma y su CSS puede seguir siendo muy 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
Author: lurkit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-23 20:27:32

¿Qué pasa con esto? Una solución libre de 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
Author: user10099,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-04 01:02:09

No es una solución muy elegante, pero"funciona":

a
{
    color: #fff;
}

a:hover
{
    text-shadow: -1px 0 #fff, 0 1px #fff, 1px 0 #fff, 0 -1px #fff;
}
 0
Author: Świeżu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 15:45:40

He combinado un montón de las técnicas anteriores para proporcionar algo que no apesta totalmente con js desactivado y es aún mejor con un poco de jQuery. Ahora que el soporte de los navegadores para el espacio entre letras subpíxeles está mejorando, es realmente agradable usarlo.

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
Author: squarecandy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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
Author: Qwertiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 22:32:54

Si no eres reacio a usar Javascript, puedes establecer el ancho adecuado una vez que se muestre la página. Así es como lo hice (usando 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
Author: Alex Grin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-10 16:46:11

Realmente no puedo soportar cuando alguien te dice que no hagas algo de esa manera cuando hay una solución simple al problema. No estoy seguro de los elementos de li, pero acabo de solucionar el mismo problema. Tengo un menú que consiste en etiquetas div.

Simplemente configure la etiqueta div para que sea "display: inline-block". En línea por lo que se sientan uno al lado del otro y bloquear a que se puede establecer un ancho. Simplemente establezca el ancho lo suficientemente ancho como para acomodar el texto en negrita y alinee el centro de texto.

(Nota: Se parece estar eliminando mi html [abajo], pero cada elemento del menú tenía una etiqueta div envuelta alrededor con el ID de corrasponding y el nombre de clase SearchBar_Cateogory. ie: <div id="ROS_SearchSermons" class="SearchBar_Category">

HTML (Tenía etiquetas de anclaje envueltas alrededor de cada elemento del menú, pero no pude enviarlas como un nuevo usuario)

<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
Author: Jørn Schou-Rode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-22 19:15:12

También puede probar los márgenes negativos si el texto en negrita es más ancho que el normal. (no siempre) Así que la idea es usar clases en su lugar para estilizar el estado: hover.

[2]} 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;
}

¡Espero poder ayudar!

 -2
Author: Robert Bokori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-07 17:39:15

Aquí hay una idea para un plugin de 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)

También podría extender esto fácilmente para la altura, lo que permite aumentar ligeramente el tamaño de la fuente al pasar el ratón sin tener que preocuparse por saltar contenido.

 -4
Author: Jules Colle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-13 10:30:42