Element width 100% of PAGE (not browser window) - css

Edit: For the sake of simplicity, I reduced my problem with overlay (see Background below) to width of a div. By doing that I however created a different and somewhat artificial problem. The accepted answer solves my real problem. The "reduced" problem is not solved there.
How can I make div with width equal to 100% of the page width? (without setting fixed min-width)
Seemingly, the solution is trivial. <div> with its 100% width should be OK by itself. That works fine unless you shrink the browser window below the page width (that's when scroll bars appear). Then the width of the <div> element is equal to the window size, not to the page size.
A note on the demonstration code: The first div simulates the page width. The divs below are my attempts to achieve an element wide across all page. If the page is big enough (more than 500px), they are rendered as expected - all over the page. But if you shrink the window (below 500px) and scroll bar appears, then the divs also shrink, although I want them to stay at 500px.
Here's the code, or check it out on jsFiddle if you prefer
/* just to see sizes of the elements */
div {
border: 1px solid red;
}
/* this simulates the width of the actual page content */
div#fixed {
width: 500px;
}
div#full1 {
width: 100%;
}
div#full2 {
width: 100%;
min-width: 100%;
}
div#full3 {
position: relative;
display: inline-block;
width: 100%;
}
/* this works fine, but uses fixed size min-width, I cannot use */
div#fullOK {
width: 100%;
min-width: 500px;
}
<div id="fixed">Width fixed to 500px</div>
The DIVs below are attempts to achieving 100% width despite scrolling. All work only if the window is wider than 500px.
<div>default</div>
<div id="full1">just width 100%</div>
<div id="full2">width and min-width 100%</div>
<div id="full3">run out of ideas</div>
<br>
<br>
<div id="fullOK">fixed min-width is the only thing that works (unusable for me though)</div>
Background: I have a page, which has an editor area that can be resized by the user. It has a modal dialog windows support, which - when invoked - shows a window and covers the rest of the page by a semi-opaque background with height and width set to 100%. It works well, unless it is viewed in window smaller than the page. Then scrolling shows part of the page not covered by the background, which looks ugly. I need to have this background spanning all over the page, not just over the visible area. Setting min-width and min-height could be done only with the help of JavaScript (due to unknown page size, as the user can resize the canvas) and I'd prefer avoiding that.

Use position: fixed for the overlay. The scrolling doesn't matter as elements that are fixed will position themselves in relation to the viewport. height: 100% and width: 100% will keep the overlay over the entire page no matter what you do.
From the MDN (emphasis mine):
fixed
Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and don't move it when scrolled. [...]
CSS / HTML / Demo
* {
margin: 0;
padding: 0;
font-size: 1.5em;
}
body {
background: white;
}
.cover {
position: fixed;
height: 100%;
width: 100%;
background: rgba(255, 0, 0, 0.7);
}
<div class="cover"></div>
<h1>I am overlapped!</h1>
<input type="text" value="cant touch this" />

Related

How can I prevent the page shifting when scrollbar is disabled [duplicate]

I have a website with center-aligned DIV. Now, some pages need scrolling, some don't. When I move from one type to another, the appearance of a scrollbar moves the page a few pixels to the side. Is there any way to avoid this without explicitly showing the scrollbars on each page?
overflow-y:scroll is correct, but you should use it with the html tag, not body or else you get a double scrollbar in IE 7
So the correct css would be:
html {
overflow-y: scroll;
}
Wrap the content of your scrollable element into a div and apply padding-left: calc(100vw - 100%);.
<body>
<div style="padding-left: calc(100vw - 100%);">
Some Content that is higher than the user's screen
</div>
</body>
The trick is that 100vw represents 100% of the viewport including the scrollbar. If you subtract 100%, which is the available space without the scrollbar, you end up with the width of the scrollbar or 0 if it is not present. Creating a padding of that width on the left will simulate a second scrollbar, shifting centered content back to the right.
Please note that this will only work if the scrollable element uses the page's entire width, but this should be no problem most of the time because there are only few other cases where you have centered scrollable content.
html {
overflow-x: hidden;
margin-right: calc(-1 * (100vw - 100%));
}
Example. Click "change min-height" button.
With calc(100vw - 100%) we can calculate the width of the scrollbar (and if it is not displayed, it will be 0). Idea: using negative margin-right, we can increase the width of <html> to this width. You will see a horizontal scroll bar — it should be hidden using overflow-x: hidden.
I think not. But styling body with overflow: scroll should do. You seem to know that, though.
With scroll always being shown, maybe be not good for layout.
Try to limit body width with css3
body {
width: calc(100vw - 34px);
}
vw is the width of the viewport (see this link for some explanation)
calc calculate in css3
34px stands for double scrollbar width (see this for fixed or this to calculate if you don't trust fixed sizes)
If changing size or after loading some data it is adding the scroll bar then you can try following, create class and apply this class.
.auto-scroll {
overflow-y: overlay;
overflow-x: overlay;
}
I don't know if this is an old post, but i had the same problem and if you want to scroll vertically only you should try overflow-y:scroll
body {
scrollbar-gutter: stable both-edges;
}
New css spec that will help with scrollbar repositioning is on its way:
https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-gutter
Summary
I see three ways - each with their own quirks:
scrollbar-gutter as mentioned by Markus T.
overflow: overlay as mentioned by kunalkamble
Add spacing with calc(100vw - 100%) as mentioned Rapti
Here is a StackBlitz demo
Press the "Toggle height" to see the content shift.
scrollbar-gutter
This has limited support but with a #support media query we can use a combination of this and overflow-y: scroll:
html {
overflow-y: scroll;
}
#supports (scrollbar-gutter: stable) {
html {
overflow-y: auto;
scrollbar-gutter: stable;
}
}
In this way content will never shift.
The "problem" with this solution is that there is always a fixed space for the scrollbar.
overflow: overlay
Limited support and it obviously hides anything it overlays. Special care is needed to make sure nothing vital is hidden (also on zoom and text size changes).
Can be combined with scrollbar-gutter:
html {
overflow-y: scroll;
}
#supports (scrollbar-gutter: stable) {
html {
overflow-y: auto;
scrollbar-gutter: stable;
}
}
#supports (overflow-y: overlay) {
html {
overflow-y: overlay;
scrollbar-gutter: auto;
}
}
It is possible to do some negative margin and overflow-x: hidden but this has a risk of hiding vital content under certain situations. Small screen, custom font/zoom size, browser extensions, etc.
calc(100vw - 100%)
This can be done with RTL support like this:
html[dir='ltr'] main {
padding-left: calc(100vw - 100%);
}
html[dir='rtl'] main {
padding-right: calc(100vw - 100%);
}
Where <main> in this case would be the container for the centered content.
Content here will not shift as long as the centered container is smaller than <main>. But as soon as it is 100% of the container a padding will be introduced. See the StackBlitz demo and click "Toggle width".
The "problem" with this solution is that you need media queries to prevent padding on "small screens" and that even on small screens - when the scrollbar should be visible - some shifting will occur because there is no room for 100% content and a scrollbar.
Conclusion
Use scrollbar-gutter perhaps combined with overlay. If you absolutely don't want empty spacing, try the calc solution with media queries.
Simply setting the width of your container element like this will do the trick
width: 100vw;
This will make that element ignore the scrollbar and it works with background color or images.
#kashesandr's solution worked for me but to hide horizontal scrollbar I added one more style for body. here is complete solution:
CSS
<style>
/* prevent layout shifting and hide horizontal scroll */
html {
width: 100vw;
}
body {
overflow-x: hidden;
}
</style>
JS
$(function(){
/**
* For multiple modals.
* Enables scrolling of 1st modal when 2nd modal is closed.
*/
$('.modal').on('hidden.bs.modal', function (event) {
if ($('.modal:visible').length) {
$('body').addClass('modal-open');
}
});
});
JS Only Solution (when 2nd modal opened from 1st modal):
/**
* For multiple modals.
* Enables scrolling of 1st modal when 2nd modal is closed.
*/
$('.modal').on('hidden.bs.modal', function (event) {
if ($('.modal:visible').length) {
$('body').addClass('modal-open');
$('body').css('padding-right', 17);
}
});
I've solved the issue on one of my websites by explicitly setting the width of the body in javascript by the viewport size minus the width of the scrollbar. I use a jQuery based function documented here to determine the width of the scrollbar.
<body id="bodyid>
var bodyid = document.getElementById('bodyid');
bodyid.style.width = window.innerWidth - scrollbarWidth() + "px";
Extending off of Rapti's answer, this should work just as well, but it adds more margin to the right side of the body and hides it with negative html margin, instead of adding extra padding that could potentially affect the page's layout. This way, nothing is changed on the actual page (in most cases), and the code is still functional.
html {
margin-right: calc(100% - 100vw);
}
body {
margin-right: calc(100vw - 100%);
}
Expanding on the answer using this:
body {
width: calc(100vw - 17px);
}
One commentor suggested adding left-padding as well to maintain the centering:
body {
padding-left: 17px;
width: calc(100vw - 17px);
}
But then things don't look correct if your content is wider than the viewport. To fix that, you can use media queries, like this:
#media screen and (min-width: 1058px) {
body {
padding-left: 17px;
width: calc(100vw - 17px);
}
}
Where the 1058px = content width + 17 * 2
This lets a horizontal scrollbar handle the x overflow and keeps the centered content centered when the viewport is wide enough to contain your fixed-width content
If the width of the table won't change, you can set the width of the element (such as tbody) that contains the scrollbar > 100% (allowing extra space for the scrollbar) and set overflow-y to "overlay" (so that the scrollbar stays fixed, and won't shift the table left when it appears). Also set a fixed height for the element with the scrollbar, so the scrollbar will appear once the height is exceeded. Like so:
tbody {
height: 100px;
overflow-y: overlay;
width: 105%
}
Note: you will have to manually adjust the width % as the % of space the scrollbar takes up will be relative to your table width (ie: smaller width of table, more % required to fit the scrollbar, as it's size in pixels is constant)
A dynamic table example:
function addRow(tableID)
{
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++)
{
var newRow = row.insertCell(i);
newRow.innerHTML = table.rows[0].cells[i].innerHTML;
newRow.childNodes[0].value = "";
}
}
function deleteRow(row)
{
var table = document.getElementById("data");
var rowCount = table.rows.length;
var rowIndex = row.parentNode.parentNode.rowIndex;
document.getElementById("data").deleteRow(rowIndex);
}
.scroll-table {
border-collapse: collapse;
}
.scroll-table tbody {
display:block;
overflow-y:overlay;
height:60px;
width: 105%
}
.scroll-table tbody td {
color: #333;
padding: 10px;
text-shadow: 1px 1px 1px #fff;
}
.scroll-table thead tr {
display:block;
}
.scroll-table td {
border-top: thin solid;
border-bottom: thin solid;
}
.scroll-table td:first-child {
border-left: thin solid;
}
.scroll-table td:last-child {
border-right: thin solid;
}
.scroll-table tr:first-child {
display: none;
}
.delete_button {
background-color: red;
color: white;
}
.container {
display: inline-block;
}
body {
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="test_table.css">
</head>
<body>
<h1>Dynamic Table</h1>
<div class="container">
<table id="data" class="scroll-table">
<tbody>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="button" class="delete_button" value="X" onclick="deleteRow(this)"></td>
</tr>
</tbody>
</table>
<input type="button" value="Add" onclick="addRow('data')" />
</div>
<script src="test_table.js"></script>
</body>
</html>
I tried to fix likely the same issue which caused by twitter bootstrap .modal-open class applied to body. The solution html {overflow-y: scroll} doesn't help. One possible solution I found is to add {width: 100%; width: 100vw} to the html element.
I use to have that problem, but the simples way to fix it is this (this works for me):
on the CSS file type:
body{overflow-y:scroll;}
as that simple! :)
The solutions posted using calc(100vw - 100%) are on the right track, but there is a problem with this: You'll forever have a margin to the left the size of the scrollbar, even if you resize the window so that the content fills up the entire viewport.
If you try to get around this with a media query you'll have an awkward snapping moment because the margin won't progressively get smaller as you resize the window.
Here's a solution that gets around that and AFAIK has no drawbacks:
Instead of using margin: auto to center your content, use this:
body {
margin-left: calc(50vw - 500px);
}
Replace 500px with half the max-width of your content (so in this example the content max-width is 1000px). The content will now stay centered and the margin will progressively decrease all the way until the content fills the viewport.
In order to stop the margin from going negative when the viewport is smaller than the max-width just add a media query like so:
#media screen and (max-width:1000px) {
body {
margin-left: 0;
}
}
Et voilà!
After trying most of the above CSS or JS-based solutions that haven't worked in my case, just wanted to add up to it.
My solution worked for the case where the scrollbar had to disappear on an event (e.g. a button click, cause you've just opened a full-screen menu that should block the page from being scrollable).
This should work when the below styles are applied to the element that turns overflow-y to hidden (in my case it's the body tag):
body {
overflow-x: hidden;
width: 100vw;
margin-right: calc(100vw - 100%);
}
Explanation: The width of your body tag is 100vw (so it includes the scrollbar's width).
By setting the margin-right, the margin only gets applied if your vertical scrollbar is visible (so your page content isn't actually under the scrollbar), meaning the page content will not reposition once overflow-y has changed.
Note: this solution only works for the pages that are not horizontally-scrollable.
Tested on Chrome 89.0, Firefox 87.0, Safari 14.0.3
Update: unfortunately it only works with centered container that doesn't take 100% width - otherwise the scrollbar overlays the piece of content on the right.
My approach is to make the track transparent. The scroll bar thumb color is #C1C1C1 to match the default scrollbar thumb color. You can make it anything you prefer :)
Try this:
html {
overflow-y: scroll;
}
body::-webkit-scrollbar {
width: 0.7em;
background-color: transparent;
}
body::-webkit-scrollbar-thumb {
background: #C1C1C1;
height:30px;
}
body::-webkit-scrollbar-track-piece
{
display:none;
}
I know the question is very old, but there is a new better method.
scrollbar-gutter: stable;
I tried overflow scroll but it didn't work for my case. the scroll bar still adds some kind of (white) padding. what works is changing the width from 100vw to 100%, but for the height it is ok to use 100vh. so this:
const Wrapper = styled.div`
min-height: 100vh
`
const Parent = styled.div`
width: 100%
`
const Children = styled.div`
width: 100%
`
Edit
I've set the width twice because the parent component held a sidebar, and the children. Depending on your use case, you can set it once.
Since I haven't found my solution here I would like to add it:
I did not want a permanent scrollbar (accepted solution) and I also decided to not use negative margins. They didn't (instantly) work for me in chrome and I also did not want to have content possibly disappearing below the scrollbar.
So this is a padding solution.
My web page consists of three parts:
Header (content is left aligned)
MainContent (content is centered)
Footer (content is left and right aligned)
Since the header would look bad with a left padding and since the logo should stay in the corner of the page, I kept it unchanged since the appearing of a scrollbar does not affect it in most cases (except when window width is very small).
Since an even padding is acceptable for both the MainContent and the footer I used only for those both containers the following css:
.main-content, .footer {
/*
* Set the padding to the maximum scrollbar width minus the actual scrollbar width.
* Maximum scrollbar width is 17px according to: https://codepen.io/sambible/post/browser-scrollbar-widths
*/
padding-right: calc(17px - (100vw - 100%));
padding-left: 17px;
}
This will keep the MainContent in the exact center and also work for all scrollbar width up to 17px. One could add a media query removing these paddings for mobile devices that have an overlay scrollbar.
This solution is similar to only adding the left padding and setting the width to "width: calc(100vw - 17px);". I cannot say if it would behave equally in all cases though.
I used some jquery to solve this
$('html').css({
'overflow-y': 'hidden'
});
$(document).ready(function(){
$(window).load(function() {
$('html').css({
'overflow-y': ''
});
});
});
#media screen and (min-width: 1024px){
body {
min-height: 700px
}
}
Contrary to the accepted answer which suggests a permanent scroll bar on the browser window even if the content doesn't overflow the screen, I would prefer using:
html{
height:101%;
}
This is because the appearance of scroll bar makes more sense if the content actually overflows.
This makes more sense than this.

How to make an image's width resize itself with a defined height

I am trying to make an image resizable.
I have a specific height for this image: height: 100% (inside a container) and a width: auto; (i want the width to be adapted to the height about the natural image size).
Everything works fine when i access the page, but when i resize the window, the height is correctly resized, but the width keeps its initial value, i want it to be proportional (like when i access the page for the first time) to the height.
Is there a way to do it in CSS ? If not, what is the more optimize solution ?
Here is an illustration in code:
HTML
<div class="container">
<img alt="test" src="/img/test.png">
</div>
CSS
.container {
height: 100px;
width: 100%;
}
.container img {
height: 100%;
width: auto; //i need it to be adapted to each height about the natural image's dimensions
}
UPDATE
Here is a jsfiddle
http://jsfiddle.net/CRGj6/1/
Sometime it works sometime it doesn't...
window resize affects only the width of the element but not the height. It is kinda make sense because if you resize the height, more content is scrollable that means don't do anything to width but to increase the scrollbar length (so more content to be scrolled). Assuming that you want to preserve the aspect ratio of the image,
.wrapper .container img {
position: relative;
height: auto;
width: 100%;
}
would be the solution to this problem.

Make nested div stretch to 100% of remaining container div height

I have a container div, which I want to stretch to at least the entire height of the window. If there's a lot of content in the container div, I want it to stretch to more than the window's height. This works.
In the container div I have an image. After/below the image, I have a second div. I want this nested div to stretch vertically to fill the remaining space of the container div. This doesn't work.
I've tried to illustrate the problem in this image. I want the div to stretch in the way illustrated in the left side of the right image, not as it looks on the right side of the right image.
The following is my code. As you can see, in this code I don't even try to make the div under the image stretch vertically, as nothing has worked. "Height: 100%" doesn't do the trick, as I've defined "100%" to be the height of the window by default, in order to make the container div to stretch to at least the window's height.
* {
margin: 0;
padding: 0;
}
body {
overflow-y: scroll;
overflow-x: hidden;
}
body,
html {
height: 100%;
}
.container {
display: block;
overflow: auto;
min-height: 100%;
height: 100%;
height: auto;
}
.bottom {
width: 100%;
}
<div class="container">
<img src="image.jpg" width="100%">
<div class="bottom">
LOREM IPSUM
</div>
</div>
I have spent way too much time trying to figure it out, but by George I've got it!
The "Eureka" moment was reading other questions where people were asking "how can I do it without using tables?" Because of course this layout is easy with tables. But that made me think of display:table.
As this blog post nicely argues, using display:table gives you table layouts without the nasty mark-up overhead as HTML table layouts, allowing you to have semantic code and different layouts for different media queries.
I did end up having to make one change to the mark-up: a wrapper <div> around the image. Also, max/min heights are all weird when dealing with table displays: height settings are treated as preferred heights given the constraints of parent and child elements. So setting a height of zero on a display:table-row wrapper div made that row fit to the content image exactly. Setting a height of 100% on the content div made it nicely fill the space in between the image and the minimum height of the parent container.
Voila!
Condensing just the essential code:
body {
overflow-y: scroll;
overflow-x: hidden;
}
body,
html {
height: 100%;
}
.container {
display: table;
width: 100% height: 100%;
/* this will be treated as a Minimum! It will stretch to fit content */
}
div.wrapper {
display: table-row;
height: 0px;
/* take as little as possible, while still fitting content */
}
img {
display: table-cell;
width: 100%;
/*scale to fit*/
}
.bottom {
display: table-cell;
height: 100%;
/* take as much as possible */
}
<div class="container">
<div class="wrapper">
<img src="http://placekitten.com/600/250" />
</div>
<div class="bottom" contentEditable="true">
</div>
Works in Firefox 25, Chrome 32, Opera 18 and IE10. Doesn't work in IE 8, but then what does? It doesn't look broken in IE8, it just doesn't stretch to fit.
If you can test it in Safari, IE9, or mobile browsers, leave a comment.
Flex boxes will be nice, when they are widely supported.
Even nicer would be a change in the spec so that if you specify min-height on a parent, you can use percentage values for a child object's min-height, instead of requiring that the parent height value has to be set explicitly for child height percentages to have any meaning. But I digress...
In the meantime, using "faux columns" can sort of get the effect you want. The concept is simple: you let the child div have an auto height, but then you paint the background of the parent such that it looks like the child div's background is continuing to the full height.
The example at that link does it with a background image, but you can use a background gradient if you don't mind sacrificing support for Safari and IE9-. (Remembering that lack of support just means not-quite-so-pretty, everything is functionally the same.)
Example here:
http://fiddle.jshell.net/y6ZwR/3/
The non-javascript way is to use flexbox. How exactly depends on a lot of details, but you can play around at http://the-echoplex.net/flexyboxes/.
Polyfills do exists, but what exactly to use depends on which browsers you are targeting.

How to make a flexible-height modal with fixed header

I've created a really simple modal that allows the content to decrease or expand without running off the page - always leaving 10% margin on the top and bottom. When the page isn't tall enough to contain all the modal content, the entire modal becomes scrollable.
See jsfiddle here
Is it possible, using only CSS, to replicate this behavior but only have the modal body be scrollable, so the header is always fixed. I've tried a few things, but haven't come up with the solution yet. Making the header position: fixed almost works, I have to reposition it over the modal box and then try to add padding to the body so the content is visible under the header, which doesn't budge the scrollbars down. I always prefer to exhaust all the css alternatives before I bind some js to window resize and manually manipulate the body height.
This might be late, but I had to solve a similar issue of fixed header, fluid height, fluid width.
This is how I tackled the issue:
Give your elements a border-box box-sizing. Use a wrapper to center and create a bounding box. This can be a fluid one with min-width and max-width + percentages.
Give your content element an overflow-y of auto and a max-height of 100%;
Use box-sizing:border-box;
The complete code should be something like this:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.modal {
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.8);
}
.wrap {
position: relative;
margin: 0 auto;
display: block;
width: 90%;
/* Change the max-width value on a media query breakpoint to make this example more "responsive" */
max-width: 500px;
height: 90%;
padding: 30px;
}
.modal header {
height: 30px;
padding: 0;
color: #FFF;
background-color: #007;
}
.modal .body {
background-color: #FFF;
max-height: 100%;
overflow-y: auto;
}
http://jsfiddle.net/mariomc/EhR7r/
Applying the max-height and overflow-y settings to .body rather than to .wrap...?
Edit 1:
Nothing's turned up so far within the constraints, which suggests either JavaScript or straying from the constraints (using % for the header height or px margins).
Edit 2:
Here's an initial demo using % for the header height. I added a px min-height to the header tag to prevent the header from almost disappearing on very small screens, at the expense of the top margin (which is reduced on very small screens).
On a screen >= 400px tall, it should work exactly as per the requirements (40px header with 10% height). If the header were reduced in height, it would support slightly-smaller screens (a 30px header with 10% height would support >= 300px screens). Here's a demo with a 30px header.
It's a clumsy solution, but it's the only one that turned up without using JavaScript.
Also, note that I added an h2 and a .content tag and moved the padding:10px; there, to avoid combining % height and padding in the same elements (which leads to a taller height than the % value specified).

Getting a horizontal scroll bar within a 100% div

I'm trying to build a quick overview that shows the upcoming calendar week. I want it arranged horizontally so it can turn out to be quite wide if we show a full calendar week.
I've got it set up right now with an inner div with a fixed width (so that the floated "day" divs don't return below) and an outer div that's set to width: 100%. I'd LIKE for the outer div to scroll horizontally if the page is resized so that the inner div no longer fits in it, but instead the outer div is fixed larger at the width of the inner div and the page itself scrolls.
Gah I'm not good at explaining these things... Here's a bit of code that might clear it up..
The CSS:
.cal_scroller {
padding: 0;
overflow: auto;
width: 100%;
}
.cal_container {
width: 935px;
}
.day {
border: 1px solid #999;
width: 175px;
height: 200px;
margin: 10px;
float: left;
}
and the (simplified) structure:
<div class="cal_scroller">
<div class="cal_container">
<div class="day">Monday</div>
<div class="day">Tuesday</div>
<div class="day">Wednesday</div>
<div class="day">Thursday</div>
<div class="day">Friday</div>
</div>
</div>
So to try again - I'd like the cal_scroller div always be the page width, but if the browser is resized so that the cal_container doesn't fit anymore I want it to scroll WITHIN the container. I can make it all work if I set a fixed width on cal_scroller but that's obviously not the behavior I'm going for. I'd rather not use any javascript cheats to adjust the width of the div if I don't have to.
Your cal_scroller class is 100% + 20px (padding) wide. Use a margin on cal_container instead, like so:
.cal_scroller {
padding: 10px 0;
overflow: auto;
width: 100%;
}
.cal_container {
margin: 0 10px;
width: 935px;
}
See here for a description of how the box model works (in short, the everything is outside the width/height of an element).
Also, block elements (like <div>s) are 100% width by default, making your 100% width declaration redundant.
One problem I see is your width: 100% rule. div.cal_scroller is already a block-level element, so it'll default to filling the entire page width. (Not to mention that padding is added on top of width, so you end up with that div being bigger than the page.)
Just get rid of that width rule, and you should be golden. (I just tried myself, and it worked like a charm.)
I didn't read your question very carefully, but when you have width: 100% and padding, that's generally not what you want.
100% + 20px > 100% - that might be the problem.
I struggled with this a lot but the simplest solution I found was adding:
.cal_container { white-space: nowrap; }
This way you don't have to give it a width at al. It just makes sure everything stays in one line.

Resources