Collapsible flexible-width sidebar using only CSS
How about changing the width
instead of position
on click? I use max-width
in this case, it works almost the same as unknown width. This will probably cause the content reflow on the sidebar, so use white-space:nowrap
if it's acceptable.
body {
margin: 0;
}
.container {
display: flex;
}
.sidebar {
background: #ccc;
transition: all .1s;
max-width: 1000px;
}
.sidebar.collapsed {
max-width: 0;
overflow: hidden;
}
<div class="container">
<div class="sidebar" id="sidebar">SIDEBAR</div>
<div class="content">lorem bla bla
<button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')">toggle Sidebar</button>
</div>
</div>
Another workaround is using transform
width position
together, but the animation effect will be slightly different.
body {
margin: 0;
}
.container {
display: flex;
}
.sidebar {
background: #ccc;
transition: all .1s;
}
.sidebar.collapsed {
transform: translateX(-100%);
position: absolute;
}
<div class="container">
<div class="sidebar" id="sidebar">
<div>SIDEBAR</div>
</div>
<div class="content">lorem bla bla
<button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')">toggle Sidebar</button>
</div>
</div>
Daniel
Co-Founder & Developer of Codecks. Background in AI/Computer Linguistics, mostly doing Frontend-Work with React these days.
Updated on July 05, 2022Comments
-
Daniel almost 2 years
Let's assume I have a collapsible fixed-width sidebar defined like this:
HTML
<div class="container"> <div class="sidebar" id="sidebar"> SIDEBAR </div> <div class="content"> lorem bla bla <button onclick="document.getElementsByClassName('sidebar')[0].classList.toggle('collapsed')"> toggle Sidebar </button> </div> </div>
CSS
body { margin:0; } .container { display: flex; min-height:100px; } .sidebar { position: relative; left: 0; width: 200px; background-color: #ccc; transition: all .25s; } .sidebar.collapsed { left:-200px; margin-right:-200px; }
Codepen here: http://codepen.io/anon/pen/pJRYJb
So here's the question:
How can I go from there to a flexible-width sidebar?
Here are the constraints:
- no javascript (I want the browser to deal with the layouting – not me)
- the sidebar must not overlap the content
- when collapsed, the sidebar's right border needs to be aligned with the window's left border (to be able to attach an absolutely positioned tab on the right side that's always visible)
- the width of the sidebar shouldn't change if collapsed to avoid reflows during the transition
- smooth transition without any sudden jumps
- modern CSS (flexboxes, calc) is fine
The main issue here is that I can't find a way to say
margin-right: -100%
where100%
refers to the width of sidebarAny help will be greatly appreciated!