34 votes

Sans JavaScript, puis-je afficher un texte différent lorsqu'un texte plus long ne convient pas?

Ce que j'essaie de faire

J'ai une taille limitée de la boîte qui est censé contenir du texte:

.box {
  width: 100px;
  height: 40px;
  background-color: yellow;
}
<div class="box">
  Some text goes here.
</div>

Toutefois, si le texte est trop long pour tenir dans la boîte, je veux remplacer ce texte avec une autre version plus courte, que j'ai préparé à l'avance.

Ainsi, par exemple, si je veux remplir les deux cases avec ces deux noms:

Short version      Long version
------------------------------------------------------------
Rudolf E. Raspe    Rudolf Erich Raspe
Baron Munchausen   Hieronymus Karl Friedrich von Munchhausen

Ensuite, la première zone contient la mention "Rudolf Erich Raspe" car il est assez court pour s'adapter à l'intérieur, mais la deuxième case contiendra "le Baron de Munchausen" depuis le Baron nom complet est trop long.

Comment puis-je mettre en place une telle zone, juste en utilisant HTML5 et CSS3? Compatibilité du navigateur est important, mais, je n'ai pas besoin pour accueillir les très anciennes versions d'Internet Explorer antérieures à la version 11.

Alternatives

Je peux choisir l'une des options standard pour la manipulation de trop-texte long - laisser déborder, ou de les couper par overflow: hidden, ou d'ajouter des barres de défilement, ou d'ajouter des points de suspension, ou l'un des autres solutions standard. Mais depuis que je l'ai déjà en version courte de tous les possibles du texte, je voudrais profiter de ces à la place.

Je peux le faire en JavaScript, par exemple, à l'aide d'une enveloppe et de comparer sa taille avec la la boîte. Mais je voudrais un non-JavaScript solution, si possible.

Ce que j'ai essayé

Jusqu'à présent j'ai pensé à faire le texte en quelque sorte pousser lui-même si il est trop long (une combinaison de blanc et word-wrap?), faire le conteneur overflow: hidden pour le cacher quand il est là-bas, et de placer la version courte du texte derrière elle, mais je ne pouvais pas le faire fonctionner, tout en permettant le texte d'occuper plus d'une ligne.

Une autre approche consiste à placer un élément avec le petit texte juste en dessous de l'élément avec le texte long, et d'utiliser certaines de transformer ce qui fait que de courte élément prendre le relais quand il est poussé trop... Mais je ne pouvais pas le faire fonctionner non plus.

Alors... d'autres idées?

22voto

drip Points 5671

Il y a un moyen ... un peu ...

 .box {
  width: 100px;
  height: 18px;
  background-color: yellow;
  overflow: hidden;
  position: relative;
  margin-bottom: 20px;
}

span {  position: absolute; bottom: 0; left: 0; width: 100%; max-height: 36px;  }
em { position: absolute; width: 100%; top: 18px; left: 0; background-color: yellow; } 
 <div class="box">
   <span> 
     This text fits
     <em>fallback text</em>
   </span>
</div>

<div class="box">
   <span> 
     Huge text that doesn't fit and it's more than 3 lines. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     <em>fallback text</em>
   </span>
</div>

<div class="box">
   <span> 
     This text doesn't fit
     <em>fallback text</em>
   </span>
</div> 

Ce n'est pas une très belle solution, mais bon c'est quelque chose. :)

5voto

Denis Sheremet Points 1259

J'ai fait quelque chose de similaire en utilisant overflow:hidden et flottant divs.

<div style="overflow:hidden;height:1.2em;">
  <div style="float:left">Rudolph</div>
  <div style="float:right">Raspe</div>
  Erich
</div>

Donc, sur un petit bloc, vous obtiendrez Rudolph Raspe, sur un grand Rudolph Erich Raspe.

Évidemment, ce n'est pas universelle, mais dans certains cas spécifiques, il peut être utilisé.

3voto

J'ai eu du plaisir avec une seule ligne de solution, je me rends compte de la multi-solution en ligne peut être un meilleur ajustement pour l'OP. Je suis tout simplement coller ici dans le cas où c'est utile à quelqu'un. J'ai couru un test rapide sur les dernières versions de Firefox, Chrome, IE et le Bord, et il semble bien fonctionner partout. J'ai ajouté un peu de largeur fixe les boîtes pour l'exemple, mais il fonctionne réellement avec une dynamique de la largeur de la zone ainsi.

div {
  position: relative;
  overflow: hidden;
  line-height: 1.2em;
  height: 1.2em;
  /* extraneous CSS added for sample clarity only */
  font-family: Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,sans-serif;
  font-size: 13px;
  margin: 3px;  
}

div > span {
  background-color: #EFF0F1;
  float: left;
}

div::before {
  content: "\00a0";
}

div::after {
  content: attr(title);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -1;
  background-color: #EFF0F1;
}
<div title="Rudolf E. Raspe">
  <span>Rudolf Erich Raspe</span>
</div>
<div title="Baron Munchausen">
  <span>Hieronymus Karl Friedrich von Munchhausen</span>
</div>
<div title="Rudolf E. Raspe" style="width:400px;">
  <span>Rudolf Erich Raspe</span>
</div>
<div title="Baron Munchausen" style="width:400px;">
  <span>Hieronymus Karl Friedrich von Munchhausen</span>
</div>
<div title="Rudolf E. Raspe" style="width:200px;">
  <span>Rudolf Erich Raspe</span>
</div>
<div title="Baron Munchausen" style="width:200px;">
  <span>Hieronymus Karl Friedrich von Munchhausen</span>
</div>
<div title="Rudolf E. Raspe" style="width:120px;">
  <span>Rudolf Erich Raspe</span>
</div>
<div title="Baron Munchausen" style="width:120px;">
  <span>Hieronymus Karl Friedrich von Munchhausen</span>
</div>

Il fonctionne par la création de trois éléments à l'intérieur d'un contenant div.

  • Un invisible div::before pseudo élément dans le seul but d'être simplement là pour vous assurer que le deuxième élément (l' span) n'est pas le premier élément de la ligne
  • Un span contenant la version longue du texte
  • Un div::after pseudo élément contenant la version abrégée du texte

Le contenant div est définie à l' position: relative pour créer un nouveau bloc de mise en forme de contexte à l'intérieur de lui-même.

L' div::after pseudo-élément est défini à l' position: absolute avec top: 0; left: 0; ensemble pour s'assurer qu'il se trouve à la même position que l' span, tandis que l' right: 0; bottom: 0; s'assurer que l'élément est toujours aussi grand que son élément contenant (l' div). z-index: -1; assure l'élément se trouve derrière le span.

À la fois l' div::before et de la span sont rendus comme des éléments inline. Dès que l' div::before et de la span ensemble devenu trop large pour s'adapter parfaitement sur une seule ligne, l'ensemble de l' span se déplace vers la ligne suivante, révélant l' div::after qui se cachait derrière elle.

La seule raison pour avoir l' div::before il y a à assurer l' span se déplace vers la ligne suivante, il ne serait pas le faire si c'était le premier élément inline.

L' overflow: hidden; line-height: 1.2em; height: 1.2em; sur le contenant div assurer l' span est invisible dès qu'il passe à la ligne suivante.

1voto

Rounin Points 4260

Pur CSS Solution:

À l'aide de:

<div class="box" data-shortname="Baron Munchausen">
    Hieronymus Karl Friedrich von Munchhausen
</div>

Pour les âges, j'ai essayé de faire quelque chose en utilisant box::after et z-index:

box {
    position: relative;
    display: block;
    width: 120px;
    height: 40px;
    background-color: yellow;
    overflow: hidden;
    z-index: 0;
}

box::after {
    content: attr(data-shortname);
    position: absolute;
    display: block;
    top: 0;
    left: 0;
    background-color: yellow;
    z-index: 1;
}

Je suis venu les mains vides, bien que vous pourriez utiliser un @media query avec la configuration ci-dessus pour appliquer un effet positif ou négatif z-index de box::after.

(Si l' box::after z-index est positif, le shortname affiche, sinon le plus long nom s'affiche.)


JavaScript Solution:

Voici donc un script JavaScript à base de solution à l'aide d' data-* après tout:

var boxes = document.getElementsByClassName('box');

for (var i = 0; i < boxes.length; i++) {
    if (boxes[i].textContent.length > 20) {
        boxes[i].textContent = boxes[i].dataset.shortname;
    }
}
.box {
    position: relative;
    width: 120px;
    height: 40px;
    background-color: yellow;
    margin-bottom: 12px;
}
<div class="box" data-shortname="Rudolf E. Raspe">
    Rudolf Erich Raspe
</div>

<div class="box" data-shortname="Baron Munchausen">
    Hieronymus Karl Friedrich von Munchhausen
</div>

1voto

kcroake88 Points 17

Je sais que ce n'est pas une vraie réponse, mais plutôt une alternative. Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser le débordement de texte?

 .box span {
    text-overflow: ellipsis; 
    white-space: nowrap;
    overflow: hidden;
}
 

Lien utile:

https://css-tricks.com/almanac/properties/t/text-overflow/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X