Étirez le texte pour adapter à la largeur de la div

j'ai un div avec une largeur fixe, mais le texte à l'intérieur du div peut changer.

Existe-t-il un moyen de définir, avec css ou autre, l'espacement entre les lettres de sorte que le texte remplit toujours parfaitement la div?

38
demandé sur web-tiki 2011-05-12 13:56:01

11 réponses

comme disait Mark, text-align:justify; est la solution la plus simple. Cependant, à court texte, il n'aura aucun effet. Le code jQuery suivant étend le texte à la largeur du conteneur.

il calcule l'espace pour chaque caractère et place letter-spacing en conséquence ainsi le texte strèches à la largeur du conteneur .

si le texte est trop long pour s'insérer dans le conteneur, il permet de l'étendre aux lignes suivantes et place text-align:justify; sur le texte.

Voici une démo:

$.fn.strech_text = function(){
    var elmt          = $(this),
        cont_width    = elmt.width(),
        txt           = elmt.html(),
        one_line      = $('<span class="stretch_it">' + txt + '</span>'),
        nb_char       = elmt.text().length,
        spacing       = cont_width/nb_char,
        txt_width;
    
    elmt.html(one_line);
    txt_width = one_line.width();
    
    if (txt_width < cont_width){
        var  char_width     = txt_width/nb_char,
             ltr_spacing    = spacing - char_width + (spacing - char_width)/nb_char ; 
  
        one_line.css({'letter-spacing': ltr_spacing});
    } else {
        one_line.contents().unwrap();
        elmt.addClass('justify');
    }
};


$(document).ready(function () {
    $('.stretch').each(function(){
        $(this).strech_text();
    });
});
p { width:300px; padding: 10px 0;background:gold;}
a{text-decoration:none;}

.stretch_it{ white-space: nowrap; }
.justify{ text-align:justify; }

.one{font-size:10px;}
.two{font-size:20px;}
.three{font-size:30px;}
.four{font-size:40px;}
.arial{font-family:arial;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="stretch one">Stretch me</p>
<p class="stretch two">Stretch me</p>
<p class="stretch three">Stretch <a href="#">link</a></p>
<p class="stretch two">I am too slong, an I would look ugly if I was displayed on one line so let me expand to several lines and justify me.</p>
<p  class="stretch arial one">Stretch me</p>
<p class="stretch arial three">Stretch me</p>
<p class="stretch arial four">Stretch me</p>
<p class="arial two">Don't stretch me</p>

Js fiddle démo

31
répondu web-tiki 2017-01-10 08:06:08

Cela peut être fait avec text-align:justify et un petit hack. Voir ici: http://codepen.io/aakilfernandes/pen/IEAhF /

le truc est d'ajouter un élément après le texte qui prétend être vraiment un long mot. Le faux mot est en fait un élément span avec display:inline-block et width:100% .

dans mon exemple le faux mot est en rouge et donne une hauteur de 1em, mais le hack fonctionnera même sans lui.

20
répondu Aakil Fernandes 2014-04-09 00:41:23

peut-être que cela pourrait aider:

text-align:justify;
7
répondu Mark 2012-09-03 12:56:22

encore plus facile méthode HTML/CSS serait d'utiliser flexbox. Il réagit aussi immédiatement. Mais à noter que SEO ne le récupérera pas si vous l'utilisez comme un h1 ou quelque chose.

HTML:

<div class="wrapper">
<div>H</div>
<div>e</div>
<div>l</div>
<div>l</div>
<div>o</div>
<div>&nbsp</div>
<div>W</div>
<div>o</div>
<div>r</div>
<div>l</div>
<div>d</div>

CSS:

.wrapper{
  width: 100%;
  text-align: center;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  border: 1px solid black;
}

jsfiddle ici

4
répondu nathan 2015-11-01 13:38:45

j'ai trouvé une meilleure solution pour un texte plus court qu'une ligne, sans js ou tag supplémentaire, une seule classe.

.stretch{ 
  /* We got 2rem to stretch */
  width: 5rem;
  /* We know we only got one line */
  height: 1rem;
  
  text-align: justify; 
}
.stretch:after{
    /* used to stretch word */
    content: '';
    width: 100%;
    display: inline-block; 
}
<div class="stretch">你好么</div>
<div class="stretch">你好</div>
4
répondu wener 2017-05-02 01:57:53

mars 2018 Si vous atterrissez sur cette question dans un temps plus actuel...

j'ai essayé de faire ce que L'OP a demandé mais avec un seul mot et a trouvé le succès avec ce qui suit:

1. utiliser un <span> et régler css: span { letter-spacing: 0px; display:block} (cela rend l'élément seulement aussi large que le contenu)

2. en charge saisir la largeur de la portée let width = $('span').width();

3. Capture de la longueur de la portée let length = $('span').length;

4. réarmer la largeur de la portée sur le réservoir $('span').css({'width','100%'});

5. capturer la nouvelle largeur de la portée (ou juste utiliser la largeur du conteneur) let con = $('span').width();

6. calculer et définir l'espacement des lettres pour remplir le conteneur $('span').css({'letter-spacing':(cont-width)/length})

évidemment, cela peut être converti pour utiliser vanilla js et il est utile même avec la plupart des styles de police, y compris les polices non mono-espace.

1
répondu KyleM 2018-03-25 18:17:27

certaines des réponses ci-dessus fonctionnent bien, mais le texte doit envelopper avec beaucoup d'enfants div

et il y a beaucoup de codes supplémentaires.

Le texte à l'intérieur du div devrait être propre, donc je l'ai fait avec l'aide de JS.

const words = document.querySelector(".words"),
  wordsArray = words.innerText.split("").map(e => " " == e ? "<div>&nbsp</div>" : "<div>" + e + "</div>");
words.innerHTML = wordsArray.join("");
.words {
  width: 100%;
  text-align: center;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
}
<div class="words">This is the demo text</div>
1
répondu ronaldtgi 2018-08-21 13:01:54

je pense que ce que vous cherchez en fait c'est une mise à l'échelle.

rendrez votre police avec une belle résolution qui a du sens et puis utilisez JS pour l'étirer vers le conteneur en utilisant CSS transforme:

transform: scale(1.05);

les avantages de ceci est que votre texte sera toujours wit, mais vous rencontrez le problème de devenir trop petit pour être lisible.

la note rapide est que vous aurez besoin de faire l'élément que vous essayez de shrink / expand ont la position absolue:

position: absolute;
0
répondu McTrafik 2015-12-18 19:47:36

donc, toujours grignoter les bords de ce problème, si vous combinez la réponse de wener qui étire de courtes lignes de texte avec cette suggestion d'utiliser un élément réel à partir d'un autre fil, vous pouvez faire le tout sans avoir besoin d'une classe de pseudo :after .

vous substituez dans un élément réel et le placez après celui que vous voulez justifier. Et cela déclenchera la justifier l'alignement de la même façon:

header {
  background-color: #ace;
  text-align: justify;
}

.hack {
  display: inline-block;
  width: 100%;
}
<header>
  <div>
    A line of text to justify
    <div class="hack"></div>
  </div>
</header>

cette variation vous permet d'utiliser cette astuce avec les objets React et style:

const style = {
  backgroundColor: '#ace',
  textAlign: 'justify'
};

const hack = {
  display: 'inline-block',
  width: '100%'
};

const example = (
  <header style={ style }>
    <div>
      A line of words to stretch
      <div style={ hack } />
    </div>
  </header>
);

ReactDOM.render(example, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

c'est déjà assez laid et ringard, mais de là vous devrez choisir votre poison de quelle façon vous voulez "fixer" la hauteur excédentaire du conteneur: hauteur fixe ou marges négatives pour le conteneur? Relatif positionnement et chevauchement des éléments suivants? faire correspondre l'arrière-plan du conteneur à l'arrière-plan de la page et prétendre que la marge supplémentaire est intentionnelle?

0
répondu worc 2018-01-30 19:39:02

un peu tard pour le parti, mais pour une mise en œuvre simple et pure CSS envisager d'utiliser flexbox :

h1.stretch {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
<h1 class="stretch">
  <span>F</span>
  <span>o</span>
  <span>o</span>
  <span>B</span>
  <span>a</span>
  <span>r</span>
</h1>

Je ne suis pas sûr que le fait d'envelopper chaque lettre dans un span (notez que n'importe quel élément fonctionnera) va affecter le référencement, mais j'imagine que les moteurs de recherche vont rayer les étiquettes du innerHTML des étiquettes utilisées pour le balisage important tel que les en-têtes, etc. (Quelqu'un qui connaît SEO pour confirmer?)

0
répondu saricden 2018-09-28 00:46:38

jsfiddle lien

pour une solution purement HTML/CSS même pour un texte plus court (assez court que

text-align: justify;

ne fonctionne pas)

j'ai suivi ce post très comme une source d'inspiration, et placés de chaque lettre dans une div

HTML:

<div class="wrapper">
    <div class="letters">H</div>
    <div class="letters">e</div>
    <div class="letters">l</div>
    <div class="letters">l</div>
    <div class="letters">o</div>
    <div class="letters">&nbsp</div>
    <div class="letters">W</div>
    <div class="letters">o</div>
    <div class="letters">r</div>
    <div class="letters">l</div>
    <div class="letters">d</div>
    <span class="stretch"></span>
</div>

CSS:

.wrapper {
    width: 300px; /*for example*/
    border: 1px solid gray; /*only for demonstrative purposes*/
    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;
}

.letters {
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1
}

.stretch {
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}
-1
répondu talker90 2017-05-23 11:47:31