Why does the w3-panel class from W3.CSS break my grid layout?

125 Views Asked by At

Working on a site that uses W3.CSS, I came across this issue where adding a w3-panel class to the grid container messes up the layout of the grid items.

This was a bit surprising, as the w3-panel docs only mention that it adds margins and padding:

The w3-panel class adds a 16px top and bottom margin and a 16px left and right padding to any HTML element.

Here's a minimal example of a grid without W3.CSS:

#my-grid {
  /* grid settings */
  display: grid;
  grid-template-columns: repeat(3, 50px);
  /* cosmetics */
  column-gap: 10px;
  background-color: lightsalmon;
}

#my-grid div {
  /* cosmetics */
  background-color: mediumpurple;
}
<div id="my-grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

And here's what happens if we add the w3-panel class from W3.CSS:

#my-grid {
  /* grid settings */
  display: grid;
  grid-template-columns: repeat(3, 50px);
  /* cosmetics */
  column-gap: 10px;
  background-color: lightsalmon;
}

#my-grid div {
  /* cosmetics */
  background-color: mediumpurple;
}
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div id="my-grid" class="w3-panel">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

What is going wrong here? How can we fix this?

This discussion may be related.

2

There are 2 best solutions below

4
djvg On

The W3.CSS source shows that the w3-panel class does a bit more than just add margins and padding.

These are all the CSS rules related to w3-panel, extracted from the W3.CSS source:

w3-panel:after,.w3-panel:before {
  content:"";
  display:table;
  clear:both;
}
.w3-panel {
  padding:0.01em 16px;
  margin-top:16px;
  margin-bottom:16px;
}

The w3-panel:before turns out to be the culprit here, as it creates a pseudo element that is treated as a grid item, as described e.g. here. This is confirmed in the snippet below.

#my-grid {
  /* grid settings */
  display: grid;
  grid-template-columns: repeat(3, 50px);
  /* cosmetics */
  column-gap: 10px;
  background-color: lightsalmon;
}

#my-grid div {
  /* cosmetics */
  background-color: mediumpurple;
}

#my-grid:before {
  /* reproduce the issue */
  content: "";
}
<div id="my-grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

One way to work around this is issue (other than not using w3.css) is not to apply the w3-panel class directly to the grid container itself, but, instead, wrap the grid container in another element. This is probably more robust in general. See snippet below:

#my-grid {
  /* grid settings */
  display: grid;
  grid-template-columns: repeat(3, 50px);
  /* cosmetics */
  column-gap: 10px;
  background-color: lightsalmon;
}

#my-grid div {
  /* cosmetics */
  background-color: mediumpurple;
}
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-panel">
  <div id="my-grid">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
</div>

1
L. Alejandro M. On

I don´t see why mix w3.css with hand coded grid having w3.css your own grid internal support.

One approach to achieve something like your first example could be, for example :

​<div class="w3-row" style="background-color:lightsalmon">
  <div class="w3-col s3 w3-margin-right w3-purple">1</div>
  <div class="w3-col s3 w3-margin-right w3-purple">2</div>
  <div class="w3-col s3 w3-margin-right w3-purple">3</div>
</div>

For more information take a look at w3.css Fluid Grid documentation

Saludos,

<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
<div class="w3-row" style="background-color:lightsalmon">
      <div class="w3-col s3 w3-margin-right w3-purple">1</div>
      <div class="w3-col s3 w3-margin-right w3-purple">2</div>
      <div class="w3-col s3 w3-margin-right w3-purple">3</div>
  </div>

</body>
</html>