web-dev-qa-db-fra.com

Comment définir la taille de la police d'un paragraphe dont le contenu est constamment remplacé

Je veux définir une boîte avec un paragraphe. Le texte de ce paragraphe doit être remplacé chaque fois que je clique sur le bouton. Et ce qui est important pour moi, c’est que ce texte reste à l’intérieur de la boîte et qu’il ne se casse pas. Pour ce faire, j'ai décidé d'utiliser le plug-in FitText.js car les mots ont des longueurs différentes (les mots donnés ne sont qu'un exemple). En le définissant comme table et cellule de table, j'ai obtenu un alignement de Nice (à la fois vertical et horizontal). Avez-vous des idées sur la raison pour laquelle un code donné ne fonctionne pas comme il se doit?

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array){
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
   
function function1(){
    var randomWord = getRandomItem(words); 
    document.getElementById('Word').innerHTML = randomWord;
}

$('#give_me_a_name_please').click(function() { 
    function resize () { $("#Word").fitText(0.6); } 
});
#parent_of_Word {
  width: 20%;
  height: 20%;
  top: 10%;
  left: 10%;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  Word-break: keep-all;
  white-space: nowrap;
}

#Word {
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_Word">
    <p id="Word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

19
wymyszony

Edit: extrait de code mis à jour et JSFiddle avec une boucle plus optimale.

J'ai adapté votre exemple de code pour qu'il soit un peu plus léger et plus facile à comprendre. Il utilise également jQuery pur au lieu d'un mélange de jQuery et de JS pur et ne s'arrête pas à 'indéfini' après avoir appuyé plusieurs fois sur le bouton, ce qui donne un tableau vide. Au lieu de cela, il parcourra à nouveau tous les mots.

Il existe deux solutions principales en vigueur ici.

  • On s’inspire de cette approche itérative pour JavaScript Ajuster le texte pour s’adapter à Fixed Div , où la taille de la police commence à une valeur fixe, puis se réduit si nécessaire jusqu’à ce que la largeur du mot soit inférieure à celle du conteneur. Pas besoin d'un plugin car c'est extrêmement trivial.
  • La deuxième partie implémente overflow:hidden de sorte que dans le cas où le texte est si massif qu'il ne peut éventuellement pas être réduit suffisamment petit (voir la limite inférieure de 8 dans la boucle while), il ne sera toujours pas sorti de son conteneur.

Voir aussi la version de JSFiddle .

var words = [
  "Emily",
  "William Callum Smith Jr.",
  "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard",
  "EdwaaaaaaaaaaaaaaaaaaaAAAAAAAAAaaaaaAAaaaaAAAaaaaaaaaaaaaaaaaaaaaaaaaard",
  "Bradley",
  "The quick brown fox"
];

var changeWord = $("#change_Word");
var parentOfWord = $("#parent_of_Word");
var Word = $("#Word");
var idx = 0;

changeWord.click(function() {
  Word.text(words[idx++ % words.length]);
  var size = 40;
  Word.css("font-size", size);
  while (Word.width() > parentOfWord.width() && size > 8) {
    Word.css("font-size", --size);
  }
});
#parent_of_Word {
  width: 200px;
  height: 50%;
  top: 50px;
  left: 50%;
  margin-left: -100px;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  Word-break: keep-all;
  white-space: nowrap;
  overflow: hidden;
}

#Word {
  color: brown;
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>
  <button id="change_Word">Button</button>
</p>
<div id="parent_of_Word">
  <p id="Word">----------------</p>
</div>

8
BoffinbraiN

Pour avoir votre texte sur une ligne, sans casser: 

white-space: nowrap;

Pour centrer n'importe quoi verticalement et horizontalement:

display:flex;
align-items: center;
justify-content: center;

Appliqué à votre exemple:

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Resize this to see how it behaves on narrower screens. Lorem ipsum dolor sit amet bla bla bla, lorem ipsum dolor sit amet bla bla bla, lorem ipsum dolor sit amet bla bla bla.", "Bradley"];


var button1 = document.getElementById("give_me_a_name_please");


button1.addEventListener("click", function1);

function getRandomItem(array){
  return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
   
function function1(){
var randomWord = getRandomItem(words) || 'No more options.'; 
document.getElementById('Word').innerHTML = randomWord;
}

$( '#give_me_a_name_please' ).click(function() { 
function resize () { $("#Word").fitText(0.6); 
} 
});
#parent_of_Word {
  display: flex;
  align-items: center;
  justify-content: center;
  /* rest optional, just to demo 
  * vertical alignment 
  */  
  height: calc(100vh - 40px); 
  border: 1px solid red;
  padding: 1rem;
}

#Word {
  white-space: nowrap;
  border: 5px solid;
  padding: 1rem;
  flex: 0 1 auto;
  max-width: 100%;
  overflow: hidden;
  text-overflow: Ellipsis;
}
 * {
  margin: 0;
  box-sizing: border-box;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_Word">
<p id="Word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

4
Andrei Gheorghiu

C'est parce que vous avez défini la width du #parent_of_Word comme étant 20%, qui est bien sûr liée à son élément parent, c'est-à-dire l'élément corps, basé sur l'exemple donné.

Ainsi, la width du #parent_of_Word ne peut pas être simplement redimensionnée de manière dynamique en fonction de la largeur de son contenu. Il ne peut s'agir que de "visuellement redimensionné" avec sa largeur parent}, mais il n'en restera que 20%. Même si l'unité utilisée est % et que largeur de l'élément est dynamique, il est toujours corrigé.

Donc, ma solution serait d'omettre la widthpropriété et de simplement définir la padding de votre choix:

Note: J'ai commenté l'inutile.

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array) {
  return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
   
function function1() {
  var randomWord = getRandomItem(words); 
  document.getElementById('Word').innerHTML = randomWord;
}

$('#give_me_a_name_please').click(function() {
  function resize() {
    $("#Word").fitText(0.6); 
  } 
});
#parent_of_Word {
  display: flex;
  /*width: 20%; the culprit*/
  height: 20%;
  padding: 0 20px; /* can also use [%] */
  position: absolute;
  top: 10%;
  left: 10%;
  /*text-align: center;*/
  justify-content: center;
  align-items: center; /* added; vertical alignment */
  /*line-height: 100%;*/
  border: 5px solid black;
  /*
  Word-break: keep-all;
  white-space: nowrap;
  */
  color: brown;
}

/*
#Word {
  color: brown;
  display: flex;
  align-items: center;
  justify-content: center;
}
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>

<button id="give_me_a_name_please">Button</button>

<div id="parent_of_Word">
  <p id="Word">----------------</p>
</div>

3
VXp

La solution la plus simple à votre problème consiste à changer la valeur de la largeur de #parent_of_Word en width:auto. La largeur sera ajustée automatiquement en fonction du contenu (ajustement automatique en fonction de la longueur du paragraphe).

Exemple de travail: https://jsfiddle.net/18faLbap/4/

2
Jake Miller

Il existe un moyen CSS pour insérer des mots dans le contenu

En gros, je désactive la largeur absolue de votre #parent_of_Word et modifie la display en inline-block, de sorte que sa largeur corresponde à son contenu. Pour le rendre plus beau, j'ajoute la propriété padding. La version réduite et améliorée de votre code est présentée ci-dessous.

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array){
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
   
function function1(){
    var randomWord = getRandomItem(words); 
    document.getElementById('Word').innerHTML = randomWord;
}
#parent_of_Word {
  top: 10%;
  left: 10%;
  display: inline-block;
  position: absolute;
  text-align: center;
  padding: 10px;
  border: 5px solid black;
  Word-break: keep-all;
}

#Word {
  text-overflow: Ellipsis;
  white-space: nowrap;
  overflow: hidden;
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;
}

#Word:hover {
    white-space: normal;
    }
<div id="parent_of_Word">
    <p id="Word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

Donc, vous n'avez plus besoin de la bibliothèque JavaScript supplémentaire maintenant. Plus de connaissances peuvent être trouvés ici

0
Travor Liu
#parent_of_Word {
    min-width: 20%;
    width: auto;
    padding: 0px 20px;
}

Tout ce que j'ai fait ici est d'ajouter width: auto et de définir un min-width:20%. Cela rend la largeur dynamique lorsque le texte est mis à jour dans la zone. Ajouté dans un peu padding pour le rendre joli aussi. J'espère que cela t'aides.

0
Ben Davies

Je le fais habituellement par cette approche lorsque je veux garder du texte en ligne. En particulier, je grille. Ainsi, peu importe la longueur de votre boîte, elle sera alignée et, lorsque vous la survolerez, elle affichera des lignes lisibles.

var words = ["Emily", "William Callum Smith Jr.", "Edwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaard", "Bradley"];

var button1 = document.getElementById("give_me_a_name_please");

button1.addEventListener("click", function1);

function getRandomItem(array){
    return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
   
function function1(){
    var randomWord = getRandomItem(words); 
    document.getElementById('Word').innerHTML = randomWord;
}

$('#give_me_a_name_please').click(function() { 
    function resize () { $("#Word").fitText(0.6); } 
});
#parent_of_Word {
  width: 20%;
  
  top: 10%;
  left: 10%;
  display: flex;
  position: absolute;
  text-align: center;
  justify-content: center;
  line-height: 100%;
  border: 5px solid black;
  Word-break: keep-all;

}

#Word {
  text-overflow: Ellipsis;
  white-space: nowrap;
  overflow: hidden;
  color: brown;
  display:flex;
  align-items: center;
  justify-content: center;
}

#Word:hover {
    white-space: normal;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/davatron5000/FitText.js/0b4183af/jquery.fittext.js"></script>


<div id="parent_of_Word">
    <p id="Word">----------------</p>
</div>
<button id="give_me_a_name_please">Button</button>

0
molikh

Comme vous avez déjà jQuery sur la page, envisagez d’utiliser le jquery-textfill plugin:

http://jquery-textfill.github.io/

Cela garantira que votre texte s'adapte à votre conteneur.

0
hzsheikh