简体   繁体   中英

Tab box sized by biggest panel content in pure CSS

Using floats, flexbox or a table, there are different methods to size two adjacent blocks to the same height or to the same width, dependent on their contents without using JavaScript.

I wonder if there is a way to achieve the same for panels of a tab box, of which only one is visible at a time.

So if for example a panel is empty, its size (or at least its background) should be extended to the size of the biggest panel in the stack of panels.

My intention is to prevent elements below or beside the tab box to jump to different positions when the tab is switched, but I don't want to assume anything about the dimensions of the panel contents since they are dynamic.

On a conceptual level, and on how I understood your question, you will need a row structure, like a table or a flexbox, where siblings on the same row sizes equal.

Since each panel's content should behave as if it were alone, it need to have the width of its container, or else the content will start wrap and effect its siblings height.

So to allow a normal flow I added a wrapper and nn times amount of children as width and then used transform: translate to pull them on top of each other, so one can animate between them without anything moves.

Here is a sample code using flexbox , which I also recommend to use.


Updated based on a comment.

One can of course predefine this in the same way one does when making ie a grid, where you setup a max amount of tabs you need and then it will work with up to that amount, here defined for 12 but only using 7

And this works today, no need to wait for Chrome :)

 (function (count) { var button = document.querySelector('button'); var children = document.querySelectorAll('.wrapper div'); button.addEventListener('click', function() { children[count].classList.toggle('show'); count++; if (count == children.length) count = 0; children[count].classList.toggle('show'); }) })(0); 
 html, body { margin: 0; } .container { overflow: hidden; } .wrapper { display: flex; background: lightgray; width: 1200%; } .wrapper div { position: relative; width: calc(100% / 12); background: lightblue; padding: 10px; transition: opacity 1s, transform 1s; opacity: 0; } .wrapper div.show { opacity: 1; } .wrapper div:nth-child(2) { transform: translate(-100%); } .wrapper div:nth-child(3) { transform: translate(-200%); } .wrapper div:nth-child(4) { transform: translate(-300%); } .wrapper div:nth-child(5) { transform: translate(-400%); } .wrapper div:nth-child(6) { transform: translate(-500%); } .wrapper div:nth-child(7) { transform: translate(-600%); } .wrapper div:nth-child(8) { transform: translate(-700%); } .wrapper div:nth-child(9) { transform: translate(-800%); } .wrapper div:nth-child(10) { transform: translate(-900%); } .wrapper div:nth-child(11) { transform: translate(-1000%); } .wrapper div:nth-child(12) { transform: translate(-1100%); } /* styling stuff */ button { padding: 5px 10px; margin-bottom: 10px; } 
 <button>Toggle</button> <div class="container"> <div class="wrapper"> <div class="show"> 1. Some text </div> <div> 2. Some more text<br> Some more text<br> </div> <div> 3. Some even more text<br> Some even more text<br> Some even more text<br> Some even more text<br> Some even more text<br> </div> <div> 4. Some more text<br> Some more text<br> </div> <div> 5. Some text </div> <div> 6. Some more text<br> Some more text<br> </div> <div> 7. Some even more text<br> Some even more text<br> Some even more text<br> Some even more text<br> Some even more text<br> </div> </div> The height is kept so text like this does not move </div> 

Using flexbox and visibility: collapse (see W3C draft ), contents can be hidden while the occupied space is still taken into account.

The following example is working on IE and Firefox, not (yet) in Safari, Opera and Chrome [in progress] .

 var count = 0; var children = document.querySelectorAll('.container div'); document.querySelector('button') .addEventListener('click', function () { children[count++ % 4].classList.toggle('show'); children[count % 4].classList.toggle('show'); }); 
 .container { display: flex; overflow: hidden; } .container div { visibility: collapse; } .container div.show { visibility: visible; } 
 <button>toggle</button> <div class="container"> <div class="show"> 1. Some text </div> <div> 2. Some more text<br/> Some more text </div> <div> 3. Some even more text<br/> Some even more text<br/> Some even more text<br/> Some even more text<br/> Some even more text </div> <div> 4. Some more text<br/> Some more text </div> </div> <p>Text below, does not move on toggle.</p> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM