Reputation:
What should be my CSS to make a div adjust its width when scrollbar is visible.
Here is the scenario, I have a div and child elements
<div id="ListHolder">
<ul id="LeftList">
<li></li>
<li></li>
<li></li>
</ul>
<ul id="RightList">
<li></li>
<li></li>
<li></li>
</ul>
</div>
I want to adjust my div width automatically for scrollbars when it has overflow. Means when there is no scrollbar it should be like image on left side and when scrollbars becomes visible it should automatically adjust width for scrollbars. I do not want to use javascript but with pure CSS and HTML. And I believe it is possible with CSS and HTML only.
Considering above UL Lists, my CSS is something like
#ListHolder
{
display:inline-block;
}
#ListHolder > ul
{
width:250px; //<---Necessary to keep fixed width not percentage
display:inline-block;
}
#ListHolder > ul > li
{
display:inline-block;
}
#LeftList
{
float:left;
}
#RightList
{
float:right;
}
Upvotes: 17
Views: 44581
Reputation: 2614
The solution is actually pretty simple.
You need a wrapper element with display: inline-block
. Then set the width of the child element.
var count = 20;
var interval = setInterval(function(){
document.getElementById('inner').innerHTML += '<p>another line</p>';
if( --count === 0 )
clearInterval(interval);
}, 250);
/* important stuff */
#outer {
display: inline-block;
height: 150px;
overflow-y: auto;
}
#inner {
width: 300px;
}
/* styling */
p {
margin: 0;
padding: 20px;
background: white;
}
#outer {
padding: 20px;
outline: 2px solid red;
background: #ccc;
}
#inner {
outline: 2px solid red;
}
<div id="outer">
<div id="inner">
</div>
</div>
Upvotes: 2
Reputation: 23814
Instead of adjusting the width depending of the visibility of the vertical scroll bar you can always reserve the width the scroll bar needs on the right side if it is visible.
padding-right: 2em;
Upvotes: 3
Reputation: 272076
The content width of an element includes the width of scrollbar, and as far as I know, you cannot fight this behavior.
Suppose you are trying to create a shrink-wrap div that contains two 250px wide columns. The browser calculate its width as 500px, then the height, and if a scrollbar is required, it fits the scrollbar inside those 500px reducing the available width to 483px (or so).
A tricky solution is as follows:
width
property on that box or make that box shrink-wrap around its contentsmax-height
to desired value and overflow-y
property to auto
to trigger automatic scrollbarAt this point the box will be as wide as desired and the scrollbar, if visible, draws over the right padding; not interfering with the width.
In order to display the chrome (border and padding) you need to create additional divs.
HTML Markup:
<div id="ListBorder">
<div id="ListOverflow">
<div id="ListHolder">
<ul id="LeftList">
<li></li><li></li><li></li>
</ul>
<ul id="RightList">
<li></li><li></li><li></li>
</ul>
</div>
</div>
</div>
CSS (only the important bits)
#ListHolder ul {
float: left;
width: 250px;
}
#ListHolder {
width: 500px;
overflow: hidden;
}
#ListOverflow {
width: 500px;
overflow: auto;
max-height: 350px;
padding-right: 20px;
}
#ListBorder {
width: 500px;
border: 1px solid;
padding: 20px;
}
Note:
#ListHolder
is used for clear-fix#ListBorder
can be used to add a border and padding to match the desired outputUpvotes: 13
Reputation: 103760
As other people have mentioned, there is not way to adapt the width of the div based on the scrollbar condition only with CSS.
You could find a workaround like including the width of the scroll bar in your fixed width demo here. This is simple, effective, scollbar appears right of your content but it doesn't change the width of the container when the scrollbar appears.
CSS can't set a conditional width to the container based on scrollbar presence like :
So to achieve this exact behaviour you can't use CSS.
I wrote this simple JS (no library needed so it is lightweight) code that gives you the behaviour you are looking for :
var div= document.getElementById('ListHolder');
var hasVerticalScrollbar= div.scrollHeight>div.clientHeight;
if (hasVerticalScrollbar > 0) {
div.style.width = '530px' ;
}
Now, this only works on page load. If you also want this behaviour when the window is resized, you can add :
window.addEventListener( 'resize', function( event ) {
var hasVerticalScrollbar= div.scrollHeight>div.clientHeight;
if (hasVerticalScrollbar > 0) {
div.style.width = '530px' ;
}
else{
div.style.width = '500px' ;
}
}, false );
Note for unicorn lovers, I know april is nearly finished but there is a late easter egg for you in demos
Upvotes: 4
Reputation: 245
Is this what you're looking for?
Giving the images or whatever content you're putting in there a max-width of 50% (for two columns) and setting the box-sizing to border-box you should get your desired result:
#ListHolder ul {
margin: 0;
padding: 10px;
list-style: none;
float: left;
max-width: 50%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Upvotes: 1
Reputation: 5411
Maybe you could change the scrollbar. Something like this:
::-webkit-scrollbar {
width: 2em;
height: 2em
}
::-webkit-scrollbar-button {
background: #ccc
}
::-webkit-scrollbar-track-piece {
background: #888
}
::-webkit-scrollbar-thumb {
background: #eee
}
Also, you can find the IE css here
Upvotes: -1
Reputation: 4931
Just check the demo & inspect element and remove height from "#ListHolder" div you will see the width will adapt the change of scroll-bar presence.
If this is what you are looking for let me know and i will explain the logic behind it.
HTML:
<div class="overall-width">
<div id="ListHolder">
<ul id="LeftList">
<li>
<img src="http://placehold.it/200x200" />
</li>
<li>
<img src="http://placehold.it/200x200" />
</li>
<li>
<img src="http://placehold.it/200x200" />
</li>
</ul>
<ul id="RightList">
<li>
<img src="http://placehold.it/200x200" />
</li>
<li>
<img src="http://placehold.it/200x200" />
</li>
<li>
<img src="http://placehold.it/200x200" />
</li>
</ul>
</div>
</div>
CSS:
html {
overflow: -moz-scrollbars-vertical;
/* For FF */
-ms-overflow-y: scroll;
/* For IE */
overflow-y: scroll;
/* For others & old IE */
}
#ListHolder {
display:inline-block;
height: 610px;
overflow: auto;
width: 100%;
padding: 10px;
}
#ListHolder > ul {
-moz-box-sizing: border-box;
-webki-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #CFCFCF;
border-radius: 3px;
display: inline-block;
margin: 0;
padding: 20px;
text-align: center;
width: 250px;
}
#ListHolder > ul > li {
display:inline-block;
}
#LeftList {
float:left;
}
#RightList {
float:right;
}
body{
height: 100%;
margin: 0px;
}
.overall-width{
width: 600px;
}
Upvotes: 0
Reputation: 488
Even if you could adjust your DIVs width to the presence of a scrollbar, I wouldn't recommend it. Consider that a user could have customized the size (width) of their scrollbars within their OS (Windows comes to mind).
Next, comes the fact that some browsers report the viewport's width with the scrollbar, while others report it without. Specifically, Chrome and Safari exclude the scrollbar dimensions, while Firefox, Opera and IE include the scrollbar dimensions.
I conclusion, I concur with the other answers that you should use overflow: scroll
. Either that, or use javascript to use a custom scrollbar (which I think is overkill).
Reading material:
Upvotes: 0
Reputation: 10698
You won't be able to increase the container's div when it overflows by pure CSS.
However, if you want to keep your actual layout (the flexbox model would be a better fit here, as @AlecMoore suggested), here's a workaround for webkit only : use the overlay
value for overflow
. It'll appear above your content, so it'll not slide down.
div{
width: ...px; /* Fixed width */
overflow-y: overlay; /* Overlaying scrollbar for y axis */
}
Or, you could just adapt your div, make it slightly wider, so the scrollbar will fit in when needed (demonstration).
Again, this is not the best solution ; if you aim to make something responsive, you should be using relative sizing units, and / or flex-box model.
Note to unicorn lovers: I do love kittens, but I prefer unicorns. I'm using kittens, cause I miss an image placeholder website with cute unicorns... Please tell if you know one!
Upvotes: 4
Reputation: 2193
I think your best shot would be to always display the scroll bar even when there is no overflow (the scroll bar would be deactivated and will get activated when the content of the page gets longer than the viewport).
You can achieve this using this code:
html {
overflow: -moz-scrollbars-vertical; /* For FF */
-ms-overflow-y: scroll; /* For IE */
overflow-y: scroll; /* For others & old IE */
}
And here is a working FIDDLE
Alternatively, if you are OK with setting a fixed width to your container div, you can ignore the width of the scroll bar by setting the overflow-y value to overlay which will make the content get behind the scroll bar on smaller viewports.
Please Note: that overflow:overlay;
is deprecated.
Here you go:
html {
overflow-y: overlay;
}
#ListHolder {
display:inline-block;
width:600px; /* Fixed width */
}
And here is another FIDDLE
Note that both approaches work correctly on modern AND older browsers such as the great IE8.
Hope this helps.
Upvotes: 0
Reputation: 674
I think you should make the div width taking in consideration the scrollbar width. Add a few pixels (30px) maybe to the div width. Then set the RighList and LeftList width to something like 49% each.
overflow-y:auto is causing your list to move because you are not taking the scrollbar width into consideration.
Hope this helps!
Upvotes: 0
Reputation: 1175
What it sounds like you want is overflow:auto;
which will only show the scroll bar when the content needs to scroll. Otherwise it will hide the scroll bar.
So your div could look like this:
<div class="scroll">
<ul>
<li></li>
<li></li>
<li></li>
</ul>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
and your css:
.scroll {
overflow-y:auto; /* Only scroll the y axis */
}
Upvotes: -1