2
votes

Une grille est-elle possible avec des éléments représentant des lignes en CSS?

J'essaie de reproduire cette conception en utilisant HTML / CSS pour un navigateur moderne:

entrez la description de l'image ici

C'est essentiellement un tableau, avec des lignes et des colonnes , cela signifie que si la cellule de nom d'une ligne devient plus grande, elle devrait devenir plus grande pour tous. Je vois deux possibilités: les tableaux et la grille CSS.

Les lignes dans les tableaux, pour autant que je sache, ne sont pas assez stylables, elles ne peuvent pas prendre un rayon de bordure par exemple, je n'ai pas essayé box shadow.

Si j'utilise une grille CSS, je peux styliser les cellules pour simuler le rayon de la bordure à la fin, mais alors l'ombre de la boîte devient impossible car l'ombre de la boîte de la deuxième cellule recouvre la première.

Je pense que le problème se résume à avoir des éléments qui représentent des lignes pour le style mais toujours à l'intérieur de chacune d'elles, les cellules doivent avoir la même largeur que dans les autres lignes, pour représenter les colonnes.

Y a-t-il un moyen en CSS pour y parvenir?

Par exemple, voici une tentative de le faire avec la table HTML dans laquelle la marge et le rayon de la bordure n'ont aucun effet: p>

<div class="table">
  <div class="row">
    <div class="cell">Eva Lee</div>
    <div class="cell">Call back</div>
    <div class="cell">15/02/19</div>
  </div>
  <div class="row">
    <div class="cell">Evelyn Allen</div>
    <div class="cell">Call back</div>
    <div class="cell">14/01/19</div>
  </div>
  <div class="row">
    <div class="cell">Slawomir Pelikan</div>
    <div class="cell">Voicemail</div>
    <div class="cell">14/01/19</div>
  </div>
  <div class="row">
    <div class="cell">Christopher Walken</div>
    <div class="cell">Voicemail</div>
    <div class="cell">14/01/19</div>
  </div>
</div>
.table {
  display: table;
  border-collapse: collapse;
}

.row {
  display: table-row;
  background-color: grey;
  border-radius: 8px;
  margin: 10px;
}

.cell {
  display: table-cell;
}

Voici une autre tentative, en utilisant display: table , qui agit de la même manière que table:

<table>
  <tr>
    <td>Eva Lee</td>
    <td>Call back</td>
    <td>15/02/19</td>
  </tr>
  <tr>
    <td>Evelyn Allen</td>
    <td>Call back</td>
    <td>14/01/19</td>
  </tr>
  <tr>
    <td>Slawomir Pelikan</td>
    <td>Voicemail</td>
    <td>14/01/19</td>
  </tr>
  <tr>
    <td>Christopher Walken</td>
    <td>Voicemail</td>
    <td>14/01/19</td>
  </tr>
</table>
table {
  border-collapse: collapse;
}

tr {
  background-color: grey;
  border-radius: 8px;
  margin: 10px;
}


3 commentaires

utilisez display: table et vous éviterez le tableau et pourrez toujours avoir la mise en page du tableau avec les styles que vous souhaitez


@TemaniAfif: Je pense que cela présente les mêmes défauts que le tableau. J'ai mis à jour la question pour inclure des exemples.


J'ai modifié ma réponse pour inclure les styles nécessaires


3 Réponses :


0
votes

Vous pouvez résoudre le problème de style avec une astuce. Voici un exemple où je me fie à un pseudo élément pour styliser une ligne:

<div class="table">
  <div class="row">
    <div class="cell">Eva Lee</div>
    <div class="cell"><span>Call back</span></div>
    <div class="cell">15/02/19</div>
  </div>
  <div class="row">
    <div class="cell">Evelyn Allen</div>
    <div class="cell"><span>Call back back</span></div>
    <div class="cell">14/01/2019</div>
  </div>
  <div class="row">
    <div class="cell">Slawomir Pelikan</div>
    <div class="cell"><span>Voicemail</span></div>
    <div class="cell">14/01/19</div>
  </div>
  <div class="row">
    <div class="cell">Christopher Walken</div>
    <div class="cell"><span>Voicemail Voicemail</span></div>
    <div class="cell">14/01/19</div>
  </div>
</div>
.table {
  display: table;
  border-collapse: collapse;
}

.row {
  display: table-row;
}

.cell {
  display: table-cell;
  position: relative;
  z-index: 0;
  padding: 5px;
}

.cell span {
  background: orange;
  color: #fff;
  border-radius: 10px;
  padding: 2px 4px;
}

.cell:first-child {
  padding: 10px 5px 20px;
  width: 50%;
}

.cell:before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 10px;
  background: #fff;
  border: 1px solid grey;
}

.cell:first-child:before {
  border-right: 0;
  border-radius: 8px 0 0 8px;
  background:#fff;
  box-shadow: -1px 0 6px;
}

.cell:last-child:before {
  border-left: 0;
  border-radius: 0 8px 8px 0;
  background: #fff;
  box-shadow: 1px 0 6px;
}

.cell:nth-child(2) {
  text-align: center;
  z-index: 1;
}

.cell:nth-child(2):before {
  border-right: 0;
  border-left: 0;
  box-shadow: 0 0 6px;
}

.cell:nth-child(2):after {
  content: "";
  position: absolute;
  top: 1px;
  bottom: 11px;
  left: -5px;
  right: -5px;
  background: 
   linear-gradient(green,green) left 5px top 50%/ 2px 80% no-repeat,
   linear-gradient(green,green) right 5px top 50%/ 2px 80% no-repeat,
  #fff;
  z-index: -1;
}

body {
  background: #f3f3f3;
}


4 commentaires

Comment intégrez-vous box-shadow dans cela?


@yunzen vérifie la mise à jour, une ombre sur tous les côtés;)


Bien qu'il s'agisse techniquement d'une ombre, cela ressemble plus à une lueur extérieure. Qu'en est-il des ombres portées comme ceci: box-shadow: 3px 3px 5px rgba (0,0,0,0.3); ?


@yunzen bien, il peut être ajusté au besoin, j'ai fait de tout le côté pour le montrer possible, on peut alors le traduire facilement



1
votes

Edit 1

Cela fonctionne dans FF, Chrome, MSIE, MS Edge.
Le bord pourrait avoir besoin d'un petit ajustement, car les cellules du tableau ont une largeur de sous-pixel, si maintenant la largeur de pixel est donnée, ce qui conduit à des barres verticales ennuyeuses.

Cela fonctionne en utilisant des marges négatives sur div code> s qui enveloppent le contenu des cellules et overflow: hidden sur les cellules.

<table>
  <tr>
    <td>Eva Lee</td>
    <td>Call back</td>
    <td>15/02/19</td>
  </tr>
  <tr>
    <td>Evelyn Allen</td>
    <td>Call back</td>
    <td>14/01/19</td>
  </tr>
  <tr>
    <td>Slawomir Pelikan</td>
    <td>Voicemail</td>
    <td>14/01/19</td>
  </tr>
  <tr>
    <td>Christopher Walken</td>
    <td>Voicemail</td>
    <td>14/01/19</td>
  </tr>
</table>
table {
  border-spacing: 10px;
  border-collapse: separate;
}

tr {
  position: relative;
  margin: 10px;
}
tr:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: gold;
  z-index: -1;
  border-radius: 20px;
  box-shadow: 3px 2px 5px rgba(0, 0, 0, 0.25);
}

td {
  padding: 10px;
}

Ancien, ne fonctionne pas sous Chrome

Que diriez-vous d'un peu de magie de pseudo-élément?

<table>
  <tr>
    <td>
      <div>Lorem.</div>
    </td>
    <td>
      <div>Ea!</div>
    </td>
    <td>
      <div>Animi.</div>
    </td>
  </tr>
  <tr>
    <td>
      <div>Quas!</div>
    </td>
    <td>
      <div>Dolor!</div>
    </td>
    <td>
      <div>Suscipit.</div>
    </td>
  </tr>
  <tr>
    <td>
      <div>Mollitia?</div>
    </td>
    <td>
      <div>Inventore!</div>
    </td>
    <td>
      <div>Dolorem.</div>
    </td>
  </tr>
</table>
table {
  border-collapse: collapse;
  border-spacing: 0;
}
table tr td {
  overflow: hidden;
  padding: 0 0 5px 0;
}
table tr td > div {
  background-color: gold;
  padding: 4px;
  border-radius: 0px;
  box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
  margin-left: -10px;
  margin-right: -10px;
  padding-left: 14px;
  padding-right: 14px;
}
table tr td:first-child {
  padding-left: 10px;
}
table tr td:first-child > div {
  border-radius: 10px 0 0 10px;
}
table tr td:last-child {
  padding-right: 20px;
}
table tr td:last-child > div {
  border-radius: 0 10px 10px 0;
}

7 commentaires

Lorsque j'exécute l'extrait de code, la sortie ne ressemble pas à la conception que j'ai publiée.


Je ne vais pas reproduire votre conception. Je vous ai seulement donné un indice pour gérer les problèmes de rayon de bordure et d'ombre.


Oui, mais vous appliquez un rayon de bordure à une table, cela fonctionne. Le problème est d'appliquer un rayon de bordure et une ombre de boîte à un tr.


Veuillez regarder à nouveau. J'applique le rayon de bordure Nd shadow à un pseudo élément qui est positionné absolument à l'intérieur du tr relatif


vous testez votre code en utilisant FF, je suppose. Le pseudo élément sur tr ne fonctionne pas sur Chrome (je ne sais pas pour l'autre navigateur) mais pour autant que je sache, ils ne sont pas censés fonctionner sur tr .. c'est pourquoi je les ai utilisés sur td dans ma réponse


@TemaniAfif Vous avez absolument raison. Je ne l'ai pas testé dans Chrome. J'ai supposé que cela fonctionnait là-bas. Si cette méthode ne fonctionne pas, je ne peux pas trouver une solution différente.


@pupeno j'ai fait une modification et une nouvelle approche dans ma réponse



0
votes

Grilles de lignes avec ombre de boîte

Pour corriger l'ombre de boîte au lieu de créer une grille avec des éléments.
Je crée une grille pour chaque ligne.
Cela nous permet de créer la fonction de taille des lignes.
Tout en tenant toujours les éléments d'une ligne sur lesquels appliquer une ombre de boîte.

<div class="container">
  <div class="row">
    <div class="name">
      Lee Wong
    </div>
    <div class="status">
      <span class="decoration error">
      error
      </span>
    </div>
    <div class="date">
      12/5/2020
    </div>
  </div>
  <div class="row">
    <div class="name">
      Lee Wong
    </div>
    <div class="status">
      <span class="decoration error">
      error
      </span>
    </div>
    <div class="date">
      12/5/2020
    </div>
  </div>
  <div class="row">
    <div class="name">
      Lee Wong
    </div>
    <div class="status">
      <span class="decoration error">
      error
      </span>
    </div>
    <div class="date">
      12/5/2020
    </div>
  </div>

</div>
body {
  background-color: #eee;
}

.container {
  width: 100%;
}

.row {
  display: grid;
  grid-template-columns: 1fr 150px 200px;
  width: 100%;
  /* box-shadow: 0px 0px 0px 1px #222; */
  margin: 10px 0px;
  border-radius: 5px;
  box-shadow: 0px 0px 2px 0px #222;
}

.name {}

.status {
  position: relative;
  text-align: center;
  width: 150px;
}

.status:before {
  content: "";
  position: absolute;
  display: inline-block;
  border-left: 2px solid #aaa;
  height: calc(1em + 20px);
  left: 0;
  top: 5px;
}

.status:after {
  content: "";
  position: absolute;
  display: inline-block;
  border-left: 2px solid #aaa;
  height: calc(1em + 20px);
  right: 0;
  top: 5px;
}

.decoration {
  width: 100%;
  padding: 2px 30px;
  border-radius: 50px;
}

.decoration.error {
  background-color: tomato;
}

.date {
  text-align: center;
}

.container .row div {
  background-color: white;
  padding: 15px;
}

.container .row div:first-of-type {
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
}

.container .row div:last-of-type {
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}


3 commentaires

Remarque. Bien que cela fonctionne comme prévu, cela ne fonctionne que s'il n'y a qu'une seule colonne non auto par ligne.


jsfiddle.net/qe8367o1 Vous pouvez avoir plusieurs colonnes automatiques. Mais votre balisage doit correspondre au css donné. Il est possible de configurer la grille avec des noms de zone pour contourner cela.


Si vous voulez une taille de texte indépendante, utilisez 1fr 1fr 150px 200px au lieu de auto auto 150px 200px .