Determinar el ancho de una cadena impresa mediante una aplicación web
-
09-06-2019 - |
Pregunta
En mi aplicación web (PHP), tengo una parte de mi sitio que mantiene un historial de búsquedas recientes.Las consultas más recientes se muestran en un cuadro lateral.Si el texto de la consulta es demasiado largo, lo trunco y muestro puntos suspensivos.P.ej:"Mi consulta muy larga es..."
Actualmente, trunco después de una cierta cantidad de caracteres.Dado que la fuente no es monotipo, una consulta de todas las íes es más limitada que una consulta de todas las W.Me gustaría que todos tuvieran aproximadamente el mismo ancho antes de las elipses.¿Hay alguna manera de obtener el ancho aproximado de la cadena resultante de modo que las elipses de cualquier cadena determinada aparezcan aproximadamente en la misma cantidad de píxeles desde el principio?¿CSS tiene alguna manera?¿PHP?¿Esto se manejaría mejor con JavaScript?
Solución
¡Aquí hay otra versión y no tienes que vivir sin puntos suspensivos!
<html>
<head>
<style>
div.sidebox {
width: 25%;
}
div.sidebox div.qrytxt {
height: 1em;
line-height: 1em;
overflow: hidden;
}
div.sidebox div.qrytxt span.ellipsis {
float: right;
}
</style>
</head>
<body>
<div class="sidebox">
<div class="qrytxt">
<span class="ellipsis">…</span>
Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
<span class="ellipsis">…</span>
Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
<span class="ellipsis">…</span>
Short text. Fail!
</div>
</body>
</html>
Hay un defecto en esto: si el texto es lo suficientemente corto como para mostrarse por completo, las elipses también se mostrarán.
[EDITAR:26/06/2009]
Por sugerencia de Power-Coder he revisado esto un poco.En realidad sólo hay dos cambios, la adición del doctype
(ver notas a continuación) y la adición del display: inline-block
atributo en el .qrytxt
DIV.Así es como se ve ahora...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style>
div.sidebox
{
width: 25%;
}
div.sidebox div.qrytxt
{
height: 1em;
line-height: 1em;
overflow: hidden;
display: inline-block;
}
div.sidebox div.qrytxt span.ellipsis
{
float: right;
}
</style>
</head>
<body>
<div class="sidebox">
<div class="qrytxt">
<span class="ellipsis">…</span>
Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
<span class="ellipsis">…</span>
Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
<span class="ellipsis">…</span>
Short text. FTW
</div>
</div>
</body>
</html>
Notas:
Visto en IE 8.0, Opera 9, FF 3
A
doctype
es necesario para que IE obtenga eldisplay: inline-block
para funcionar correctamente.Si el
.qrytxt
El desbordamiento de DIV ocurre en una palabra larga, habrá una gran brecha entre los puntos suspensivos y la última palabra visible.Puede ver esto viendo el ejemplo y cambiando el tamaño del ancho de su navegador en pequeños incrementos.(Esto probablemente también existía en el ejemplo original, pero es posible que no lo haya notado en ese momento)
De nuevo, una solución imperfecta solo de CSS.Javascript puede ser lo único que puede lograr un efecto perfecto.
[EDITAR:27/06/2009]
Aquí hay otra alternativa que utiliza extensiones específicas del navegador.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style>
div.sidebox
{
width: 26%;
}
div.sidebox div.qrytxt
{
height: 1em;
line-height: 1em;
overflow: hidden;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
-ms-text-overflow:ellipsis;
-moz-binding:url(ellipsis-xbl.xml#ellipsis);
white-space:nowrap;
}
</style>
</head>
<body>
<div class="sidebox">
<div class="qrytxt">
Some long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
Some more long text which will arbitrarily be cut off at whatever word fits best but will have an ellipsis at the end.
</div>
<div class="qrytxt">
Short text. FTW
</div>
</div>
</body>
</html>
Tenga en cuenta que para que el ejemplo anterior funcione, debe crear el archivo xml al que hace referencia la regla -moz-binding, puntos suspensivos-xbl.xml.Debe contener el siguiente xml:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xbl="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="ellipsis">
<content>
<xul:window>
<xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
</xul:window>
</content>
</binding>
</bindings>
Otros consejos
También puedes usar bastante fácilmente un poco de javascript:
document.getElementByID("qrytxt").offsetWidth;
le dará el ancho de un elemento en píxeles e incluso funciona en IE6.Si agrega un intervalo que contiene elipses al final de cada consulta, se podría usar una prueba lógica simple en JavaScript con un poco de manipulación de CSS para ocultarlas/mostrarlas según sea necesario.
¿CSS tiene alguna manera?
No
¿PHP?
No
-
Para hacer eso, tendrías que obtener las métricas de fuente para cada carácter y aplicarlas a todas las letras de tu cadena.Si bien podría hacer esto usando una biblioteca de dibujo/renderizado como ImageMagick en el servidor, en realidad no funcionaría porque diferentes navegadores en diferentes sistemas operativos procesan las fuentes de manera diferente.
Incluso si funcionara, no querrías hacerlo, porque también tardaría una eternidad en renderizarse.Su servidor podría enviar 1 página por segundo (si es así) en lugar de varios miles.
Si puedes vivir sin el rastro..., entonces puedes fingirlo usando div
etiquetas y css overflow: hidden
, como esto:
.line_of_text {
height:1.3em;
line-height:1.3em;
overflow:hidden;
}
<div class="line_of_text"> Some long text which will arbitrarily be cut off at whatever word fits best</div>
PHP debe dejarse completamente fuera de consideración debido al hecho de que, aunque existe una función diseñada para medir fuentes, http://www.php.net/imageftbbox , PHP no tiene forma de saber si el visitante tiene un tamaño de fuente mínimo configurado que sea mayor que el tamaño de fuente anticipado.
@Roberto
¿Qué pasa si pones las elipses en un div con un nivel bajo? z-index
¿De modo que cuando se mueve hacia la izquierda (para líneas más cortas) queden cubiertas por una imagen de fondo o algo así?
Es bastante complicado, lo sé, pero vale la pena intentarlo, ¿verdad?
editar Otra idea:determinar la posición del div que contiene las elipses con javascript y, si no está completamente presionado, ¿ocultarlo?