Takeshi Tokugawa YD
Takeshi Tokugawa YD

Reputation: 913

Take 2 columns in 2-columns layout but not when 1-column layout in CSS grid without @media

The desired layout for wide screens:

enter image description here

The desired layout for narrow screens:

enter image description here

Initial CSS:

.Layout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  grid-gap: 24px 40px;
}

If I'll set grid-column-start: span 2 for the third element, the layout will be simply broken (it' happen in CSS grid ignores minimal width specified in minmax() in second column question).

Please don't use the media queries because it will nullify the announced free-space-based responsiveness which became available in CSS grid.

Grid has two extremely powerful features for dealing with changes in available space.

<...>

Layout that relies on media queries is tied to the view-port, this isn’t modular — components within a system need to be able to adapt to the space they have available.

🌎 Getting to know CSS Grid Layout

Please say clearly: "it's impossible" if you are sure that it so and skilled in CSS grid.

Upvotes: 4

Views: 8674

Answers (3)

Temani Afif
Temani Afif

Reputation: 272582

Use grid-column: 1/-1;

.box {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  grid-gap: 24px 40px;
}

span {
  height: 50px;
  background: blue;
}

.more {
  grid-column: 1/-1;
  background: red;
}
<div class="box">
  <span></span>
  <span></span>
  <span class="more"></span>
  <span></span>
  <span></span>
</div>

That you can edit like below if you want to always have a maximum of 2 columns:

.box {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(240px,40vw), 1fr));
  grid-gap: 24px 40px;
}

span {
  height: 50px;
  background: blue;
}

.more {
  grid-column: 1/-1;
  background: red;
}
<div class="box">
  <span></span>
  <span></span>
  <span class="more"></span>
  <span></span>
  <span></span>
</div>

Upvotes: 9

vals
vals

Reputation: 64164

A posible solution using flex, like MichaelT

.layout {
  border: solid 1px black;
  margin: 2px;
  position: relative;
}


.innerlayout {
  display: flex;
  flex-wrap: wrap;
  position: relative;
  left: -10px;
  right: 10px;
  width: calc(100% + 20px);
}

span {
    background-color: green;
    height: 40px;
    min-width: 240px;
    width: 40%;
    margin: 15px 10px;
    flex-grow: 1;
}

.wide {
    width: 100%;
    background-color: red;
}

#narrow {
    width: 300px;
}
<div class="layout">
<div class="innerlayout">
  <span></span>
  <span></span>
  <span class="wide"></span>
  <span></span>
  <span></span>
</div>
</div>

<div class="layout" id="narrow">
<div class="innerlayout">
  <span></span>
  <span></span>
  <span class="wide"></span>
  <span></span>
  <span></span>
</div>
</div>

Upvotes: 0

michaelT
michaelT

Reputation: 1701

Finally I think I could handle your problem, but by using flex instead of grid. It is pretty tricky.

The main element is a class called wrapper, which has display: flex;. You can insert your "grid items" there, now called wrapper-container.

I need this helper class to recreate the grid-gap property. Now I am using padding instead. Note that padding works a bit ditterent to grid-gap so I had to divide your gap by 2.

Each wrapper-container has a wrapper-container__item child, which contains your content. When you inspect these elements, you will notice, that they have at least a width of 240px which is caused by their min-width property.

When you want an element to span over two "columns" add the class wrapper-container__stretched to the wrapper-container. It is applying width: 100% so that the element will be fullsized. Elements which do not have the class, has flex: 1, so they will stay next to each other (just like a 2-column grid).

Feel free to ask when there are any ambiguities.

Codepen: Responsive grid without media queries using flex-box

.wrapper{
  position: relative;
  width: 100%;
  background: #dedede;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.wrapper-container{
  position: relative;
  padding: 12px 20px;
}

.wrapper-container:not(.wrapper-container__stretched){
  flex: 1;
}

.wrapper-container.wrapper-container__stretched{
  width: 100% !important;
}

.wrapper-container__item{
  position: relative;
  min-width: 240px;
  min-height: 64px;
  width: 100%;
}


.red{
  background: #e53935;
}

.green{
  background: #388e3c;
}
<section class="wrapper">
  <!-- Row 1 -->
  <div class="wrapper-container">
    <div class="wrapper-container__item green">Item 1</div>
  </div>
  <div class="wrapper-container">
    <div class="wrapper-container__item green">Item 2</div>
  </div>
  <!-- Row 2 -->
  <div class="wrapper-container wrapper-container__stretched">
    <div class="wrapper-container__item red">Item 3</div>
  </div>
  <!-- Row 3 -->
  <div class="wrapper-container">
    <div class="wrapper-container__item green">Item 4</div>
  </div>
  <div class="wrapper-container">
    <div class="wrapper-container__item green">Item 5</div>
  </div>
</section>

Upvotes: 0

Related Questions