2

I am using CSS flexbox for grid based navigation which has 3 columns in row and 'n' no of rows in the grid. The width of the grid-child calculated based on the parent container width (i.e. 100%).

I set margin-right:10px; and margin-bottom:10px; for each 3rd of the grid-child i had set 0px for margin-rightto force the grid-child at the right edge of the parent container.

Everything works fine if a the column equally divided by 3. (i.e. 3 columns per row).

Here the problem is, if last row has only 2 columns then we have 10px space between grid and the grid-child.

Is there any possible solution to get rid of the remaining space.

Please find the below codepen link for better understanding: https://codepen.io/yesvin/pen/xXwBqa

HTML code block:

<div class="menu-wrapper">  
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
       <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>
    <div class="menu">
      <div class="menu-icon">
        <img src="http://via.placeholder.com/80x80"/>
      </div>
      <div class="menu-name">
        <p>Txt</p>
      </div>
    </div>  
</div>

CSS code block:

.menu-wrapper {
  width:100%;
  height:100%;
  display: flex;    
  flex-wrap:wrap;
  margin:0px; 

  .menu {
    display: inline-block;
    border:solid 1px #ccc;
    margin:0 10px 10px 0;    
    flex-grow: 1;      
    width: calc(33% - 10px);
  }
  .menu:nth-child(3n) {
    margin-right:0;
  }
  .menu-icon {
    text-align:center;
  }
  .menu-name {
    width:80%;
    margin:0 auto;
    text-align:center;
  }
}

Problem:

enter image description here

Required result

enter image description here

Thanks in advance.

NOTE: It is possible to achieve the similar effect by split the each row in a separate flexbox styling. But, I don't want that, because, the 'n' no. of menus are dynamically appending inside the menu-wrapper.

Yesvinkumar
  • 559
  • 10
  • 28

1 Answers1

2

Simply add margin-right:0 to the last child to remove this space :

.menu-wrapper .menu:last-child {
    margin-right: 0;
}

This will work in any case :

  • if you already have 3 it's already 0
  • if you have one or two it will remove the undesired space.

Full code with 1 items in the last row :

.menu-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  margin: 0px;
}

.menu-wrapper .menu {
  display: inline-block;
  border: solid 1px #ccc;
  margin: 0 10px 10px 0;
  flex-grow: 1;
  width: calc(33% - 10px);
}

.menu-wrapper .menu:nth-child(3n),
.menu-wrapper .menu:last-child {
  margin-right: 0;
}

.menu-wrapper .menu-icon {
  text-align: center;
}

.menu-wrapper .menu-name {
  width: 80%;
  margin: 0 auto;
  text-align: center;
}
<div class="menu-wrapper">
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>


</div>

Full code with 2 items in the last row :

.menu-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  margin: 0px;
}

.menu-wrapper .menu {
  display: inline-block;
  border: solid 1px #ccc;
  margin: 0 10px 10px 0;
  flex-grow: 1;
  width: calc(33% - 10px);
}

.menu-wrapper .menu:nth-child(3n),
.menu-wrapper .menu:last-child {
  margin-right: 0;
}

.menu-wrapper .menu-icon {
  text-align: center;
}

.menu-wrapper .menu-name {
  width: 80%;
  margin: 0 auto;
  text-align: center;
}
<div class="menu-wrapper">
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
   <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>

</div>

Full code with 3 items in the last row :

.menu-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  margin: 0px;
}

.menu-wrapper .menu {
  display: inline-block;
  border: solid 1px #ccc;
  margin: 0 10px 10px 0;
  flex-grow: 1;
  width: calc(33% - 10px);
}

.menu-wrapper .menu:nth-child(3n),
.menu-wrapper .menu:last-child {
  margin-right: 0;
}

.menu-wrapper .menu-icon {
  text-align: center;
}

.menu-wrapper .menu-name {
  width: 80%;
  margin: 0 auto;
  text-align: center;
}
<div class="menu-wrapper">
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
   <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>
  <div class="menu">
    <div class="menu-icon">
      <img src="http://via.placeholder.com/80x80" />
    </div>
    <div class="menu-name">
      <p>Txt</p>
    </div>
  </div>

</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thank you very much. +1 for the solution – Yesvinkumar Dec 07 '17 at 04:51
  • Is there any possibility to implementing animation / transition for the above code.. (i.e) If i click on any one of the child.. remaining children needs to hide.. and the clicked one to be animating to fill the whole parent grid width and height.. with exact tranform origin. (If we click on the third one, it should animate the width and height by right to left ). I tried and come up with the following ... https://codepen.io/yesvin/pen/NwVJYo but it is not similar to the android mobile app drawer icon.. (In Android mobile, if you click app drawer icon it will show sub items).. – Yesvinkumar Dec 07 '17 at 13:33
  • without flex codepen link https://codepen.io/yesvin/pen/oorgwM – Yesvinkumar Dec 07 '17 at 13:54
  • @Yesvinkumar you are trying to use display property which is not good for animation. What i sugest you is to consider using absolute position and stretch the element using top/left/right/bottom to make it full width and with a high z-index you will hide the other so no need to hide them – Temani Afif Dec 07 '17 at 20:42