Je souhaite réaliser quelque chose comme ceci:
Mais actuellement, je ne reçois que ceci:
Explication (merci Andrei Gheorghiu):
Je souhaite afficher les éléments dans un nombre indéfini de colonnes en ligne, la règle étant "pas plus de 2 éléments dans 1 colonne". Le 3ème élément crée la deuxième colonne, la 5e crée la 3e, la 7e crée les 4e colonnes et ainsi de suite. Soit chaque colonne, soit la liste entière doit se comporter comme un bloc en ligne.
Pour résumer:
Voici mon code: https://jsfiddle.net/2uf951km/6/
p>
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
</ul>
in the middle of other text.
</div>
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-block;
column-width: 35px;
height: 35px;
padding: 0;
list-style: none;
font-size: 10px;
vertical-align: middle;
/*
Setting margin fixes the issue,
but the with of the list is not
known.
*/
/* margin-right: 170px; */
}
li {
background: #9eff80;
padding: 2px;
opacity: 0.7;
}
Comment mon CSS / HTML peut-il être modifié pour que la liste ne couvre pas le texte?
4 Réponses :
Il existe plusieurs correctifs, soit ajoutez display: block à ul comme ceci
ul {
display: inline-block;
column-width: 35px;
height: 35px;
padding: 0;
list-style: none;
font-size: 10px;
vertical-align: middle;
/*
Setting margin fixes the issue,
but the with of the list is not
known.
*/
margin-right: 30%;
}
Ou modifiez la marge -droite à% ou vw au lieu de px comme ceci
ul {
display: block;
column-width: 35px;
height: 35px;
padding: 0;
list-style: none;
font-size: 10px;
vertical-align: middle;
/*
Setting margin fixes the issue,
but the with of the list is not
known.
*/
/* margin-right: 170px; */
}
Hey. Malheureusement, aucune de ces solutions ne résout le problème. Le réglage display: block force la liste à être sur une ligne distincte. La définition de margin-right résout le problème pour un contenu spécifique de la liste, mais si deux éléments sont ajoutés / supprimés, cela ne fonctionne plus bien.
qu'en est-il de l'ajout de display: inline-block; au style li ?
N'aide pas en soi. Mais si vous avez d'autres idées, vous pouvez essayer par vous-même ici! jsfiddle.net/uwy21kp3
Si cela ne vous dérange pas d'avoir chaque dans sa propre colonne, je pense que cela pourrait fonctionner:
ul {
display: inline;
...
}
li {
display: inline-block;
...
}
Merci, mais j'ai besoin de deux dans une colonne pour économiser de l'espace.
Réponse initiale (avant que je réalise ce que vous demandez):
En fonction de la façon dont vous voulez que les soient classés, vous pouvez utiliser colonnes ... p >
$('ul').each(function() {
while($('li', this).length > 2) {
let newUl = $('<ul/>'), i = 0;
while(i < 2) {
$('li', this).eq(0).appendTo(newUl);
i++;
}
newUl.insertBefore($(this));
}
})
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
<li>A list</li>
</ul>
in the middle of other text. I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
<li>A list</li>
</ul>
in the middle of other text.
</div>
... ou display: inline-flex . Vous devrez définir la max-width sur les enfants, définir flex-wrap: wrap sur le parent et spécifier vertical-align souhaité sur le parent:
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-block;
padding: 0;
list-style: none;
font-size: 10px;
vertical-align: middle;
min-height: 35px;
}
li {
background: #9eff80;
padding: 2px;
margin: 1px;
opacity: 0.7;
}
let uls = document.querySelectorAll('ul');
for(let i = 0; i < uls.length; i++) {
let count = uls[i].children.length;
if (count && count > 2) {
for (j = 0; j < count/2; j++) {
let parent = uls[i].parentElement,
newUl = document.createElement('ul');
for (k = 0; k < 2; k++) {
li = uls[i].querySelector(':first-child');
if (li) {
newUl.appendChild(li);
parent.insertBefore(newUl, uls[i]);
}
}
}
}
}
L'élément le plus important de tout cela est probablement de supprimer height: 35px; de ul . Pourquoi avez-vous codé cela en dur si "Le nombre d'éléments de la liste est inconnu" ?
Bonne réponse (comment être atteint):
Il semble que vous vouliez que vos éléments soient affichés comme une série indéfinie de blocs en ligne, chacun contenant 2 éléments ou moins. Vous devez encore définir ce qui doit se passer lorsque le contenu de vos 2 éléments dépasse la hauteur souhaitée de 35px .
Voici comment y parvenir en utilisant du JavaScript vanille. Si possible, vous devriez le faire côté serveur, cependant:
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
</ul>
in the middle of other text.
</div>
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-flex;
padding: 0;
list-style: none;
font-size: 10px;
flex-wrap: wrap;
line-height: 5em;
vertical-align: middle;
/* see also -webkit-baseline-middle
text-bottom
text-top */
}
li {
line-height: 1em;
flex: 0 1 auto;
margin: 1px;
width: calc(50% - 2px); /*deduct margin*/
background: #9eff80;
padding: 2px;
opacity: 0.7;
box-sizing: border-box;
}
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
</ul>
in the middle of other text.
</div>
C'est l'un des cas où jQuery serait beaucoup plus court:
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-block;
column-width: 35px;
padding: 0;
list-style: none;
font-size: 10px;
columns: 2 0px;
}
li {
background: #9eff80;
margin: 1px;
padding: 2px;
opacity: 0.7;
width: 100%;
break-inside: avoid;
}
Réponse mise à jour pour atteindre vos objectifs en utilisant CSS Grid inline-grid pour générer une grille de niveau en ligne:
grid-template-rows code > est configuré pour répéter un maximum de deux lignes avec 1fr chacune.
grid-template-columns est configuré pour répéter un auto nombre de colonnes nécessaires avec une largeur de 35px .
grid-auto-flow est défini sur column pour que l'algorithme de placement automatique de la grille remplisse chaque colonne à tour de rôle, en ajoutant de nouvelles colonnes si nécessaire tout en conservant le maximum de deux lignes.
grid-column-gap était utilisé pour ajouter un remplissage entre les colonnes pour afficher les mêmes résultats que les images fournies.
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
</ul>
in the middle of other text.
</div>
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-block;
columns: auto 3;
padding: 0;
list-style: none;
font-size: 10px;
vertical-align: middle;
}
li {
background: #9eff80;
padding: 2px;
opacity: 0.7;
}
J'espère que cela résout votre problème!
Si votre objectif est d'avoir un maximum de 3 décomptes de colonnes comme indiqué dans les images fournies, Je pense que la propriété que vous devez modifier est:
column-width: 35px to columns: auto 3 si vous que la largeur de colonne de chaque colonne soit définie sur auto.
ou
largeur de colonne: 35px à colonnes: 35px 3 si vous souhaitez une largeur de colonne spécifique pour chaque colonne.
Ceci une explication de ce que fait la propriété columns :
La propriété CSS
columnsdéfinit la largeur et le nombre de colonnes d'un élément. - MDN - colonnes css
Ci-dessous, le code que j'ai utilisé pour obtenir le même résultat que l'image que vous avez fournie.
<div>
I'd like to have a list with several columns
<ul>
<li>A list</li>
<li>like this</li>
<li>with unknown</li>
<li>number and items</li>
<li>or columns.</li>
</ul>
in the middle of other text.
</div>
div {
font-size: 30px;
padding: 30px;
}
ul {
display: inline-grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(auto, 35px);
grid-auto-flow: column;
grid-column-gap: 10px;
align-items: center;
list-style: none;
font-size: 10px;
padding: 0;
margin: 0;
vertical-align: middle;
}
li {
background: #9eff80;
padding: 2px;
opacity: 0.7;
}
J'espère que cela vous aidera!
Je pense que vous vous êtes trompé, comme tout le monde, car cela n'a pas été clairement expliqué: OP veut afficher les éléments dans un nombre indéfini de colonnes en ligne, la règle étant "pas plus de 2 éléments dans 1 colonne". Le 3e élément crée la deuxième colonne, le 5e crée la 3e, le 7e crée les 4e colonnes et ainsi de suite. Chaque colonne doit se comporter comme un bloc en ligne.
Merci Christian pour votre réponse. @AndreiGheorghiu a bien compris. Le nombre de colonnes est indéfini. Le problème avec cette solution est qu'elle crée 2 colonnes même si une seule est nécessaire. Pensez-vous que vous pourriez modifier cette solution pour agir comme Andrei l'a expliqué?
@AndreiGheorghiu @Draex_ Merci pour votre contribution et vos commentaires. J'ai modifié ma réponse pour utiliser CSS display: inline-grid , qui, je crois, permet de réaliser l'explication d'Andrei et les objectifs de la question originale.
Bonne idée, @Christian. Malheureusement, la grille se comporte comme un bloc en ligne, pas comme une série de blocs en ligne (les colonnes s'enroulent comme un élément entier et ne s'enroulent pas lorsque la largeur de l'appareil est inférieure à la largeur de la grille). Ma conclusion est que ce que veut OP n'est pas possible en utilisant uniquement CSS.
@Jake Je vais le convertir en PDF, donc le référencement n'est pas un problème. Je n'ai pas essayé
:: avant/:: après, mais je ne vois pas comment ils pourraient être utiles ici. Pouvez-vous poster quelques codes pls?Ce que vous voulez n'est pas possible. Devrait fonctionner en définissant un affichage
max-heightet: inline-flex; flex-wrap: wrap; flex-direction: colonnesuruletwidthsurli, mais cela produit le résultat auquel vous êtes arrivé. Tout bien considéré, c'est une mauvaise décision de conception en premier lieu. Arrêtez de l'avoir en ligne et affichez le tout au centre.Cela peut être fait avec JavaScript: prenez le
et transformez-le en plusieurs éléments contenant chacun 2 éléments, affichés sous forme deinline-blocks. Terminé! Si vous ne connaissez pas JS, je peux l'écrire (c'est trivial). Solution acceptable?@AndreiGheorghiu Eh bien, c'est la meilleure solution à ce jour, même si j'espérais une solution sans JS. Je peux l'écrire, merci.