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>
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>
This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 3 years ago.
I use display: inline-block for div.left - div.right and div.red - div.yellow but none of them are in the same line. I set the width exactly. But it does not work at all.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Update
If you need to keep inline-block styles, you need the .left and .right divs to add up to 800px. The thing with inline-block is that it will include white space and add it to the width. This is why the wrapping is still occurring. The following image shows the white space that is causing the wrapping.
There are many ways to remove white space and make this fit. One way is to add an HTML comment between the .left and right div, which removes all white space.
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
If you add display: flex to the .container, the immediate children (.left and .right) will align in the same row. The .right div is 50px taller than the .left div because of the explicit width being set (550px for .right, 500px for .left).
Also, you can remove this, as it will no longer have any effect due to the flexbox container.
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
display: flex;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
if use display: inline-block , there will be some space between the elements. In order to overcome that u can use float property so that every element will be aligned in the same line.
If u want to go with display: inline-block property, you have to reduce the width of .red and .yellow,say for example
.red,.yellow{ width: 270px}
I want to add margin (10px) to .inner-container (blue) which is 960px fixed width which also inside .outer-container (360px fixed width).
To make it scrollable, i set overflow: scroll to .outer-container
to add margin to inner container, I set margin: 10px; to .inner-container.
the problem is there are no margin on the right side of .inner-container.
.outer-container {
width: 360px;
height: 500px;
background: #555;
overflow: scroll;
}
.container-inner {
width: 960px;
height: 300px;
background-color: #0D47A1;
margin: 10px;
}
<div class="outer-container">
<div class="container-inner"></div>
</div>
You can do it, by adding one more div (with 980px width), to wrap inner container, so applied margin will work:
.outer-container {
width:360px;
height: 500px;
background: #555;
overflow-x: scroll;
}
.inner-wrap {
width:980px;
}
.container-inner {
width: 960px;
height: 300px;
background-color: #0D47A1;
margin:10px;
}
<div class="outer-container">
<div class="inner-wrap">
<div class="container-inner"></div>
</div>
</div>
try giving padding to outer container instead of giving margin to inner container.
.outer-container {
width: 360px;
height: 500px;
background: #555;
overflow: scroll;
padding: 10px;
}
.container-inner {
width: 960px;
height: 300px;
background-color: #0D47A1;
display:block
}
You need one more wrap between parent and child div element.
Consider the following markup:
<div class="outer-container">
<div class="middle-container">
<div class="inner-container"></div>
</div>
</div>
And add padding + width on this middle element:
.middle-container {
padding: 10px;
width: 960px;
}
Output Image:
Working Demo:
* {box-sizing: border-box;}
.outer-container {
width: 360px;
height: 500px;
background: #555;
overflow: scroll;
}
.middle-container {
padding: 10px;
width: 960px;
}
.inner-container {
background-color: #0D47A1;
height: 300px;
}
<div class="outer-container">
<div class="middle-container">
<div class="inner-container"></div>
</div>
</div>
I have divs that i want to wrap to the next line when the browser window gets smaller. I also want margin to be put in between the divs so that there's a gap between them. The problem I'm having is that the margin on the centre divs causes the divs to wrap incorrectly if the browser is set to a specific size. At a certain size you have 2 divs underneath one div. See my screenshot below as an example and this fiddle: http://jsfiddle.net/uhh2jwe2/ (change the width of the window)
This really needs to be dynamic as it will be a framework solution for laying out differently sized divs. The parent div will be fluid similar to the example. Any help would be great
#outer {
width: 90%;
height: 90%;
margin: 5%;
overflow: auto;
background-color: red;
}
.inner1 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner2 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner3 {
float: left;
width: 150px;
height: 150px;
background-color: blue;
}
<div id="outer">
<div class="inner1">1</div>
<div class="inner2">2</div>
<div class="inner3">3</div>
</div>
You can use media queries to alter the css on smaller screen.
#outer {
width: 90%;
height: 90%;
margin: 5%;
overflow: auto;
background-color: red;
}
.inner1 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner2 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner3 {
float: left;
width: 150px;
height: 150px;
background-color: blue;
}
#media (max-width: 435px) {
#outer > div {
margin-right:auto;
margin-left:auto;
margin-bottom:15px;
float:none;
}
}
<div id="outer">
<div class="inner1">1</div>
<div class="inner2">2</div>
<div class="inner3">3</div>
</div>
Use Media query like this:
#outer div:last-child {
margin-bottom: 0;
}
#media screen and (max-width:570px) {
.inner1, .inner2, .inner3 {
margin-bottom: 5px;
}
}
#media screen and (max-width:411px) {
.inner1, .inner2, .inner3 {
float: none;
margin: auto;
margin-bottom: 5px;
}
}
#outer {
width: 90%;
height: 90%;
margin: 5%;
overflow: auto;
background-color: red;
}
.inner1 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner2 {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
.inner3 {
float: left;
width: 150px;
height: 150px;
background-color: blue;
}
#outer div:last-child {
margin-bottom: 0;
}
#media screen and (max-width:570px) {
.inner1, .inner2, .inner3 {
margin-bottom: 5px;
}
}
#media screen and (max-width:411px) {
.inner1, .inner2, .inner3 {
float: none;
margin: auto;
margin-bottom: 5px;
}
}
<div id="outer">
<div class="inner1">1</div>
<div class="inner2">2</div>
<div class="inner3">3</div>
</div>
I would recommend a solution that extracts the grid-elements from the content-elements. Therefore you have a lot more control about your layout and you can be more flexible with content you want to place into it.
Use your .inner elements as grid-elements and wrap content inside them into .inner-content
Wrap all inners into a row to get rid of the outer-gutter
Give the .inner elements a percentage-width and a px-max-width. So the elments can take alwyay 33.33% of the avaiable width but never more then 150px.
I added some adjustments for small screens, so the .inner elements wrap below each other and take more then 33.33% of the .outer container width.
Inspect the code: http://jsfiddle.net/uhh2jwe2/5/
* {
box-sizing: border-box;
}
/* flexible outer container */
.outer {
width: 90%;
height: 90%;
margin: 5%;
overflow: hidden;
background-color: red;
}
/* remove outer gutter */
.row {
margin: 0 -10px;
}
/* .inner will take care of the width */
.inner {
width: 33.33%;
max-width: 150px;
float: left;
padding: 0 10px;
}
/* .inner-content take care of the height */
.inner-content {
height: 150px;
color: #fff;
background: blue;
}
#media (max-width: 435px) {
/* this wraps .inner elements below each other and extends width */
.outer .inner {
padding: 10px 0;
width: 100%;
max-width: 100%;
float:none;
}
}
<div class="outer">
<div class="row">
<div class="inner">
<div class="inner-content">1</div>
</div>
<div class="inner">
<div class="inner-content">2</div>
</div>
<div class="inner">
<div class="inner-content">3</div>
</div>
</div>
</div>
I would suggest to use bootstrap's technique for that. Have padding on both sides of your inner elements, and negate it with negative margin on the container.
This will require more markup tough. While .row and .container could be merge on the same element, the background-color would overflow to the left because of the negative margin.
.container {
background-color: green;
width: 510px;
}
.row {
font-size: 0;
margin: 0 -15px;
}
.block {
font-size: 12px;
padding: 0 15px;
display: inline-block;
}
.content {
width: 150px;
height: 150px;
background-color: red;
}
<div class="container">
<div class="row">
<div class="block">
<div class="content">
</div>
</div>
<div class="block">
<div class="content">
</div>
</div>
<div class="block">
<div class="content">
</div>
</div>
<div class="block">
<div class="content">
</div>
</div>
<div class="block">
<div class="content">
</div>
</div>
</div>
</div>
in your example, the first two divs are 170px wide (150+20), and the third is 150px wide because it doesn't have a margin, thats the problem.
avoid #media if you mant it to be fully responsive and not jumping from 4 items a line to 1 item a linefor example.
you can solve your issue by simply adding a margin-right:20 to your last element, but it is better to to like so :
.inner1, .inner2, .inner3{
float: left;
width: 150px;
height: 150px;
margin: 2px 10px; //left & right sides to half of 20px
background-color: blue;
}
because it will split the margin to the two sides, making it more symetrical.
For laying out differently sized divs.
if all your divs can change size but stay equal, it will work, but if the first div is 70 and the 2nd and 3rd are 50, there will always be two divs on the bottom line at some point.
I think I've found the simplest solution to what I'm trying to do without having to use media queries. I simply added the right margin to all fields including the last field rather than adding it to every field except the final field.
I then wrap all the fields in another div and add a minus margin (the same size as the gaps) so that the fields will wrap when they hit the side of the container. Here's a fiddle with the solution: http://jsfiddle.net/rahg1ky3/
#outer {
width: 90%;
height: 90%;
margin: 5%;
overflow: auto;
background-color: red;
}
#inner {
margin-right: -20px;
}
.cont {
float: left;
width: 150px;
height: 150px;
margin-right: 20px;
background-color: blue;
}
<div id="outer">
<div id = "inner">
<div class="cont">1</div>
<div class="cont">2</div>
<div class="cont">3</div>
</div>
</div>
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/