dwigt
dwigt

Reputation: 611

Moving one HTML element before another while maintaining document flow

I am trying to create tab module such as this:

https://codepen.io/oknoblich/pen/tfjFl

However I am having difficulty since I can not change the HTML layout:

<div class="container">
    <div class="tab-header">Tab1</div>
    <div class="tab-content teal">Content1</div>
</div>
<div class="container current">
    <div class="tab-header">Tab2</div>
    <div class="tab-content teal">Content2</div>
</div>

The problems are that absolute positioning removes the content from the document flow, while other methods prevents the content from being the full width of the page.

I created two codepen's that illustrates the difficulties:

https://codepen.io/dwigt/pen/pOQpLd (absolute positioning removes content from document flow)

https://codepen.io/dwigt/pen/YOREOJ (flexbox layout does not take up full page-width)

Is there anyway I can replicate the tab functionality using this HTML layout and no javascript?

Upvotes: 0

Views: 72

Answers (2)

Piotr Wicijowski
Piotr Wicijowski

Reputation: 2115

You can use display: contents (which is unfortunately not too well supported) combined with flexbox layout with wrap, set on the .wrapper element. This way, tab-headers and tab-contents will be treated equally, as if they were at the same level with one another - the .container elements are "transparent" to the layout engine. As a result, they will all be laid out with flexbox logic applied. Finally, to have the three tab headers display first, we set the order of the tab contents to some high value (here 100), and since we have flex wrap enabled, the content is then pushed downwards to a new line, below the headers. See example below:

.wrapper {
  max-width: 300px;
  display: flex;
  flex-wrap: wrap;
  height: 100%;
}

.container {
  height: 50px;
  display: contents;
}
.container .tab-header {
  width: 100px;
  max-width: 100%;
  max-height: 100%;
  flex: 1 0 33.33%;
}
.container .tab-content {
  display: none;
  height: 200px;
  order: 100;
}
.container.current .tab-content {
  display: block;
  width: 300px;
  left: 0;
}

.footer {
  height: 500px;
  width: 300px;
  display: block;
}

.red {
  background: red;
}

.teal {
  background: teal;
}
<div class="wrapper">
    <div class="container">
        <div class="tab-header">Tab1</div>
        <div class="tab-content teal">Content1</div>
    </div>
    <div class="container current">
        <div class="tab-header">Tab2</div>
        <div class="tab-content teal">Content2</div>
    </div>
    <div class="container">
        <div class="tab-header">Tab3</div>
        <div class="tab-content teal">Content3</div>
    </div>
</div>
<div class="footer red">Footer Text</div>  

Upvotes: 2

Birdie Golden
Birdie Golden

Reputation: 571

This isn't quite perfect because the first tab is a bit wider, but give this a shot and see if this doesn't get your closer to your goal. It allows your tabs to be 100% and also allows you to add more tabs that space evenly from edge to edge of your container.

Let me know how it works out :D

Add display: table-cell and width: 100% to your css selector label

label {
  display: table-cell;
  width: 100%;
  margin: 0 0 -1px;
  padding: 15px 25px;
  font-weight: 600;
  text-align: center;
  color: #bbb;
  border: 1px solid transparent;
}

Upvotes: 2

Related Questions