28182 sujets

CSS et mise en forme, CSS3

Modérateur
Bonjour,

Je bute régulièrement sur le petit problème suivant. On considère une liste de 3 éléments html quelconque dont on ne connait pas la largeur a priori et qui ne sont pas tous de la même largeur. Sur écran large, ces éléments sont à afficher sur une même ligne. Sur écran étroit, lorsqu'il n'y a plus assez de place pour afficher les 3 éléments sur la même ligne, il faudrait que ce soit l'élément du milieu qui passe à la ligne en premier.

Jusqu'à présent, je m'en sors soit avec du js, soit avec des suppositions sur la largeur des éléments. Mais j'aimerais bien une solution en css pur qui ne fait aucune supposition sur la largeur des éléments.

Écran large :
AAA BBBBB CCCC

Écran étroit :
AAA CCCC
BBBBB

Une idée ?

Html (mais on a entière liberté pour le modifier si besoin est)
<div>
<span>AAA</span>
<span>BBBBB</span>
<span>CCCC</span>
</div>


Amicalement,
Modifié par parsimonhi (29 Feb 2024 - 18:42)

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
html, body {
margin: 0;
padding: 0;
font-family: system-ui;
color: #000;
font-size: 100%;
overflow-x: hidden;
background-color: #fff;
}
.txt {
font-size: 44px;
color: red;
}
.bloc1, .bloc2, .bloc3 {
position: relative;
top: 0;
display: inline-block;
width: 30%;
height: 300px;
border: 1px solid #000;
margin: 1%;
background-color: lightcoral;
}

@media only screen and (orientation: portrait){
.bloc1, .bloc2, .bloc3 {
width: 46%;
}
.bloc2 {
position: absolute;
top: 320px;
left: 0;
}
}
</style>
</head>
<body>
<div class="bloc1">AAA</div>
<div class="bloc2">BBB</div>
<div class="bloc3">CCC</div>
</body>
</html>

comme çà ?:
https://royalplayaclub.be/brol/test.html
Modifié par drphilgood (29 Feb 2024 - 20:02)
Modérateur
Bonjour,

J'avoue que ton utilisation de "(orientation: portrait)" m'a scotchée ! C'est très astucieux et je n'avais pas du tout pensé à cette voie. Bravo !

Bon, ça ne me sort pas d'affaire tel quel, car ça suppose qu'on va être en orientation landscape capable de tout afficher et en orientation portrait devoir passer à la ligne, ce qui est une contrainte assez forte sur la taille des éléments concernés.

Par contre, ça m'a donné quelques idées et en particulier, je me suis mis à chercher du côté des @container (que je connais bien mal) et j'ai vu qu'on pouvait utiliser l'orientation mais aussi l'aspect-ratio. On suppose toujours quelque chose sur la taille du conteneur (l'aspect-ratio), mais rien du tout sur les éléments et la contrainte s'en trouve beaucoup moins forte qu'avec la plupart des autres astuces que j'ai pu tester. Voilà ce que ça donne et ça commence à ressembler à ce que je recherche :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
div
{
	position:relative;
	font-size:5em;
	container-type: size;
	container-name: z;
	height:1.25em;
	display:flex;
	justify-content:space-between;
}
@container z (max-aspect-ratio: 7/1)
{
	span:nth-of-type(2)
	{
		position:absolute;
		display:block;
		width:100%;
		text-align:center;
		top:1.25em;
	}
}
</style>
</head>
<body>
<div>
<span>AAA</span>
<span>BBBBB</span>
<span>CCCC</span>
</div>
</body>
</html>

Un grand merci !

J'attends de voir s'il n'y aurait pas quelqu'un qui arriverait avec des contraintes encore moins fortes sur la taille des éléments (ou du conteneur) avant de clore le sujet.

Amicalement,
Modérateur
Bonsoir,

j'avais dans l'idée que grid, auto-fit et grid-row ferait l'affaire...
Cependant grid-row à un effet trés similaire à order lorsque l'on definit grid-row:1 à deux éléments sur trois sur la même ligne, ils se repositionnent dans les premières cellules de la grille.

Reste alors peut-être l'option des Container Queries pour appliquer le positionnement a une ligne avec le défaut de devoir anticiper un ou plusieurs point de ruptures.

Voici l'idée, si tu peut en faire quelque chose. https://codepen.io/gc-nomade/pen/abxbKyO

Très bonne question et fil très intéressant ! .

Cdt
Modifié par gcyrillus (29 Feb 2024 - 22:43)
gcyrillus a écrit :
Très bonne question et fil très intéressant !.

Je confirme. J'ai moi aussi testé des trucs mais : nop.

Le problème c'est que, quelque soit la solution que l'on envisage (de mon côté j'ai tenté une bidouille avec columns), on en revient toujours à devoir définir au moins un point de rupture, ce qui serait un compromis par rapport à la demande initiale.
Modérateur
Olivier C a écrit :

Je confirme. J'ai moi aussi testé des trucs mais : nop.


Le javascript reste encore le plus simple et solide à mon avis. en reprenant une idée testant la position d'un élément par rapport au haut de son parent et flex et order , on s'en sort pas trop mal : https://codepen.io/gc-nomade/pen/XWQWYwd
;)
Modérateur
Bonjour,

gcyrillus a écrit :
Reste alors peut-être l'option des Container Queries pour appliquer le positionnement a une ligne avec le défaut de devoir anticiper un ou plusieurs point de ruptures.
Tout à fait d'accord, à la fois pour le fait que ça permet de passer à la ligne, et à la fois que ça a l'inconvénient de devoir anticiper au moins un point de rupture.

gcyrillus a écrit :
Très bonne question et fil très intéressant ! .
Merci, un petit "stroke" de temps en temps comme disent les formateurs en management, ça fait toujours plaisir. Smiley cligne

Olivier C a écrit :
Le problème c'est que, quelque soit la solution que l'on envisage (de mon côté j'ai tenté une bidouille avec columns), on en revient toujours à devoir définir au moins un point de rupture, ce qui serait un compromis par rapport à la demande initiale.
C'est effectivement le coeur du problème, d'où l'avancée quand on peut caser un point de rupture sur autre chose qu'un width du container, ce que je n'avais pas envisagé jusqu'à présent.

gcyrillus a écrit :
Le javascript reste encore le plus simple et solide à mon avis.
Oui ! Et c'est d'ailleurs comme ça que je fais quand la largeur des éléments ou du container est imprévisible. Les possibilités pour obtenir le résultat sont nombreuses. Celle que tu proposes est astucieuse, évitant un calcul des widths des éléments. Mais oserais-je le dire, une bidouille en javascript, c'est la solution de facilité (que je voudrais éviter justement). Smiley smile

Amicalement,
Salut,

Il y a quelques temps j'avais commencé à essayer de couper la poire en 2 en faisant du javascript pour le moment et en espérant qu'il y aura une solution en full css dans un futur proche Smiley lol
En gros ce qui manque à mon gout, ça serait une propriété css ":wrapped" , et donc j'avais essayé d'en faire un faux/simulacre en javascript avec un ajout d'une classe au parent.

Bon le problème c'est que je n'ai pas retrouvé ce que j'avais fais il y a quelques temps .. donc j'en ai refais un à la va vite, et la en regardant la réponse de gcyrillus ça ressemble globalement à son traitement (en moins propre Smiley bawling )

Le lien vers le jsfiddle que je viens de faire : https://jsfiddle.net/729k60rb/

Et idéalement si cela existait en css, ça serait donc juste d'avoir &:wrapped au lieu du &.wrapped dans le css
Modérateur
Bonjour,

Mathieuu a écrit :
En gros ce qui manque à mon gout, ça serait une propriété css ":wrapped" , et donc j'avais essayé d'en faire un faux/simulacre en javascript avec un ajout d'une classe au parent.
Il se peut que les @container finissent par arriver à faire un équivalent.

Mathieuu a écrit :
Bon le problème c'est que je n'ai pas retrouvé ce que j'avais fais il y a quelques temps .. donc j'en ai refais un à la va vite, et la en regardant la réponse de gcyrillus ça ressemble globalement à son traitement (en moins propre Smiley bawling )

Le lien vers le jsfiddle que je viens de faire : https://jsfiddle.net/729k60rb/
Ça marche aussi. Merci !

À vrai dire, je n'ai pas trop de problème à réaliser cette fonctionnalité en js. On notera au passage que les solutions basées sur les hauteurs des éléments sont à adapter si les éléments n'ont pas tous la même hauteur. J'ai en fait selon les cas des mélanges de boutons, de textes, d'images, etc. Quelque chose du genre "vérifier que le y de l'un des éléments est supérieur au y + height de l'un des autres" devrait fonctionner dans ces cas. Ceci dit, c'est du détail. L'idée reste la même.

Amicalement,
Modifié par parsimonhi (02 Mar 2024 - 07:37)
parsimonhi a écrit :
Il se peut que les @container finissent par arriver à faire un équivalent.

Le fameux effet masonry, qui doit advenir avec l'API grid layout, pourra peut-être aider :
grid-template-rows: masonry;

... ou non : car il faudra alors lier cet effet avec un "order quelque chose" sur l'item n°2, et donc définir un point de rupture pour placer cet order...
Arf, je n'en sais rien.