0

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.

djvg
  • 11,722
  • 5
  • 72
  • 103

2 Answers2

0

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>
djvg
  • 11,722
  • 5
  • 72
  • 103
  • a good indicator to stop using such messy framework. It's using a clearfix so I suppose it still uses Float. – Temani Afif Mar 16 '23 at 10:47
  • @TemaniAfif I agree, but, unfortunately, it's not my choice. – djvg Mar 16 '23 at 10:49
  • well, you are combining grid with an old framework so you have the choice. You have to choose one way not combine both. Either the old framework or the modern ways – Temani Afif Mar 16 '23 at 10:52
  • @TemaniAfif The rest of the codebase uses w3.css. Prevailing guideline is *not* to add custom styling, unless there is no other way. In this case there *is* a simple way to work around the problem. This Q&A is just intended to inform other people that may run into a similar issue. – djvg Mar 16 '23 at 11:15
0

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>
L. Alejandro M.
  • 619
  • 6
  • 14
  • Thanks, but this is beside the point. The example provided is just a minimal reproducible example. W3.CSS "fluid grid" has many limitations that do not match with our requirements. – djvg Mar 20 '23 at 07:51