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.
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>
Let's say I have a div with a fluid width (for example, min-width 200px and max-width 1000px). We'll call this div Div1. I want to wrap this div in a parent div and I want this parent div to shrink to fit Div1 without affecting Div1's width at all.
From what I've read, the way to get a parent to fit its contents is to set the parent's display to inline-block. However, whenever I do this it seems to force the contents to shrink to their min-width. Here's an example on codepen - I have two divs with the exact same properties but one of them is forced to its min width because it is has a parent container with display: inline-block.
http://codepen.io/ahung89/pen/LGqrwz
Code below (HTML on top CSS on bottom)
<div class="container">
<div class="div-with-min-width">
This div is forced to its minimum width.
</div>
</div>
<div class="div-with-min-width">
This div is not forced to its minimum width.
</div>
.div-with-min-width {
border: 1px red solid;
background: red;
color: yellow;
min-height: 100px;
min-width: 200px;
max-width: 1000px;
}
.container {
border: 4px green solid;
display: inline-block;
}
How do I make the parent wrap to the child's width without actually changing the child's width?
Add float: left; or float: right; or overflow: hidden; to collapse the parent element.
Look at this jsfiddle:
http://jsfiddle.net/w9k2sz52/
#content {
background: #ff0000;
min-height: 200px;
}
.container-fluid {
min-width: 2000px;
}
<div id="content">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<h1>Some title here</h1>
</div>
</div>
</div>
</div>
Why is the width of #content not stretching to be 2000px instead of being the width of the viewport? What do I need to do to make content stretch so that no matter what min-width is set on container-fluid #content will always stretch to fit it
Set #content to inline-block, and then set min-width to 100%. Note that setting width to 100% won't have the desired affect.
#content {
background: #ff0000;
min-height: 200px;
min-width: 100%;
display:inline-block;
}
Adding a float will make the parent element the same width as the child:
#content {
background: #ff0000;
min-height: 200px;
float: left;
}
#content {
background: #ff0000;
min-height: 200px;
display: inline-block;
}
You could use
width:auto;
This should mean it stretches to the width of its contents.
EDIT:
The min-width property in CSS is used to set the minimum width of a specified element. The min-width property always overrides the width property whether followed before or after width in your declaration. Authors may use any of the length values as long as they are a positive value.
You need to set a max-width or width with it. Say you had a width of 80% and a min width of 400px, it will be no smaller then 400px even if 80% of the page is 200px.
You could give the content a min width forcing the div to be auto and be no smaller then the content.
Could #content determine the width, while .container-fluid expands to fill it? Instead of the other way around.
#content {
background: #ff0000;
min-height: 200px;
width:2000px;
}
.container-fluid {
width: 100%;
}
By adding
position:absolute
to your CSS declaration for #content, you force the CSS interpreter to check what elements are inside #content, therefore achieving desired effect.
The problem with absolute positionning is that it remove the element from the natural workflow of the document. Therefore, you are better wrapping the element unto which you want to apply absolute positionning inside another element. This one will stay in the natural workflow of the DOM.
See this jsfiddle: https://jsfiddle.net/7Ls47d83/4/
Google "CSS box model" for more interesting articles and post about this, or this article.
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...
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)