Home > database >  3 column layout or 2 column layout if sidebar is present
3 column layout or 2 column layout if sidebar is present

Time:09-17

We have a dynamic number of radio buttons that we would like to display in 3 columns. However, if there is a sidebar present (e.g. a div on the side with some text), then we want to layout the radio buttons in 2 columns and the sidebar would take up the space where the 3rd column would go. Example images are below. Is this possible using only CSS?

Things we have tried

We have implemented a solution using React by dynamically changing the class name depending on the number of columns to use, i.e. this was not a CSS solution but a React solution. This works, however there may be layout changes in the future where a CSS only solution would be more flexible.

Some things to note

  • This is not a responsive design question - the layout should change depending on the presence of the sidebar, not the size of the screen.
  • Ideally this would be a pure-css solution.
  • We are using Boostrap if that helps.

3 Column Layout example

3 columns

2 Column Layout with sidebar example

2 columns with sidebar

Edit:

Some code we have tried so far. We are using React to add the class names 'col2' or 'col3' depending on the layout we want:

.item {
  background: #ececec;
  margin: 2rem;
  padding: 20px;
}

.sidebar {
  background: #f32a9b;
  padding: 20px;
}

.col3 .col {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.col2 {
  display: grid;
  grid-template-columns: 2fr 1fr;
}

.col2 .col {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
<h2>3 cols</h2>
<div class="container col3">
  <div class="row">
    <div class="col">
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
    </div>
    <button type="submit">Submit</button>
  </div>
</div>

<h2>2 cols with sidebar</h2>
<div class="container col2">
  <div class="row">
    <div class="col">
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
    </div>
    <button type="submit">Submit</button>
  </div>
  <div class="col sidebar">
    sidebar text. sidebar text. sidebar text. sidebar text. sidebar text.
  </div>
</div>

CodePudding user response:

You can fix this issue with grid easily.


With sidebar

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.grid-item {
  margin: 0.5rem;
  padding: 2rem;
  background-color: #e91e63;
}

.side-bar {
  background: blue;
  grid-column: 3 / -1;
  grid-row: 1 / span 100;
}
<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item side-bar"></div>
</div>

Without sidebar

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.grid-item {
  margin: 0.5rem;
  padding: 2rem;
  background-color: #e91e63;
}

.side-bar {
  background: blue;
  grid-column: 3 / -1;
  grid-row: 1 / span 100;
}
<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <!--<div class="grid-item side-bar"></div> -->
</div>

CodePudding user response:

You may try play through the selectors :not(), :nth-last-child(n) , calc() (to reset paddings) & background-clip (could also be margin alone instead) and grid-template-columns:1fr auto; for the main container to shrink to zero the second (auto) column if empty (no sidebar to put in it).

All together, it could be something alike:

.item {
  background: #ececec;
  margin: 2rem;
  padding: 20px;
}

.sidebar {
  background: linear-gradient( #f32a9b, #f32a9b) no-repeat;
  background-clip: content-box;
  padding: 30px 20px calc(20px   2.2em);
  margin-right: 30px;
  max-width: calc(calc(33vw - 40px) - 30px);
}

.col .row .col:not(.sidebar) {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.col .row:nth-last-child(2) .col:not(.sidebar) {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.container.col {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px;
}
<!-- untouched HTML of yours aside the input which is a self closing tag -->
<h2>3 cols</h2>
<div class="container col">
  <div class="row">
    <div class="col">
      <div class="item"><input type="radio" name="radio">radio
      </div>
      <div class="item"><input type="radio" name="radio">radio
      </div>
      <div class="item"><input type="radio" name="radio">radio
      </div>
      <div class="item"><input type="radio" name="radio">radio
      </div>
      <div class="item"><input type="radio" name="radio">radio
      </div>
      <div class="item"><input type="radio" name="radio">radio
      </div>
    </div>
    <button type="submit">Submit</button>
  </div>
</div>

<h2>2 cols with sidebar</h2>
<div class="container col">
  <div class="row">
    <div class="col">
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
      <div class="item"><input type="radio" name="radio">radio</input>
      </div>
    </div>
    <button type="submit">Submit</button>
  </div>
  <div class="col sidebar">
    sidebar text. sidebar text. sidebar text. sidebar text. sidebar text.
  </div>
</div>

  • Related