prevenir: después de que el elemento se envuelva a la siguiente línea

81

Tengo este HTML:

<ul>
    <li class="completed"><a href="#">I want the icon to stay on the same line as this last <strong>word</strong></li>
</ul>

Estoy agregando un ícono usando el pseudo elemento: after:

ul li.completed a:after {
    background:transparent url(img.png) no-repeat; 
    content: '';
    display:inline-block;
    width: 24px;
    height: 16px;
}

El problema: si el ancho disponible es demasiado pequeño, el icono pasa a la siguiente línea. Me gustaría que permaneciera en la misma línea que la última palabra del enlace al que se adjunta:

ingrese la descripción de la imagen aquí

¿Es esto posible, sin agregar 'nowrap' a todo el enlace (quiero que las palabras se ajusten, pero no el ícono)?

Vea jsFiddle aquí .

ptriek
fuente
¿Podrías alterar el HTML? ¿O estás atrapado con eso?
yunzen
Sí, puedo modificar el HTML ..
ptriek

Respuestas:

16

en su lugar, puede agregar la imagen a la última palabra. eso hará que se rompa.

agregar una clase a la palabra <strong class="test">word</strong>

y .test:after { ...

http://jsfiddle.net/52dkR/

el truco también es hacer que esa clase sea inline-block

y si desea mantener el subrayado, vea esto.

http://jsfiddle.net/atcJJ/

añadir text-decoration:inherit;

btevfik
fuente
4
No creo que siempre haya una última palabra en un elemento fuerte.
yunzen
maravilloso, funciona como un encanto de hecho ... @HerrSerker el elemento fuerte fue solo para mayor claridad, inserté un <span class="icon">en cada última palabra y agregué el ícono a estospan
ptriek
@HerrSerker También hice el elemento fuerte en span en el segundo jsfiddle. Supuse que era por claridad.
btevfik
Intenté esto, lleva el elemento a la segunda línea cuando la palabra se ajusta. ¿Como funciona esto? jsfiddle.net/supriti/atcJJ/5
Supriti Panda
3
Esta respuesta no es lo suficientemente general. Espera que una etiqueta HTML específica esté siempre donde desea que esté.
Fritzmg
85

JSFiddle: http://jsfiddle.net/Bk38F/65/

Agregue un margen negativo al pseudo elemento, para compensar su ancho:

ul li.completed a:after {
    background:transparent url(img1.png) no-repeat; 
    content: ' ';
    display: inline-block;
    width: 24px;
    height: 16px;
    margin-right: -24px;
}

Ahora, eso hará que el icono se desborde del contenedor, y la línea se romperá solo cuando el texto llegue al final de la línea. Si necesita mantener el icono dentro del ancho del contenedor original, puede agregar relleno para compensar nuevamente:

ul li.completed a {
    display: inline-block;
    padding-right: 24px;
}

ACTUALIZACIÓN IMPORTANTE:

Para que este método funcione, no debe haber espacios en blanco entre el texto y la etiqueta de cierre del elemento que contiene el pseudo elemento. Aunque el ancho del pseudo elemento se compensa con un margen negativo, el espacio en blanco hará que la línea se salte cuando se encuentre con el borde del elemento principal. Por ejemplo, esto funciona:

<span>text goes here</span>

y esto no :

<span>
    text goes here
</span>
Hugo Silva
fuente
En mi opinión, esta es la solución más elegante, ya que no se requiere un marcado adicional. Mi única queja es que cualquier espacio que desee entre el icono y el texto debe agregarse a la imagen, el margen / relleno no funcionará.
brendanmckeown
este es el camino a seguir cuando se trata de celdas de tabla (donde el ancho de columna se determina en el momento de la visualización)
David J
3
@brendanmckeown si aumenta el ancho, simplemente puede cambiar la ubicación del fondo. Así width:26px;y 2px 0como posición de fondo lo movería. jsfiddle.net/Bk38F/23
Jacob Raccuia
3
@brendanmckeown: PUEDE usar el margen para hacer espacio entre el icono y el texto. Use el margen izquierdo del pseudo para hacer el espacio y haga que su margen derecho negativo sea la suma de su ancho y el margen izquierdo: {ancho: 24px; margen izquierdo: 10px; margin-right: -34px}
Rand Scullard
Esta solución no funciona. Al menos en Chrome, todavía puedo encontrar tamaños de pantalla donde el icono se ajusta antes de la última palabra. Eso simplemente no sucede tan a menudo con esta solución, pero aún es posible.
m5seppal
13

Esto es un poco similar a una respuesta anterior, pero pensé que lo desarrollaría y lo explicaría completamente.

Tan pronto como lo establezca display: inline-block, se :afterconvierte en un elemento sin enlace de texto. Es por eso que envuelve y por qué nowrap no tiene ningún efecto. Así que vetedisplay paz.

Como es un elemento de texto por defecto, el contenido se vincula al texto anterior, siempre que no haya espacios en blanco entre ellos. Así que no agregue ninguno, pero asegúrese de tenerlo content: "", o es lo mismo que display: none. El único problema es heighty widthestán controlados por el content, que en este caso está colapsado. Así widthes 0, y heightes la altura de la línea.

Cambie el tamaño del área con relleno; izquierda o derecha, no importa. Agrega un poco marginpara que el ícono no toque el texto. Mantener todo lo más tamaños relativos ( em, pt, etc.), y el uso background-size: contain, por lo que las escalas de icono con el texto, como un emoji o de la fuente. Finalmente coloque el icono donde desee background-position.

ul li.completed a:after {
  content: "";
  background: url('icon.svg');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center center;
  margin-left: 0.2em; /* spacing*/
  padding-right: 0.75em; /* sizing */
}

He usado esto para mis enlaces externos ( a[href*="://"]:after) y ha funcionado bien en Firefox, Chrome e iOS. Y dado que el icono sigue siendo un elemento de texto, incluso el texto directo después de enlazarlo, por lo que cualquier puntuación de cierre también se ajustará.

Phernost
fuente
Esto funciona muy bien para :after. ¿Alguna idea de cómo hacer que funcione :beforetambién?
Jor
6

Yo estaba teniendo el mismo problema. Realmente no me gustó la idea de agregar etiquetas fuertes o extensas a la última palabra, así que intenté simplemente agregar el ícono como una imagen de fondo con algo de relleno a la derecha en lugar de usar los pseudo elementos: after o: before. ¡Trabajó para mi!

<ul><li class="completed"><a href="#">I want the icon to stay on the same line as this last word</a></li></ul>

ul li.completed a {
background: url(img1.png) no-repeat 100% 50%;
padding-right: 18px;
}

http://jsfiddle.net/atcJJ/36/

Jason
fuente
5

Si utiliza una fuente de icono: utilizando el Unicode de "espacio sin interrupción" \00a0 junto con el contenido del pseudoelemento (en este caso, un glifo de Font Awesome).

Esto funciona sin ningún tipo de marcado adicional o formato especial o nombres de clase.

a[href^='http']::after {
  content: '\00a0\f14c';
  font-family: 'Font Awesome 5 Pro', sans-serif;
  line-height: 0;
}

La line-height: 0;parte evita que las líneas se muevan cuando se ajusta la última 'palabra + icono'.

Ejemplo de CodePen

Jase
fuente
3

Asegúrese de terminar la etiqueta antes

<ul><li class="completed"><a href="#">I want the icon to stay on the same line as this last <strong>word</strong></a></li></ul>

Pruebe el CSS a continuación. En lugar de usar "después", use "antes" y flote a la derecha.

ul li.completed a:before {
    background:transparent url(img1.png) no-repeat; 
    content: '';
    display:inline-block;
    width: 24px;
    height: 16px;
    float:right;
}

Compruebe esto: http://jsfiddle.net/supriti/atcJJ/7/

Supriti Panda
fuente
3

Es posible hacerlo sin :after. El elemento con fondo debería ser display:inline.

<h1><span>I want the icon to stay on the same line as this last word</span></h1>

h1 span {
   padding-right: 24px;
   background: url('icon.svg') no-repeat right top; 
}

http://jsfiddle.net/my97k7b1/

Svyat P.
fuente
3

Intenté esto con un botón de enlace y tuve más éxito al agregar relleno a la derecha del elemento como sugirió @Hugo Silva, luego estableciendo :: after en la posición absoluta. Esta era una solución bastante simple y parecía funcionar en los navegadores modernos.

.button {
  position: relative;
  color: #F00;
  font-size: 1.5rem;
  padding-right: 2.25rem;
}

.button::after {
  content: '>>';
  display: inline-block;
  padding-left: .75rem;
  position: absolute;
}

Aquí hay un JS Fiddle.

María7678
fuente
1

El problema se produce cuando hay espacios en blanco al final del texto del elemento, por lo que considera el icono como una palabra más. Mi solución es eliminar el espacio en blanco con javascript y ponerlo fuera del elemento. Además, de esta forma evitamos que text-decoration:underlineestilice el espacio en blanco que puede estar al final de un enlace:

$(document).ready(function () {
  $("a[href$=\".pdf\"]").each(function () {
    var endspace = /\s$/;
    if (endspace.test($(this).html())) {
      var linktx = $(this).html().replace(/\s*$/, "");
      $(this).html(linktx);
      $(this).after(" ");
    }
  });
});

En el CSS agrego un espacio sin interrupciones \00A0antes del ícono para separarlo del texto y escalar de acuerdo con el tamaño de fuente. En algunos casos, utilizar un espacio estrecho sin interrupciones \202Fofrece un mejor efecto visual:

a[href$=".pdf"]:after {
  content: "\00A0\f1c1";
  font-family: "Font Awesome 5 Pro";
}

https://jsfiddle.net/poselab/910bw7zt/8/

PoseLab
fuente
¡Wow gracias! Estuve luchando por siempre y ninguna publicación solucionó mi problema ... pero usar content: '\00A0'; fue el truco. <3
Paul Irish
0

Con mi configuración particular, la única solución de trabajo era usar la posición relativa y colocar mi elemento de icono en un intervalo con una posición absoluta. Al igual que:

h2 a {
            position: relative;
            width: auto;
}
h2 a span {
            position: absolute;
            right: -30px;
            bottom: 0;
 }
<h2>
    <a href="#">
            The arrow won't drop to the next line as an orphan, even if the text is long and responsive
         <span>&#8594;</span>
    </a>
</h2>

Archie Butler
fuente