4

I have a row with 2 columns. Within these columns I have a headline, content and a list. They have a different content length.

What I want to achieve is, that the list stays next to each other on the same line without breaking the bootstrap mobile optimization.

I first tried it with 3 different rows, but when the columns break, the content doesn't belong to each other anymore. Is there a solution for what I need without JavaScript? Maybe with flexbox somehow?

Here is my current code:

<div class="light-grey-section ruler">
   <div class="container">
      <div class="row">
         <div class="light-section col-xs-12 col-md-6">
            <div class="panel panel-default panel-blank">
               <div class="panel-body">
                  <div class="content"> // contentlength is different in each column
                     <h2>
                        Lorem ipsum Lorem ipsum
                     </h2>
                     <p>
                        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren
                     </p>
                     <p>
                        Lorem ipsum dolor
                     </p>
                     <ul class="check"> // I want this list to stay in the same line with the other ul.check in the other column
                        <li>Lorem ipsum dolor sit amet,</li>
                        <li>Lorem ipsum dolor sit amet,</li>
                        <li>Lorem ipsum dolor sit amet,</li>
                        <li>Lorem ipsum dolor sit amet,</li>
                        <li>Lorem ipsum dolor sit amet,</li>
                     </ul>
                  </div>
               </div>
            </div>
         </div>
         <div class="dark-section col-xs-12 col-md-6">
            <div class="panel panel-default panel-blank">
               <div class="panel-body">
                  <h2>
                     Lorem ipsum
                  </h2>
                  <p>
                     Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                  </p>
                  <ul class="check">
                     <li>Lorem ipsum dolor sit amet,</li>
                     <li>
                        Lorem ipsum dolor sit amet,
                     </li>
                     <li>Lorem ipsum dolor sit amet,</li>
                     <li>Lorem ipsum dolor sit amet,</li>
                  </ul>
               </div>
            </div>
         </div>
      </div>
   </div>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • Please post the css which you have. – Hema Nandagopal Sep 25 '17 at 06:01
  • display:table springs to mind... – Mr Lister Sep 25 '17 at 06:04
  • 3 ways to solve that, either script, fixed height on each item or markup change where Flexbox can be used – Asons Sep 25 '17 at 06:05
  • The css shouldn't really matter. I'm using Bootstrap 3. All the other CSS has only some styling stuff for the list and columns which isn't really necessary. Take a look here: https://codepen.io/Insane415/pen/dVOQLZ –  Sep 25 '17 at 06:05
  • @LGSon Flexbox sounds good. But how do I have to change the markup without breaking the mobile optimization? –  Sep 25 '17 at 06:07
  • So you want the 2 `ul` to always be aligned vertically? – Asons Sep 25 '17 at 06:53
  • @LGSon well, I want them always to be in one line. But I don't know how to achieve this because they are in two different columns. –  Sep 25 '17 at 09:15
  • @LGSon Gonna try that in a few hours, I will let you know! –  Sep 27 '17 at 11:13

1 Answers1

6

To be able to accomplish that without using script, all the items (h2,p,p,ul) needs to see each other, which technically mean they need to be siblings.

And then, for wider screens where they sit side-by-side, they need to be reordered, where the h2 comes first (order: 0) and so on.

I used one media query, but you might want to add more, to match more of Boostrap's break points.

To add i.e. an outer border, you need to use a combination of border-top/border-left/border-right/border-bottom on the elements, which also need to be altered with the query's, to cover both horizontally and vertically stacked items.

Updated codepen

@media (min-width: 768px) {
  
  .content {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
  }

  .content > * {
    flex-basis: calc(50% - 30px);
  }

  .content h2 {                     /*  1st row  */
    order: 0;
  }
  .content p {                      /*  2nd row  */
    order: 1;
  }
  .content p + p {                  /*  3rd row  */
    order: 2;
    flex-basis: calc(100% - 30px);  /* as only 1 `p` in markup, it need 100% width,
                                       or add an extra empty in the markup  */
  }
  .content ul {                     /*  4th row  */
    order: 3;
  }
  
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<div class="light-grey-section ruler">
  <div class="container">
    <div class="row">
      <div class="light-section col-xs-12">
        
        <div class="content">
          <h2>Lorem ipsum Lorem ipsum</h2>
          <p>
            Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren
          </p>
          <p>
            Lorem ipsum dolor
          </p>
          <ul class="check">
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
          </ul>
          <h2>Lorem ipsum</h2>
          <p>
            Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
            sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
          </p>
          <ul class="check">
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
            <li>Lorem ipsum dolor sit amet,</li>
          </ul>
        </div>
        
      </div>
    </div>
  </div>
</div>

Updated, based on a comment at a duplicate question

If one have many items, one can group them, i.e. 4 per group, to make the CSS much smaller.

Codepen sample

.container {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}

.container .row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container .row>* {
  flex-basis: calc(100% - 30px);
  min-width: 0;
}

.container .row>div {
  border: 2px solid gray;
}

.container .row>div:nth-child(8n+1),
.container .row>div:nth-child(8n+2),
.container .row>div:nth-child(8n+3),
.container .row>div:nth-child(8n+4) {
  background: lightgray;
}

.container .row>div:nth-child(4n+1) {
  border-width: 2px 2px 0 2px;
  margin-top: 10px;
}

.container .row>div:nth-child(4n+2) {
  border-width: 0 2px;
}

.container .row>div:nth-child(4n+2)+div {
  border-width: 0 2px;
}

.container .row>div:nth-child(4n+4) {
  border-width: 0 2px 2px 2px;
}

@media (min-width: 600px) {
  .container .row>* {
    flex-basis: calc(50% - 30px);
  }
  .container .row>div:nth-child(4n+1) {
    order: 0;
  }
  .container .row>div:nth-child(4n+2) {
    order: 1;
  }
  .container .row>div:nth-child(4n+2)+div {
    order: 2;
  }
  .container .row>div:nth-child(4n+4) {
    order: 3;
  }
  .container .row>div:nth-child(4n+9) {
    order: 4;
  }
  .container .row>div:nth-child(4n+10) {
    order: 5;
  }
  .container .row>div:nth-child(4n+10)+div {
    order: 6;
  }
  .container .row>div:nth-child(4n+12) {
    order: 7;
  }
}
<div class="container">
  <div class="row">  
      <div><h2>Title 1</h2></div>
      <div><p>Test text 1</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>

      <div><h2>Title 2</h2></div>
      <div><p>Test text 1 is a bit longer to force it to wrap</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>

      <div><h2>Title 3 is a bit longer to make it wrap</h2></div>
      <div><p>Test text 1 is a bit longer to force it to wrap</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>
        
      <div><h2>Title 4</h2></div>
      <div><p>Test text 1</p></div>
      <div><p>Test text 2 is a bit longer to force it to wrap</p></div>
      <div><button>Button</button></div>
  </div>
  
  <div class="row">  
      <div><h2>Title 5</h2></div>
      <div><p>Test text 1</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>

      <div><h2>Title 6</h2></div>
      <div><p>Test text 1 is a bit longer to force it to wrap</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>

      <div><h2>Title 7 is a bit longer to make it wrap</h2></div>
      <div><p>Test text 1 is a bit longer to force it to wrap</p></div>
      <div><p>Test text 2</p></div>
      <div><button>Button</button></div>
        
      <div><h2>Title 8</h2></div>
      <div><p>Test text 1</p></div>
      <div><p>Test text 2 is a bit longer to force it to wrap</p></div>
      <div><button>Button</button></div>
  </div>  
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • hehe oh it's actually you. Tbh I don't really understand what you are doing and why this works. But is it really necessary that they are close siblings? you can obviously use something like `.sibling1 + .sibling2 .sibling2child` in the css. Especially I don't really understand the flex-basis trick – Toskan Oct 12 '17 at 15:23
  • @Toskan Yes, it was me :) ... If we take your question's code, where the `header` is a child of `item` and `item` is a child of `col-12 col-md-4 col-lg-3`, for `header`'s on the same row to have the same height, they need to see each other (be siblings), like the `col-12 col-md-4 col-lg-3` do, or else they can't stretch equally. And when using Flexbox, flex items on the same row get equal height by default. So in your case, the `header` and `content` as a group can though, if one would apply Flexbox properties to `col-12 col-md-4 col-lg-3` and `item` – Asons Oct 12 '17 at 15:32
  • 1
    @Toskan Here is your code sample where I dropped Bootstrap and used Flexbox: https://codepen.io/anon/pen/gGjzMR .... and here it is when `header`/`content` are siblings: https://codepen.io/anon/pen/yzqjaQ .... and for the last sample I used `order` to make the `header` render first, but with a markup change, you can skip that: https://codepen.io/anon/pen/MEBGrd – Asons Oct 12 '17 at 15:52
  • `header`/`content` siblings behaves odd when new data is added: https://codepen.io/anon/pen/jGRjwz but for me this is not so important any more. I think the cleanest solution is your jquery solution provided here: https://stackoverflow.com/a/46600682/533426 – Toskan Oct 23 '17 at 05:33
  • @Toskan Yes, using CSS alone is complicated as one can't just drop in an arbitrary amount of items, nor can they be wrapped...the jQuery will overcome that :) – Asons Oct 23 '17 at 06:00
  • 2
    I LOVE that we can do this with CSS but semantically I really don't like it :( it really is a creative way of achieving it without JS though :) – Mike Young May 14 '18 at 10:15