Comparing and contrasting: Grid, Margin, Flex, Float

Which would you say is the most reliable?

What are your thoughts on how Grid is set up?

Which is the best, which is the worst to use?

How would you rate each of them?

Grid, Margin, Flex, Float


On these, overflow:hidden is removed

and replaced with:

.wrapd.inactive .nav {
  display: none;
}

Instead of:

.wrapd.inactive  a {
  display: none;
}

Another View:
https://jsfiddle.net/theq2pxL/12/

On those you can see that there is no overflow,
and that the height on all of them are 174px.

Using the same method:

.wrapd.inactive .nav {
  display: none;
}

Can someone comment on this?

On the removal of overflow:hidden;

What are your thoughts on that?

@PaulOB @Ray.H



Grid:
https://jsfiddle.net/g8rpf5rz/4/

.wrapa .nav {
  display: grid;
  width: 266px;
  height: 174px;
  grid-gap: 12px 4px;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(5, 1fr);

Margin:
https://jsfiddle.net/m9wexxny/14/

.wrapb .nav div {
  margin: 0 0 12px 0;
}

.wrapb .nav a {
  display: block;
  width: 50px;
  height: 50px;
  margin: -50px 0 0;
  background: rgba(0, 0, 0, 0.2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

.wrapb .nav a:hover {
  border: 3px solid red;
}

.wrapb .nav a.x1 {
  margin: 0;
}

.wrapb .nav a.x2 {
  margin-left: 54px;
}

.wrapb .nav a.x3 {
  margin-left: 108px;
}

.wrapb .nav a.x4 {
  margin-left: 162px;
}

.wrapb .nav a.x5 {
  margin-left: 216px;
}

Flex:
https://jsfiddle.net/m9wexxny/10/


.wrapc .nav div {
  margin: 0 0 12px 0;
  display: flex;
}

.wrapc .nav a {
  display: block;
  width: 50px;
  height: 50px;
  background: rgba(0, 0, 0, .2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

.wrapc a.x2,
.wrapc a.x4 {
  margin: 0 4px;
}

Float:
https://jsfiddle.net/nodzr9gt/



.wrapd .nav a {
  float: left;
  width: 50px;
  height: 50px;
  margin: 0 4px 12px 0;
  color: transparent;
  background: rgba(0, 0, 0, .2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

I have commented on this several times now but you seem to ignore the comments. The float demo needs the overflow because it will snag any content that follows as shown in this screenshot.

Grid: Plus: Good if you want to support only the very newest browsers. Minus: Code is more complex to understand unless you are familiar with it.

Flex: Plus: Easiest of the bunch (in this case) and much greater support than grid. Minus : Some bugs in IE and code can get complex for more sophisticated layouts…

Margin: No plus for this method: Never do this as it is unusable in a real situation and is a magic number nightmare. Did I say never ever do this.

Float: Plus : Will work back to year dot in every browser ever invented (almost). Simple to set up and use. Minus : Need to understand what float containment means.

7 Likes

Did you mean to say grid there, Paul?

1 Like

Whoops well caught I’ll change it now :blush:

1 Like

@PaulOB

What I mean is, isn’t it better:

To have display:none; on .nav, rather than 'a'

Or do you not agree with this?

And if you don’t agree, why not?

.nav is containing the ‘a’, so wouldn’t it be better to have display:none; on .nav instead?

This:

.wrapd.inactive .nav {
  display: none;
}

Instead of:

.wrapd.inactive  a {
  display: none;
}


.wrapd {
  position: relative;
  width: 266px;
  height: 174px;
  margin-top: 8px;
  overflow: hidden;
}


  <div class="nav">
    <a href="" target="_blank" title=""></a>
 <a href="" target="_blank" title=""></a>
 <a href="" target="_blank" title=""></a>
   </div>

@PaulOB

When referring to the magic number nightmare, you mean this, right?

margin: -50px 0 0

Because it has a negative number, and that’s not good, right?

This explains magic numbers: https://css-tricks.com/magic-numbers-in-css/

2 Likes

Assuming that .nav has no functional impact on the layout then yes it would be better to get rid of the whole block.

On its own that wouldn’t be too bad but you also have various left margins on each element with specific amounts. Imagine how much work that would be too change if you changed the size of the element. It’s an unworkable practice that works only for one use case because it relies on magic numbers.

2 Likes

I thought only negative numbers are considered magic numbers?

.wrapb .nav a.x1 {
  margin: 0;
}

.wrapb .nav a.x2 {
  margin-left: 54px;
}

.wrapb .nav a.x3 {
  margin-left: 108px;
}

.wrapb .nav a.x4 {
  margin-left: 162px;
}

.wrapb .nav a.x5 {
  margin-left: 216px;
}

Wait a second, by itself the -50 is not too bad, but it would be a pain if I had to change the size of the whole element, that’s what you mean.

Thank you for showing me this example.

Now I see why hidden is needed, and how to test it.

No any number that relies on something else to be consistent is basically a magic number. If you change one then you have to change everything else that relies on it.

Read the link we have posted (see gandalf’s post above) as it is clearly explained. I have posted that same link numerous times in your threads so there is no excuse not to know what we mean by magic numbers.

5 Likes

So all of those numbers from post #9 are magic numbers, those being 54px, 108px, 162px, and 216px.

In that link above the anchors are all set to display:block; which by default stacks blocks one below another, A perfectly normal layout method for web pages.

But in a situation where you want your elements to be inline with each other, then you reach for a tool that puts you in that direction off the bat.

float: left or right;
display: inline-block;
flex-direction: row;

Then you won’t need classes on every anchor to manipulate it out of it’s normal flow like you’ve done with all those margins from post #9. That is not too much different than using position:relative to move boxes around, they only move visually while they retain their original place. Things get out of hand real quick and each manipulated position is dependent on the other.

That layout is held together by this one rule margin: -50px 0 0;

.wrapb .nav a {
  display: block;
  width: 50px;
  height: 50px;
 /* margin: -50px 0 0; */
  background: rgba(0, 0, 0, 0.2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

With that rule removed or altered you get this…

If you ever needed to change the dimensions on the main container you would have a lot of unnecessary work to do.

1 Like

What do I do next?

  float: left;
  display: inline-block;
  flex-direction: row;

That all depends on what you are wanting to achieve? Is it grid, flex, margin, or float?

I just realized display:block; isn’t needed on flex.

.wrapc .nav a {
  /*display: block;*/
  width: 50px;
  height: 50px;
  background: rgba(0, 0, 0, .2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

This isn’t working:

.wrapb .nav div {
  margin: 0 0 12px 0;
}

.wrapb .nav a {
  display: inline-block;
  flex-direction: row;
  width: 50px;
  height: 50px;
  margin: 0 0 2px 0;

Personally, I would go with something that required less work on your end.
Let the display model do the heavy lifting and positioning for you.

display:table; might work out for you.

Just a quick example of it’s automatic layout model.
Of course you would need to tailor it to your needs.

The entire layout is controlled by the anchor dimensions :slight_smile:
EDIT: 3px border on each anchor butted together = 6px

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.wrap {
   display:table; /*shrink to fit without width*/
   margin:0 auto;
   border:3px solid red;
   position:relative;
}
.wrap div {
   display:table-row;
}
.wrap a {
   display:table-cell;
   width:50px;
   height:50px;
   border:3px solid blue;
   background:lime;
}
   .wrap::after,
   .wrap::before {
       content: "";
       position:absolute;
       width:3px;
       height:100%;
       top:0; left:calc(33.3% - 1px);
       background:red;
   }
   .wrap::before {
      left:auto;
      right:calc(33.3% - 1px);
   }
</style>

</head>
<body>

<div class="wrap">
   <div>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
   </div>
   <div>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
   </div>
   <div>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
      <a></a>
   </div>
</div>

</body>
</html>

What am I doing wrong?

It’s not working.

.wrapb {
  display: table;
  position: relative;
  width: 266px;
  height: 174px;
  margin-top: 8px;
  background: red;
}

.wrapb div {
   display:table-row;
}

.wrapb .nav a {
  display: table-cell;
  width: 50px;
  height: 50px;
  margin:3px;
  background: rgba(0, 0, 0, 0.2);
  border: 3px solid #0059dd;
  box-sizing: border-box;
}

1 Like

I’m not sure what is wrong above, haven’t looked.

Appears to be something stretching one of the table-cells and the others are following along. That is how tables work.

You probably won’t get a pixel perfect replication of your other methods.

CSS tables follow a different set of rules. For one margins don’t apply to table cells. You would need to use border-spacing instead. Along with border-collapse: separate;

In my other post I said it ‘might work out for you’
But then again it might not. You have to accept it’s layout rules.

2 Likes