28128 sujets

CSS et mise en forme, CSS3

Bonjour à tous,

Je sollicite votre aide concernant un petit souci que je rencontre avec un morceau de code CSS. J'utilise actuellement la règle suivante pour mettre en forme mon site web :
css
.ligne:has(>.colonne-unique) {
  display: block;
}

Je me suis aperçu que la pseudo-classe :has n'est toujours pas prise en charge par Firefox. Quelqu'un aurait-il trouvé une solution de contournement pour résoudre ce problème tout en maintenant une expérience utilisateur agréable et une compatibilité avec les différents autre navigateurs ?

Je suis ouvert à toutes suggestions et serai ravi d'apprendre de nouvelles méthodes. En vous remerciant par avance pour votre aide précieuse, je vous souhaite une excellente journée.

Amicalement,
Modifié par Pyanepsion (23 Apr 2023 - 20:21)
Bonsoir,

De mon côté j'avais failli répondre avec une solution JavaScript mais, au vu du sujet précédemment posté qui semble en lien, je pense qu'il faut faire plus simple.
Bonjour,

Je vous remercie pour vos réponses et pour avoir pris le temps de me donner des conseils. Les solutions proposées ne semblent cependant pas répondre à ma situation particulière où j’ai besoin de contourner la pseudo-classe :has() pour adapter ma mise en page en fonction du nombre de colonnes présentes dans la section "ligne".

Pour clarifier ma demande, voici un exemple de code qui illustre ma situation :

Première situation :
<section class="ligne" aria-label="…">
  <section class="colonne-unique;" aria-label="Titre">
    <h1>
      Titre_h1
    </h1>
    <hr class="hr-diviseur hr-rouge">
    <h2>
      Titre_h2
    </h2>
    <p class="centre">
      Slogan
    </p>
  </section>
  <section class="colonne-unique centre" aria-label="Module">
    <!-- Module  -->
  </section>
</section>

Deuxième situation :
<section class="ligne" aria-label="…">
  <section class="colonne-double centre" aria-label="Titre">
    <h1>
      Titre_h1
    </h1>
    <hr class="hr-diviseur hr-noir">
    <h2>
      Titre_h2
    </h2>
    <p>
      Slogan
    </p>
  </section>
  <section class="colonne-double centre-media" aria-label="Module">
    <!-- Module -->
  </section>
</section>

Je cherche toujours une solution qui puisse maintenir une expérience utilisateur agréable et une compatibilité avec les différents navigateurs, y compris Firefox. Si quelqu’un a une autre approche à me proposer ou des conseils supplémentaires, je serais ravi de les entendre.

Encore merci pour votre aide et en espérant que nous pourrons trouver une solution ensemble. Je vous souhaite une excellente journée.

Amicalement,
Modérateur
Salut,

Le :has() est la seule solution CSS à ma connaissance (pas encore supportée pleinement comme tu peux le voir) pour sélectionner une elements en fonction de son contenu (donc un sélecteur de parent quoi).

Pour moi le seul contournement possible pour le moment est dans le langage qui build ton DOM (ou en Js à la volée en dernier choix), avec un ajout dynamique d'une classe spécifique quand il n'y a pas d'enfant à ajouter dans la colonne.

Bonne journée
Meilleure solution
Bonjour, _Laurent,

Merci beaucoup pour ta réponse et pour tes suggestions. J’apprécie vraiment que tu aies pris le temps de partager ton point de vue sur cette question.

Je suis d’accord avec toi sur le fait que la pseudo-classe :has() est la solution idéale en CSS pour résoudre mon problème. Comme tu l’as mentionné, il est dommage que Firefox ne la prenne pas encore pleinement en charge.

Après avoir pesé les avantages et les inconvénients, j’ai décidé de ne pas ajouter de fonction JavaScript pour le moment pour les raisons suivantes :

1. Ajouter du JavaScript pourrait complexifier mon code, ce qui pourrait rendre la maintenance et les mises à jour plus difficiles à l’avenir.

2. Étant donné que Firefox est maintenant le seul grand navigateur à être en retard sur cette fonctionnalité, je suis optimiste quant à la possibilité qu’ils l’implémentent prochainement, et d’autant plus qu’il est maintenant possible de l’activer manuellement sur Firefox.

3. En l’état actuel, la situation non prise en charge par Firefox se comporte de manière similaire à l’autre situation, ce qui rend l’ajout d’une solution de contournement moins urgent.

Pour ces raisons, je vais plutôt surveiller l’évolution de la prise en charge de la pseudo-classe :has() dans Firefox et attendre qu’elle soit implémentée. Cela me permettra de conserver un code plus simple et plus facile à gérer.

Je te souhaite aussi une excellente journée.

Amicalement,
Pyanepsion
Maintenant que le problème est exposé je comprends mieux. J'opterais alors pour une approche complètement différente, par exemple via ceci (avec la classe "grid-auto" sur l'élément parent) :
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--size-grid, 15em), 1fr));
}

Le nombre de colonnes s'adaptera selon le nombre d'items présents dans l'élément parent, avec comme condition un minimum de 15em par items. On peut faire un peu plus complexe si besoin.

Un exemple en demo ici (allez-voir la classe "grid-auto") : Grids
Modifié par Olivier C (24 Apr 2023 - 11:39)
Merci, Olivier, pour ta réponse et pour tes démonstrations.
Je ne connaissais pas du tout grid jusqu’à hier. Cela semble résoudre de nombreux petits tracas et je t’en remercie. Après 8 h d’apprentissage, il me faut maintenant transférer l’ancien CSS sur celui-ci et mettre en place les points de rupture.
Voici à tout hasard la page de test que j’ai produit, si cela peut être utile. Vos améliorations sont en tout cas les bienvenues.

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test de grid</title>
  <style>
    :root {
      --menu-largeur: 50%;
    }

    body {
      display: grid;
      grid-template-areas:
        "entete"
        "principal"
        "pied";
      gap: 1rem;
      margin: 0;
      font-family: sans-serif;
      background-color: lightyellow;
    }

    header {
      grid-area: entete;
    }

    main {
      grid-area: principal;
    }

    footer {
      grid-area: pied;
    }

    header, main, footer {
      display: grid;
      grid-template-columns: auto var(--menu-largeur) auto;
      background-color: lightgreen;
      gap: 1rem;
    }

    header > div, main > div, footer > div {
      background-color: lightblue;
      text-align: center;
      box-sizing: border-box;
    }

    .ligne {
      grid-column: 1 / -1; /* S'étend sur les trois colonnes */
      display: grid;
      grid-template-columns: auto var(--menu-largeur) auto;
      gap: 1rem;
    }

    .ligne-bicephale {
      grid-column: 1 / -1; /* S'étend sur les trois colonnes */
      display: grid;
      grid-template-columns: 50% 50%;
      gap: 1rem;
    }

    .ligne-totale {
      grid-column: 1 / -1; /* S'étend sur les trois colonnes */
      display: grid;
      grid-template-columns: 100%;
      gap: 1rem;
      background-color: lightyellow;
    }

    .colonne-gauche, .colonne-droite {
      background-color: lightcoral;
    }

    .colonne-principale {
      min-height: 100px;
      display: flex;
      justify-content: space-between;
    }

    .colonne-principale.vignettes {
      display: flex;
      flex-wrap: wrap;
      gap: 1rem;
      justify-content: space-between;
      align-content: flex-start;
    }

    .vignette {
      flex: 0 0 calc(100% / 12 - 1rem);
      background-color: green;
      text-align: center;
      padding: 1rem;
      box-sizing: border-box;
    }

    .colonne-pied {
      display: flex;
      justify-content: space-between;
    }

    .pied-menu {
      flex: 1;
    }
        </style>
</head>
<body>
  <header>
    <div class="colonne-gauche">Menu gauche 1</div>
    <div class="menu">Menu 1</div>
    <div class="colonne-droite">Menu droite 1</div>
    <div></div>
    <div class="menu">Menu 2</div>
    <div></div>
  </header>
  <main>
    <!-- Ligne en 2 colonnes -->
    <div class="ligne-bicephale">
      <div class="colonne-gauche">Bicéphale gauche 1</div>
      <div class="colonne-droite">Bicéphale droite 1</div>
    </div>
    <!-- Ligne standard en 3 colonnes -->
    <div class="ligne">
      <div class="colonne-gauche">Gauche 1</div>
      <div class="colonne-principale">Ligne 1</div>
      <div class="colonne-droite">Droite 1</div>
    </div>
    <!-- Ligne de vignettes -->
    <div class="ligne">
      <div class="colonne-gauche">Gauche 2</div>
      <div class="colonne-principale vignettes">
        <div class="vignette">Vignette 1</div>
        <div class="vignette">Vignette 2</div>
        <div class="vignette">Vignette 3</div>
        <div class="vignette">Vignette 4</div>
        <div class="vignette">Vignette 5</div>
        <div class="vignette">Vignette 6</div>
        <div class="vignette">Vignette 7</div>
        <div class="vignette">Vignette 8</div>
        <div class="vignette">Vignette 9</div>
        <div class="vignette">Vignette 10</div>
        <div class="vignette">Vignette 11</div>
        <div class="vignette">Vignette 12</div>
      </div>
      <div class="colonne-droite">Droite 2</p></div>
    </div>
    <!-- Ligne standard en 3 colonnes -->
    <div class="ligne">
      <div class="colonne-gauche">Gauche 3</div>
      <div class="colonne-principale">Ligne 3</div>
      <div class="colonne-droite">Droite 3</div>
    </div>
    <!-- Ligne 1 colonne -->
    <div class="ligne-totale">
      <div>Ligne totale 1</div>
    </div>
    <div class="ligne-totale">
      <div>Ligne totale 2</div>
      <div>Ligne totale 3</div>
    </div>
  </main>
  <footer>
    <div class="colonne-gauche">Pied gauche</div>
    <div class="colonne-pied">
      <div class="pied-menu">
        <div>Navigation 1.1</div>
        <div>Navigation 1.2</div>
        <div>Navigation 1.3</div>
      </div>
      <div class="pied-menu">
        <div>Navigation 2.1</div>
        <div>Navigation 2.2</div>
      </div>
      <div class="pied-menu">
        <div>Navigation 3.1</div>
        <div>Navigation 3.2</div>
        <div>Navigation 3.3</div>
        <div>Navigation 3.4</div>
      </div>
      <div class="pied-menu">
        <div>Navigation 4.1</div>
      </div>
    </div>
    <div class="colonne-droite">Pied droit</div>
  </footer>
</body>
</html>
Modérateur
J'éviterais le flex sur .colonne-principale.vignettes et je partirais sur un display: grid. Tu pourras plus facilement gérer avec les columns depuis le parent plutôt qu'avec un calcul de flex-basis sur ta vignette et ton gap fera le reste du travail.

Le display: grid sur <body> avec les grid-areas me semble vraiment inutiles dans ce cas-ci.

Ce n'est pas encore disponible, mais regarde déjà aux prochaines possibilités que subgrid va offrir Cela simplifiera encore ton code.

Et enfin, c'est cool de voir comme tu investigues les différentes alternatives Smiley smile
Modifié par Yordi (26 Apr 2023 - 15:48)