Swapping columns (left / right) on alternate rows

2019-02-24 16:04发布

I have a series of rows, each containing two columns, split 50/50 in width.

I'd like every other row to swap the left column (.image) to the right right, but I need to maintain the sequence in the HTML as it's displayed as one column on smaller screens.

CSS:

ul {
  list-style: none;
  padding-left: 0;
}

.row {
  text-align: center;
}

@media (min-width: 768px) {

  .image,
  .text {
      display: inline-block;
      width: 50%;
      vertical-align: middle;
  }

  /* alternate */
  .row:nth-child(odd) .image {
    float: right;
  }

  /* clearfix */
  .row:before,
  .row:after {
      content: " ";
      display: table;
  }

  .row:after {
      clear: both;
  }

}

HTML:

<ul>
  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div><div class="text">
      <p>Lorem ipsum</p>
  </div>
  </li>
  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div><div class="text">
      <p>Lorem ipsum</p>
    </div>
  </li>
  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div><div class="text">
      <p>Lorem ipsum</p>
    </div>
  </li>
</ul>

I know I can do this with flexbox, which I can't use in this project. And using float: left doesn't allow me to vertically align the elements. What other options do I have?

NB: I'm using display: inline-block for these columns, as they vary in height and I'd like them to be aligned vertically to one another.

Edit: I've made a CodePen with the example using floats as shown above.

3条回答
男人必须洒脱
2楼-- · 2019-02-24 16:40

you may use display:table(optionnal), :nth-child(even) and direction to swap div position : codepen

ul {
  margin: 0;
  padding: 0;
  width: 100%;
}
.row {
  width: 100%;
  display: table;
  table-layout: fixed;
}
.row:nth-child(even) {
  direction: rtl;
}
.row:nth-child(odd) .image {
  text-align: right
}
.image,
.text {
  display: table-cell;
  direction: ltr;
  border: solid;
}
.text {
  background: tomato;
}
img {vertical-align:top;}
@media screen and (max-width: 640px) {
  .row,
  .image,
  .text {
    display: block;
    direction:ltr
  }
  .row:nth-child(odd) .text {
  text-align: right
}
}
<ul>
  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div>
    <div class="text">
      <p>Lorem ipsum</p>
    </div>
  </li>

  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div>
    <div class="text">
      <p>Lorem ipsum</p>
    </div>
  </li>
  <li class="row">
    <div class="image">
      <img src="http://placehold.it/350x150">
    </div>
    <div class="text">
      <p>Lorem ipsum</p>
    </div>
  </li>
</ul>

查看更多
Animai°情兽
3楼-- · 2019-02-24 16:40

Try this:

/* CSS */

.row .image {
   display: table-cell
}
.row .text {
   display: table-cell;
   vertical-align: top;
}
.row:nth-child(even) .image {
   float: right;
}
.row {
   clear: both;
}

Here is a working plunker

查看更多
时光不老,我们不散
4楼-- · 2019-02-24 16:47

I don't really understand what you mean by "aligned vertically to one another". How exactly aligned?

But maybe you want to align them vertically using vertical-align: middle and then, yes, float: left is not your friend.

You say that your columns split 50/50 in width. Then you can use position: relative with left: 50%; and right: 50%; rules.

Like this:

.row {
  display: block;
  position: relative;
}

.row > .image {
  display: inline-block;
  position: relative;
  width: 50%;
  background-color: #eef;
  vertical-align: middle;
}
.row > .text {
  display: inline-block;
  position: relative;
  width: 50%;
  background-color: #fee;
  vertical-align: middle;
}

.row:nth-child(even) > .image {
  left: 50%;
}
.row:nth-child(even) > .text {
  right: 50%;
}

The background color is just for demonstration.

This way each even row will swap columns and you can still use vertical-align rule. See the plunker.

查看更多
登录 后发表回答