How can I reorder my divs with CSS?

2018-12-31 06:49发布

Given a template where the HTML cannot be modified because of other requirements, how is it possible to display (rearrange) a div above another div when they are not in that order in the HTML? Both divs contain data that varies in height and width.

<div id="wrapper">
    <div id="firstDiv">
        Content to be below in this situation
    </div>
    <div id="secondDiv">
        Content to be above in this situation
    </div>
</div>
Other elements

Hopefully it is obvious that the desired result is:

Content to be above in this situation
Content to be below in this situation
Other elements

When the dimensions are fixed it easy to position them where needed, but I need some ideas for when the content is variable. For the sake of this scenario, please just consider the width to be 100% on both.

I am specifically looking for a CSS only solution (and it will probably have to be met with other solutions if that doesn't pan out).

There are other elements following this. A good suggestion was mentioned given the limited scenario I demonstrated -- given that it might be the best answer, but I am looking to also make sure elements following this aren't impacted.

标签: html css css3
23条回答
像晚风撩人
2楼-- · 2018-12-31 07:25

This can be done with CSS only!

Please check my answer to this similar question:

https://stackoverflow.com/a/25462829/1077230

I don't want to double post my answer but the short of it is that the parent needs to become a flexbox element. Eg:

(only using the webkit vendor prefix here.)

#main {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-flex-direction: column;
    flex-direction: column;
    -webkit-box-align: start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
}

Then, swap divs around by indicating their order with:

#main > div#one{
    -webkit-box-ordinal-group: 2;
    -moz-box-ordinal-group: 2;
    -ms-flex-order: 2;
    -webkit-order: 2;
    order: 2;
    overflow:visible;
}

#main > div#two{
    -webkit-box-ordinal-group: 1;
    -moz-box-ordinal-group: 1;
    -ms-flex-order: 1;
    -webkit-order: 1;
    order: 1;
}
查看更多
查无此人
3楼-- · 2018-12-31 07:25

A solution with a bigger browser support then the flexbox (works in IE≥9):

#wrapper {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}
#wrapper > * {
  -webkit-transform: scaleY(-1);
  -ms-transform: scaleY(-1);
  transform: scaleY(-1);
}
<div id="wrapper">
    <div id="firstDiv">
        Content to be below in this situation
    </div>
    <div id="secondDiv">
        Content to be above in this situation
    </div>
</div>
Other elements

In contrast to the display: table; solution this solution works when .wrapper has any amount of children.

查看更多
与风俱净
4楼-- · 2018-12-31 07:27

There is absolutely no way to achieve what you want through CSS alone while supporting pre-flexbox user agents (mostly old IE) -- unless:

  1. You know the exact rendered height of each element (if so, you can absolutely position the content). If you're dealing with dynamically generated content, you're out of luck.
  2. You know the exact number of these elements there will be. Again, if you need to do this for several chunks of content that are generated dynamically, you're out of luck, especially if there are more than three or so.

If the above are true then you can do what you want by absolutely positioning the elements --

#wrapper { position: relative; }
#firstDiv { position: absolute; height: 100px; top: 110px; }
#secondDiv { position: absolute; height: 100px; top: 0; }

Again, if you don't know the height want for at least #firstDiv, there's no way you can do what you want via CSS alone. If any of this content is dynamic, you will have to use javascript.

查看更多
伤终究还是伤i
5楼-- · 2018-12-31 07:28

Little late to the party, but you can also do this:

<div style="height: 500px; width: 500px;">

<div class="bottom" style="height: 250px; width: 500px; background: red; margin-top: 250px;"></div>

<div class="top" style="height: 250px; width: 500px; background: blue; margin-top: -500px;"></div>

查看更多
深知你不懂我心
6楼-- · 2018-12-31 07:30

Negative top margins can achieve this effect, but they would need to be customized for each page. For instance, this markup...

<div class="product">
<h2>Greatest Product Ever</h2>
<p class="desc">This paragraph appears in the source code directly after the heading and will appear in the search results.</p>
<p class="sidenote">Note: This information appears in HTML after the product description appearing below.</p>
</div>

...and this CSS...

.product { width: 400px; }
.desc { margin-top: 5em; }
.sidenote { margin-top: -7em; }

...would allow you to pull the second paragraph above the first.

Of course, you'll have to manually tweak your CSS for different description lengths so that the intro paragraph jumps up the appropriate amount, but if you have limited control over the other parts and full control over markup and CSS then this might be an option.

查看更多
登录 后发表回答