web-dev-qa-db-fra.com

CSS: display: grid et/ou -ms-grid

Existe-t-il un moyen d'utiliser les deux ou l'un des display: grid/-ms-grid dans une seule feuille de style ou dois-je utiliser un piratage HTML ou JavaScript pour demander quel type de navigateur une page est affichée avec une présentation en grille?

Exemple:

Le style suivant ne semble pas fonctionner

.container {
  display: grid -ms-grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(150px, 50px);
  grid-gap: 1vw;
  -ms-grid-columns: repeat(4, 1fr);
  -ms-grid-rows: repeat(150px, 50px);
  -ms-grid-gap: 1vw;
}
10
Mr. Bean

Transformer la nouvelle syntaxe de mise en page CSS Grid en une version obsolète d'IE/Edge est vraiment un défi. Il ne suffit pas d'ajouter des préfixes de vendeurs.

IE/Edge ne supporte que très peu ce qui est présent dans la nouvelle version de CSS Grid Layout. Il n'y a pas de support IE/Edge de

  • placement automatique et sélection de son déroulement (grid-auto-flow propriété CSS);
  • colonnes/lignes répétées (fonction repeat et certaines valeurs spéciales telles que auto-fill et auto-fit). Dans certains cas, cela signifie que vous devrez simplement remplacer par des valeurs explicites, comme dans votre cas, vous pouvez remplacer grid-template-columns: repeat(4, 1fr) par -ms-grid-columns: 1fr 1fr 1fr 1fr et cela fonctionnera parfaitement. Mais si vous avez quelque chose comme grid-template-columns: repeat(auto-fill, 1fr), il est impossible de l'implémenter dans IE/Edge;
  • espace entre les cellules de la grille (grid-row-gap, grid-column-gap, grid-gap propriétés CSS). Les lacunes peuvent être simulées à l’aide de pistes de grille supplémentaires;
  • pistes générées automatiquement (grid-auto-columns, grid-auto-rows propriétés CSS);
  • zones de grille nommées (grid-area, grid-template-areas propriétés CSS).

Vous devez juste oublier ces possibilités pour IE.

De plus, certaines valeurs des propriétés IE prises en charge ne sont pas prises en charge.

Autoplacement

Il n'y a pas de comportement de placement automatique dans l'implémentation IE/Edge. Cela signifie que vous devez tout positionner plutôt que d'utiliser la capacité de placement automatique de la grille.

Si vous ne placez pas d’éléments, ils s’empileront dans la première cellule de la grille. Cela signifie que vous devez définir explicitement la position pour chaque élément de la grille, sinon celui-ci réside dans la première cellule. Si vous avez un balisage comme ceci:

.wrapper {
  display: -ms-grid;
  display: grid;
  grid-gap: 10px;
  -ms-grid-columns: 50px 50px;
  grid-template-columns: 50px 50px;
  -ms-grid-rows: 50px 50px;
  grid-template-rows: 50px 50px;
  background-color: #fff;
  color: #444;
}

.box {
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
}
<div class="wrapper">
  <div class="box a">A</div>
  <div class="box b">B</div>
  <div class="box c">C</div>
  <div class="box d">D</div>
</div>

Vous verrez quelque chose dans IE/Edge

 IE grid demo


Donc, fondamentalement, vous avez deux options (méthodologies) lors du développement de CSS Grid pour IE/Edge (si vous savez que la présentation dans votre cas peut être transformée):

  • Générez des balises différentes pour les navigateurs IE/Edge et les autres navigateurs. Dans ce cas, vous ne vous souciez pas de la similarité des balises (en passant, votre valeur de grid-template-rows: repeat(150px, 50px) est invalide, donc je suppose que vous vouliez grid-template-rows: 150px 50px). Démo pour votre cas

    .container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: 150px 50px;
      grid-gap: 1vw;
      
      display: -ms-grid;
      /* also faking 1vw grid-gap */
      -ms-grid-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      /* also faking 1vw grid-gap */
      -ms-grid-rows: 150px 1vw 50px;
    }
    
    .grid-item {
      /* style just for demo */
      background-color: yellow;
    }
    
    /* Explicit placement for IE/Edge */
    /* Omitting default value of -ms-grid-column: 1 and -ms-grid-row: 1 where possible */
    .grid-item:nth-child(2) {
      -ms-grid-column: 3;
    }
    
    .grid-item:nth-child(3) {
      -ms-grid-column: 5;
    }
    
    .grid-item:nth-child(4) {
      -ms-grid-column: 7;
    }
    
    .grid-item:nth-child(5) {
      -ms-grid-row: 3;
    }
    
    .grid-item:nth-child(6) {
      -ms-grid-row: 3;
      -ms-grid-column: 3;
    }
    
    .grid-item:nth-child(7) {
      -ms-grid-row: 3;
      -ms-grid-column: 5;
    }
    
    .grid-item:nth-child(8) {
      -ms-grid-row: 3;
      -ms-grid-column: 7;
    }
    <div class="container">
      <div class="grid-item">1,1</div>
      <div class="grid-item">1,2</div>
      <div class="grid-item">1,3</div>
      <div class="grid-item">1,4</div>
      <div class="grid-item">2,1</div>
      <div class="grid-item">2,2</div>
      <div class="grid-item">2,3</div>
      <div class="grid-item">2,4</div>
    </div>

  • Générez un balisage très similaire pour les navigateurs IE/Edge. Dans ce cas, le balisage de tous les navigateurs sera très similaire. Cela pourrait être plus facile à gérer car vous ne devriez pas vous soucier de différentes approches. Démo pour votre cas:

    .container {
      display: -ms-grid;
      display: grid;
      /* also faking 1vw grid-gap */
      -ms-grid-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      grid-template-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      /* also faking 1vw grid-gap */
      -ms-grid-rows: 150px 1vw 50px;
      grid-template-rows: 150px 1vw 50px;
    }
    
    .grid-item {
      /* style just for demo */
      background-color: yellow;
    }
    
    .grid-item:nth-child(2) {
      -ms-grid-column: 3;
      grid-column: 3;
    }
    
    .grid-item:nth-child(3) {
      -ms-grid-column: 5;
      grid-column: 5;
    }
    
    .grid-item:nth-child(4) {
      -ms-grid-column: 7;
      grid-column: 7;
    }
    
    .grid-item:nth-child(5) {
      -ms-grid-row: 3;
      grid-row: 3;
    }
    
    .grid-item:nth-child(6) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 3;
      grid-column: 3;
    }
    
    .grid-item:nth-child(7) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 5;
      grid-column: 5;
    }
    
    .grid-item:nth-child(8) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 7;
      grid-column: 7;
    }
    <div class="container">
      <div class="grid-item">1,1</div>
      <div class="grid-item">1,2</div>
      <div class="grid-item">1,3</div>
      <div class="grid-item">1,4</div>
      <div class="grid-item">2,1</div>
      <div class="grid-item">2,2</div>
      <div class="grid-item">2,3</div>
      <div class="grid-item">2,4</div>
    </div>

19
Vadim Ovchinnikov

Votre règle display doit être structurée correctement. Ce que vous avez est invalide.

display: grid -ms-grid;

De plus, votre règle grid-template-rows est invalide. Le premier argument est supposé être un entier spécifiant le nombre de répétitions.

grid-template-rows: repeat(150px, 50px);

De plus, je ne crois pas que la notation repeat() existait dans les anciennes spécifications . Il semble que cela ait été introduit dans la spécification current , donc IE ne la prendrait pas en charge.

-ms-grid-columns: repeat(4, 1fr);
-ms-grid-rows: repeat(150px, 50px);

Enfin, il est préférable de placer les propriétés officielles (W3C) après les versions préfixées afin qu'elles soient prioritaires dans la cascade ( plus de détails ).

Essaye ça:

.container {
  display: -ms-grid; 
  display: grid;

  -ms-grid-columns: 1fr 1fr 1fr 1fr;           
  grid-template-columns: repeat(4, 1fr);

  -ms-grid-rows: 150px 50px;
  grid-template-rows: 150px 50px;

  -ms-grid-gap: 1vw;
  grid-gap: 1vw;
}
6
Michael_B

La réponse de Vadim est à peu près ce que vous devriez faire. Mais il existe encore quelques astuces CSS que vous pouvez utiliser pour soulager votre douleur.

0. Assurez-vous de lire ce billet de blog pour décider si vous souhaitez utiliser des grilles pour les sites Web prenant en charge IE: https://rachelandrew.co.uk/archives/2016/11/26/should-i-try-to-use -the-ie-implémentation-de-css-grid-layout/

Si votre réponse à la question précédente est "Oui", lisez la suite:

  1. Utilisez le préfixe automatique. Il remplacera certaines propriétés de la grille CSS par leur équivalent IE. Mais compte tenu de la complexité des propriétés de la grille (répétitions, minmax, étendues, etc.), l’autoprefixeur ne peut pas couvrir tous les cas.
  2. Un compagnon très fiable dans les cas où vous souhaitez écrire du CSS conforme aux spécifications, tout en prenant en charge IE, est la règle @supports(). Je l'utilise pour utiliser les propriétés de grille plus avancées telles que grid-gaps, etc.:

    .card-list {
      grid-row: 4;
      grid-column: 1 / 3;
      padding: 1.5vh 1vh;
      display: grid;
      grid-template-rows: 1fr 1fr;
      grid-template-columns: 1fr 1fr;
    }
    .card {
      margin-bottom: 1vh;
    }
    .card:nth-of-type(odd) {  /* takes care of IE */
      margin-right: 1vh;
      grid-column: 1;
    }
    .card:nth-of-type(even) {
      grid-column: 2;
    }
    
    @supports(grid-gap: 1vh) { /* still using standard code! */
      .card-list {
        grid-gap: 1vh;
      }
      .card {
        margin-right: 0;
        margin-bottom: 0;
      }
    }
    
0
kumar_harsh