I have two divs, an outer div and an inner div inside it. I've set the outer div to have a fixed width (505px) with overflow-x: scroll.
My inner div contains floated left dynamic content (meaning there could be one div or 100) and so could have a width of anywhere between 50px to 5000px. I'm trying to style the inner div so that it can accommodate the dynamic content all on one line but it's not behaving like that; it's hitting the 505px and moving down to the next line. If I give it a width of 5000px, obviously it's working, but the content could be much less than that. What am I doing wrong?
#outer-div {
width: 505px;
height: 100%;
float: left;
background-color: #fff;
overflow-x: scroll;
overflow-y: hidden;
}
#inner-div {
width: auto;
display: inline;
}
.dynamic-content {
width: 62px;
height: 100%;
font-size: 13px;
text-align: center;
float: left;
}
<div id = "outer-div">
<div id = "inner-div">
<div class = "dynamic-content"></div>
<div class = "dynamic-content"></div>
<div class = "dynamic-content"></div>
etc...
</div>
</div>
It's not a width setting..you need to stop the line breaks with white-space:nowrap
#outer-div {
width: 505px;
height: 100%;
float: left;
background-color: #fff;
overflow-x: scroll;
overflow-y: hidden;
border: 1px solid grey;
white-space: nowrap;
}
.dynamic-content {
height: 100%;
font-size: 13px;
text-align: center;
display: inline-block;
}
<div id="outer-div">
<div class="dynamic-content">AAAAAAAAAAAAA</div>
<div class="dynamic-content">BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</div>
<div class="dynamic-content">CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC</div>
etc...
</div>
You can do it with flexbox:
http://codepen.io/anon/pen/grymeG
The inner DIV becomes the flex-container, with flex-wrap:no-wrap to stay in one line and overflow-x: visible;, the dynamic contents get flex-shrink: 0; to not be reduced in width:
#inner-div {
width: auto;
height: 100%;
overflow-x: visible;
display: flex;
flex-wrap: no-wrap;
}
.dynamic-content {
width: 62px;
flex-shrink: 0;
height: 100%;
font-size: 13px;
text-align: center;
}
white-space: nowrap forces the inner elements to stay on the same line, but it won't work with floated element. So you can use display: inline-block but you need to use a trick for the space between the divs (negative margin or html comments between them).
Example :
.outer {
border: 1px solid black;
height: 100px;
width: 500px;
overflow-x: scroll;
white-space: nowrap;
}
.content {
display: inline-block;
margin-left: -4px;
box-sizing: border-box;
width: 100px;
height: 100px;
border: 1px solid red;
}
<div class="outer">
<div class="inner">
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>
</div>
you need to use white-space:no-wrap;
the style will be like this:
#outer-div {
width: 505px;
height: 100%;
float: left;
background-color: #fff;
}
#inner-div {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
}
.dynamic-content {
height: 100%;
font-size: 13px;
text-align: center;
display: inline-block;
}
see your demo here https://jsfiddle.net/IA7medd/o831zdqs/
Related
I have a div in HTML that has two child divs, one on the right and one on the left. Both child divs have contenteditable set, so when the user click in them they can type. However, when the text goes below the size of the div, the parent div overflows and scrolls, but the child divs don't.
Here is an example:
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
height: 100%;
float: left;
overflow: visible;
}
#part2 {
width: 50%;
margin: 0;
background: green;
height: 100%;
float: right;
overflow: visible;
}
<div id="container">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
In the above example, try typing more text than can fit vertically (by spamming the enter key while inside the box). Once the text goes over the side of the box, the parent overflows like it is supposed to, however, the children (which are being typed into) don't, even though they have 100% height.
Is there a way to make the children extend WITH the parent, so they both scroll together when one/both overflows?
It is very good for your task to use the rules of flexibility. Add display: flex and flex-flow: wrap for #container. And remove the height: 100% from the children, because flex-flow: wrap itself will stretch the elements to the full height.
Also, remove float: left and overflow: visible from children.
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
display: flex;
flex-flow: wrap;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
/*height: 100%;
float: left;
overflow: visible;*/
}
#part2 {
width: 50%;
margin: 0;
background: green;
/*height: 100%;
float: right;
overflow: visible;*/
}
<div id="container">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
You could change height to min-height for the inner divs and use an additional inner div with display: flex so that both colored divs have the same growing height. overflow: visible is not necessary.
Working example:
#container {
width: 300px;
height: 200px;
border: 1px solid black;
overflow: scroll;
color: white;
background: gray;
}
#inner {
display: flex;
min-height: 200px;
}
#part1 {
width: 50%;
margin: 0;
background: blue;
min-height: 100%;
float: left;
}
#part2 {
width: 50%;
margin: 0;
background: green;
min-height: 100%;
float: right;
}
<div id="container">
<div id="inner">
<div id="part1" contenteditable="true"></div>
<div id="part2" contenteditable="true"></div>
</div>
</div>
Since you define some css twice and overflow-x is not necessary you can add a class to the colored divs and set the overflow for the container only to overflow-y.
Working example:
#container {
border: 1px solid black;
width: 300px;
height: 200px;
color: white;
background: gray;
overflow-y: scroll;
}
#inner {
display: flex;
min-height: 200px;
}
.editable {
width: 50%;
margin: 0;
min-height: 100%;
}
#part1 {
background: blue;
float: left;
}
#part2 {
background: green;
float: right;
}
<div id="container">
<div id="inner">
<div class="editable" id="part1" contenteditable="true"></div>
<div class="editable" id="part2" contenteditable="true"></div>
</div>
</div>
I created an outer container, in which are at least two child containers. One of those 2 containers (inner container 1) has a content which make it overflow in its height. By that the outer container is growing as well.
The 2nd inner container is inheriting the height of the outer container, but it just retrieves the height of the outer container which is set to a certain value.
How do I make the second container grow to the full height of the outer container?
Hint: I kinda have the feeling that it's not possible at all.
Here a snippet:
* {
box-sizing: border-box;
}
.padding {
padding: 10px;
}
.outer-container {
height: 400px;
width: 100%;
background-color: yellow;
overflow-y: scroll;
}
.overflowing-container {
width: 20%;
display: inline-block;
background-color: salmon;
overflow-y: visible;
}
.inherit-height-container {
height: inherit;
width: 70%;
display: inline-block;
background-color: salmon;
vertical-align: top;
}
.large-element {
height: 250px;
width: 100%;
margin-top: 5px;
background-color: lightsalmon;
}
<div class="outer-container padding">
<div class="overflowing-container padding">
<div class="large-element"></div>
<div class="large-element"></div>
<div class="large-element"></div>
</div>
<div class="inherit-height-container"></div>
</div>
If you can edit your html, you can just add an inner wrapper and make it flex:
* {
box-sizing: border-box;
}
.padding {
padding: 10px;
}
.outer-container {
height: 400px;
width: 100%;
background-color: yellow;
overflow-y: auto;
}
.inner-container {
display: flex;
}
.overflowing-container {
width: 20%;
display: inline-block;
background-color: salmon;
margin-right: 5px; /* not sure if you want this gap */
}
.inherit-height-container {
/* remove height from this */
width: 70%;
display: inline-block;
background-color: salmon;
vertical-align: top;
}
.large-element {
height: 250px;
width: 100%;
margin-top: 5px;
background-color: lightsalmon;
}
<div class="outer-container padding">
<div class="inner-container">
<div class="overflowing-container padding">
<div class="large-element"></div>
<div class="large-element"></div>
<div class="large-element"></div>
</div>
<div class="inherit-height-container"></div>
</div>
</div>
jsfiddle: https://jsfiddle.net/jefftg/1chmyppm/
The orange header columns and the white list rows scroll together horizontally, which is desired. However, I want the white list rows to scroll vertically with the orange header fixed at the top. They currently don't. I'm looking for this to work in modern browsers with HTML5/CSS3.
css
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
}
.header-container {
display: flex;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
}
.data-row {
overflow-x: hidden;
display: flex;
}
.data-row-cell {
height: 30px;
min-width: 500px;
background-color: white;
border: 1px solid black;
}
html
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>
This can be done with pure CSS and you don't need JavaScript.
I've modified your JSFiddle to work the way you are requesting: https://jsfiddle.net/48386nvn/3/
Essentially, .header-container needs to be positioned absolute relative to the .container element:
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
/* added this: */
position: relative;
}
.header-container {
display: flex;
/* added these: */
position: absolute;
top: 0;
left: 0;
}
The above-mentioned CSS will stick the orange header where you want it and maintain the width you need it to be.
Next, you'll need to make the data scrollable, which is done by doing the following calculation:
height: heightOfParentContainer - heightOfHeaderRow;
The header cell height is 40px (42px when respecting the borders) It also needs a margin-top equal to the height of the header row:
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
/* added these: */
margin-top: 40px;
height: 560px;
}
This should make sure that the header row is not overlapping the data container, and that the height of the data takes up the rest of the space of the overall container.
I was able to get the desired result by simply adding height: 558px to .data-container: jsfiddle.net/jefftg/1chmyppm/2
You don't need to add the overflow to every element, just the elements that need scrolling,
all I did is gave your .data-containera display:block and a certain height so that the overflow-y:auto can work, you can change the height with what you see fits in your page.
this here shows my solution, I hope it helps.
$(".header-container").scroll(function() {
var scrollPercentage = 100 * this.scrollLeft / (this.scrollWidth - this.clientWidth);
$(".data-container").scrollTop(scrollPercentage);
});
.container {
width: 800px;
height: 600px;
}
.header-container {
display: flex;
overflow-x: auto;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: block;
height: 100px;
}
.data-row {
display: block;
}
.data-row-cell {
height: 50px;
min-width: 500px;
background-color: white;
display: block;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>
I can't figure out how to keep multiple divs inline if their width exceeds container width.If the width of all divs is about 1000 px and the container's width is 500 , i want the divs to be overlapped by container , and a horizontal scroll bar to show up.
#container {
overflow: hidden;
background: red;
width: 500px;
height: 500px;
}
#container>div {
border: 1px solid #000;
width: 30%;
height: 100px;
margin: 10px;
float: left;
}
<div id="container">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
<div class="fourth"></div>
<br style="clear: both;">
</div>
Fiddle: Click
Don't use float, use inline block with container set to nowrap for white space, and then add overflow: auto; to the container to trigger the scrollbar as needed.
jsFiddle
#container{
white-space: nowrap;
overflow: auto;
}
#container>div{
display: inline-block;
}
Add some CSS
#container {
background: red none repeat scroll 0 0;
height: 200px;
overflow: auto;
white-space: nowrap;
width: 500px;
}
#container > div {
border: 1px solid #000;
display: inline-block;
height: 100px;
margin: 10px;
width: 30%;
}
http://jsfiddle.net/WGCyu/1325/
As Pangloss says, don't use float, but display them inline. And use overflow-x:scroll
#container {
overflow: hidden;
background: red;
width: 500px;
height: 500px;
white-space: nowrap;
overflow-x:scroll
}
#container>div {
border: 1px solid #000;
width: 30%;
height: 100px;
margin: 10px;
display: inline-block;
}
<div id="container">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
<div class="fourth"></div>
<br style="clear: both;">
</div>
I have a div with class container. I have 3 more divs inside .container. What I want is to display internal divs float: left so that 2 divs tags are visible inside .container and the third one is invisible and is placed on the right side of first 2 div tags which are visible. I am trying the following code but it makes all tags visible all the time.
jsfiddle
<div class="container">
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
</div>
css
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
}
.div {
width: 200px;
height: 200px;
background: blue;
float: left;
border: 1px solid red;
}
I want above to look like this
You can do as such in other way,
HTML
<div class="container">
<div class="innerContainer">
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
</div>
</div>
CSS
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
}
.innerContainer {
position: relative;
width: 605px;
height: 500px;
overflow: hidden;
}
.div {
width: 200px;
height: 200px;
background: blue;
float: left;
border: 1px solid red;
}
Check over here http://jsfiddle.net/nftp6/8/
Use:
display: inline-block;
white-space: nowrap;
For that effect
Fiddle:
http://jsfiddle.net/Hive7/nftp6/5/
Use display:inline-block instead of float and set white-space:nowrap to the container:
.container {
position: relative;
width: 405px;
height: 500px;
background: red;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
}
.div {
width: 200px;
height: 200px;
background: blue;
display: inline-block;
border: 1px solid red;
}
Demo fiddle
Now you'll most likely face some white-space issues, read this answer for multiple ways to handle that