I am trying to make a list in HTML with only a vertical scrollbar. I understand how to do this but the part where I get stuck is positioning a div inside the overflow'd element over the edges of the overflow'd element.
See code below:
#wrapper {margin: 50px; width: 500px; height: 500px;}
#scrollable {width: 200px; height: 500px; overflow-y: visible; overflow-x: hidden;}
.item {clear: left; width: 200px; height: 40px;}
<body>
<div id='wrapper'>
<div id='scrollable'>
<div class='item'></div>
<div class='item'></div>
</div>
</div>
</body>
I want the .item elements to go 5 or 10 pixels over the left edge of #scrollable.
Can anyone show me how to do this?
Thanks.
So, as others have said, you cannot show elements out of the bounds of an elements that has an overflow that is not "visible."
However, assuming you're simply trying to achieve an effect, you can do so easily. One way would be, if your #scrollable element must be 200px, then make each .item 190px in width, and offset by 10px to the left. Otherwise, if you're .items must be 200px in width, then make your #scrollable element 210px to compensate. Then, on selection, offset left by 0.
I've made a JSFiddle with it. Take a look (the JS in it is unnecessary, but just mimics a selection)
http://jsfiddle.net/rgthree/tpfLZ/
In #wrapper, add: overflow: visible;
In #scrollable, add: margin-left: -10px; (you may need to set width: 210px to compensate)
Test to make sure this does what you're looking for. (Note that this will make items > 200px get cut off to the right)
Related
I have two DIVs on my site, both set to display: inline-block. Setting width: auto on the parent should cause it to use only the space occupied by the child.
However, when I use a large width on the child but override it with max-width and min(...) the parent size ignores the width (large whitespace on the right). In the following example you can clearly see that the max-width gets applied, but the auto keyword ignores it and stretches the parent anyway.
I want the parent element to only use the horizontal space necessary. Any idea on how to fix it? Thanks!
.wrapper-1{
display: inline-block;
width: auto;
background-color: blue;
}
.hello-world{
display: inline-block;
width: 5000px;
max-width: min(100px, 100%);
background-color: yellow;
}
<div class="wrapper-1">
<div class="wrapper-2">
<div class="hello-world">Hello, world!</div>
</div>
</div>
I have a floated div (class='outer') of fixed height with dynamic content (class='inner'). The dimensions of the content are not known in advance. The width of the floated div must be flexible, but still have some maximal value:
<style>
.outer {
border: 1px solid;
height: 200px;
max-width: 400px;
overflow: auto;
float: left
}
.inner {
height: 300px;
width: 300px;
background-color: red
}
</style>
<body>
<div class='outer'>
<div class='inner'></div>
</div>
<span>Text here</span>
</body>
This generally works; however, in case of excessive content height the following happens:
.outer assumes the width of the content, as it is below its max-width.
.inner is forced into height of the .outer and as a result the vertical scroll bar appears.
.inner is forced into a new constrained width, as the .outer will not resize once more to accommodate the scroll bar.
The completely unnecessary horizontal scroll bar appears as a result.
The fiddle: https://jsfiddle.net/w053kLkw/
Is there a way to prevent this mechanism of overflow and have both scroll bars appearing only when needed?
Not possible in CSS AFAIK (you need JS or you should not use floats!).
When you float an item, it is removed from the normal block formatting context. Floated items won't respect max-width as it will shrink to its content- so specifying a width to outer would be needed.
See what happens below when I set width: 400px also.
*{
box-sizing: border-box;
}
.outer {
border: 1px solid;
height: 200px;
max-width: 400px;
width: 400px;
overflow: auto;
float: left;
}
.inner {
height: 300px;
width: 300px;
background-color: red;
}
<body>
<div class='outer'>
<div class='inner'></div>
</div>
<div style="clear: both;"></div>
<span>Text here</span>
</body>
Explanation:
According to W3C specs, a width should always be specified to floated elements (other than replaced elements like image which has an implicit width). Otherwise we will see unpredictable behaviour.
See the section: Do floated items need a width? in this link.
If no width is set, the results can be unpredictable. Theoretically, a
floated element with an undefined width should shrink to the widest
element within it. This could be a word, a sentence or even a single
character - and results can vary from browser to browser.
This means outer will take the width of the inner- and as overflow is not visible the browser behaves as it sees fit.
I've been banging my head against the wall really hard for the past couple of hours to figure out a way to achieve the layout I'd like for a webapp. And my head hurts.
Basically what I need is to have a full window layout (full width, full height, no scrolling - ever). 100% of width and height should be covered using two different horizontal boxes (you can see them as rows).
The height of the first box/row can be variable (see it as a header for the page)
The one below should occupy what's left of the space, without ever going further than 100% of the window, hence without ever showing a scrollbar.
Now what's a bit more tricky is that within the second box/row, I want content to be displayed with an inner vertical scrolling. Imagine the second box/row contains a list of items, in case of very few items, the bottom part of the box/row should stop right after the content. In case of many items, the box/row should expand right until it hits 100% of the window height (which is basically 100% of the windows - the height occupied by the first box/row). The rest of the content should be visible through scrolling within the second box/row.
Am I making any sense?
Regarding the code, I'm not going to copy/paste the desastrous thing I've pulled together because I'd rather start from a blank page.
This is what I tried:
<html>
<body>
<div id="wrapper">
<div class="box">Header</div>
<div class="box">Content <ul><li>...</li>(x1000)</ul></div>
</div>
</body>
</html>
The reason why I use a "box" class is because both boxes/rows should show the same appearence in terms of backgrounds, margins, shadows, etc.
html, body {
height: 100%;
}
#wrapper {
position: absolute;
height: 100%;
width: 100%;
left: 15px;
right: 15px;
top: 15px;
bottom: 15px;
}
For the rest, I've just tried (and failed so far) to manipulate the .box elements by adding hazardously overflow: hidden; overflow-y: scroll; height: 100%; max-height: 100%; min-height: 100%; etc.
Thanks in advance for your help!
The problem is because CSS has long been crappy about auto-adjusting height to available space.
The solution is to use a wrapper that's set to position: absolute and tied to the top, left, right, and bottom edges of the viewport. With this, the browser will auto adjust the height of the element, and if you have a content div inside with height: 100% it'll always fill that space.
Setting overflow-y: scroll on the wrapper will allow the content to scroll if it becomes too long:
http://codepen.io/helion3/pen/jwbcx
Site headers are usually not variable in height. If you're defining the site header using percentages, and if you don't need to support IE<8 then you can use percentages safely with box-sizing: border-box to achieve the same.
I believe this should do the trick.
If you adjust the height of .header make it is equal to the top: position of .content
CSS:
html, body {
margin: 0;
}
.header {
height: 150px;
background: #0080ff; // (Unnecessary, this is set to help you see the header div)
}
.content {
position: absolute;
top: 150px;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
background: #ff8000; // (Unnecessary, this is set to help you see the content div)
}
HTML:
<body>
<div id="wrapper">
<div class="box header">Header</div>
<div class="box content">Content</div>
</div>
</body>
Maybe you want something like this? I replaced class="box" with ids, but it should work.
Consider following things:
No need to have the "absolute" positioned div (#wrapper in your example)
Create 2 box div same like you have created in your example (.box)
Second box should have "overflow:auto" style property
Calculate the height of header and full display area's height with javascript
Calculate the remaining height and assign this value as height, min-height and max-height for the second box. That's it.
You can check the solution here:
http://webnflash.com/temp/occupyAvailableHeight.htm
My goal is to get a sidebar layout which should scale based on the browser window width. Some parts should have a scaled width, others should have a static width and some should scale but with a min/max-width. (It also would be great if some would expand based on the content within)
The html:
<div id="table">
<div id="row">
<div id="sidebar">at least 90px width<br/>not more than 130px width</div>
<div id="content">scale</div>
<div id="logo">should be static 60px</div>
<div id="sidebar2">at least 90px width</div>
</div>
</div>
and the css:
#table {
display: inline-table;
width: 100%;
}
#row {
display: table-row;
}
#table #row div {
display: table-cell;
}
#sidebar {
width: 10%;
min-width: 90px;
max-width: 130px;
}
#content {
width: 70%;
}
#logo {
min-width: 60px;
background-color: #FAB6B8;
}
#sidebar2 {
min-width: 90px;
width: 20%;
}
The issues:
It appears that max-width has no effect on dom-elements with display:table-cell assigned. (I guess)
I tried to work with another div, spans around the actual cell div.
This causes the problem, that the cell scales perfectly, but the left side of the content div will not stick to the first sidebar. (Same problem, if I put the "max-width div" inside the cell)
Working with a float: left layout doesn’t work either. (Float breaks if window gets too small; don’t scale, if I use a div to protect it)
Is there a way to work around this without using js?
Put in a div in #row with no further CSS will work for a div, which expand based on content. Sadly if there is just text in it breaks after every word. How can I prevent this and be able to set a max width and hide the overflow?
I found the Answer by myself:
The key is to apply absolute width to the elements, which should get a max width.
It's not perfect, because the divs with an absolute width don’t scale, until the one with a relative width reach their min-widths but I guess it’s the only way.
So simple.
Sorry for the trouble...
Edit 2: It seems clear that no one seems to be able to understand what I'm asking, so I'll try to illustrate it;
The area in the center has the id #navigation. This has the following CSS properties,
width: 960px;
margin: auto;
background: #e4bd04;
The reason it has a width of 960px, is because I would like the links in my navigational bar to remain within a 960px limit. I'd also like them centered, so I apply margin: auto. However, this means that my background only flows for 960px. I'd like the background to flow for the entire window width (100% of page), so that users with larger screens don't end a huge chunk of white space at the top.
In order to prevent this, I nest #navigation into another id, #navouter, to which I apply width: 100%; and background: #e4bd04;, so that the background now appears to extend for the entire width of the window.
Is there any way to do this without using two elements as I've done?
I've undestood, you don't want to have 2 div to center another div with fixed width, isn't it ?
I don't think that you'll love it, but this is a solution :
.nav {
width:960px;
position:absolute;
left:50%;
margin-left:-480px; // width / 2
}
<body>
<div class="nav">Test content</div>
</body>
Result for 300px div : http://jsfiddle.net/7GTCc/1/
Or another, really ugly (lol) :
.nav {width:960px;}
<center>
<div class="nav">Test content</div>
</center>
Edit regarding your illustration
"Is there any way to do this without using two elements as I've done?"
No :-)
But if you only want the background to be 100%, don't specify a background (color or url) to your #navigation.
Last try to answer, test this :
#navigation {
min-width:960px;
text-align:center;
}
Demo here : http://jsfiddle.net/7GTCc/3/
you could use min-width property , dont know what exactly you are looking for
<div style="min-width:960px; width:100%"></div?
Yes, this is easy to do without additional markup. Use the ::before pseudo-element for the expanding part of the navigation.
Demo: http://jsfiddle.net/ThinkingStiff/eAf7w/
HTML:
<div id="nav">navigation</div>
CSS:
#nav {
background: #6D7B8D;
height: 40px;
margin: 0 auto;
width: 400px;
}
#nav::before {
background-color: lightblue;
content: '\00a0';
display: block;
height: 40px;
left: 0;
position: absolute;
width: 100%;
z-index: -1;
}