100% height for div inside another div with margins - html

I have a div inside a div. The CSS/HTML is below. I am trying to figure out how to make the inner div have true height: 100%; with no overflow and what not. No matter what I try the border of the inner div gets cropped because of the outer div's overflow: hidden.
For reasons I cannot modify the content or style of either divs. I can, however, wrap the inner div in other divs if needed. This is not done through JavaScript which is why I cannot modify the outer or inner divs.
Also, this has to work in IE8.
The outer div style won't change much -- only the width, height, background-color, and margin.
The inner div could be anything. It could have a bigger border, it could have no border, it could be who knows what.
#outer
{
width: 200px;
height: 200px;
background-color: yellow;
margin: 20px;
overflow: hidden;
position: absolute;
}
#wrapper
{
height: 100%;
}
#inner
{
border: 1px solid red;
height: 100%;
}
<div id="outer">
<div id="wrapper">
<div id="inner">
a
</div>
</div>
</div>

You can use css flex property for #wrapper
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#outer
{
width: 200px;
height: 200px;
background-color: yellow;
margin: 20px;
overflow: hidden;
position: absolute;
}
#wrapper /* adding flex */
{
display: flex;
flex-flow: column;
height: 100%;
}
#inner
{
border: 1px solid red;
height: 100%;
}
<div id="outer">
<div id="wrapper">
<div id="inner">
a
</div>
</div>
</div>
it will work on all latest browser but this won't work on IE8.

jsfiddle
change the #wrapper height to only 99% will solve the problem.
The reason why the inner is getting cut off because:
#inner {
height: 100%; //this means it equals to 200px
border: 1px solid red; //1px at the top border and 1px at the bottom added to the height of the #inner so now it becomes 202px, which will get cut off by overflow:hidden
}

Related

Can this double inner scroll table be done with CSS only?

To better explain the situation. I've made a quick image to explain:
Basically, this seems paradoxical and I'm not sure if it can be done through CSS only.
The left and right columns can be scrolled vertically at the same time while the header stays fixed on top and NEVER scrolls vertically.
The right column can be scrolled horizontally WHILE also scrolling the left column HEADER horizontally.
Also note, that all this needs to be inside a <div> so I can't use position: sticky, which only works based on the browser window. The table has a fixed height and the browser window doesn't have a scroll.
Here is my attempt:
* {
box-sizing: border-box;
}
.columns {
width: 796px;
border: 2px solid green;
height: 200px;
overflow-y: scroll;
display: flex;
}
.left-col {
width: 200px;
border: 2px solid yellow;
}
.right-col {
width: 600px;
height: 200px;
border: 2px solid brown;
overflow-y: auto;
overflow-x: auto;
}
.filler-y {
height: 1200px;
width: 10px;
background-color: red;
}
.filler-both {
width: 2000px;
height: 2000px;
background-color: red;
}
<div class="columns">
<div class="left-col">
leftcol
<div class="filler-y"></div>
</div>
<div class="right-col">
right col
<div class="filler-both"></div>
</div>
</div>
View on jsFiddle

The scrollable height is ignoring the bottom margin of the last child of a scrollable div in Safari/Chrome

.scroll {
border: 1px solid black;
width: 200px;
height: 200px;
overflow: scroll;
background-color: yellow;
}
.inner {
height: 100%;
}
.content {
height: 100%;
margin: 50px 0;
background-color: red;
}
<div class="scroll">
<div class="inner">
<div class="content">
</div>
</div>
</div>
Fiddle
The above snippet consists of a scrollable div of size 200px. Inside that is an element with height 100%, and inside that is another element with height 100% but with top and bottom margin of 50px.
I would expect that the scrollable height of the div would be 50 + 200 + 50 = 300px. Indeed, this is the case in Chrome and Firefox where you can see the top and bottom yellow margin when you scroll the div, but for some reason Safari clips the bottom margin and the scrollable height is only 50 + 200 = 250px.
Who is correct here? Is this a Safari bug? Is there an easy fix for this without changing the overall structure of the page too much?
Adding overflow: auto; to your div.inner seems to solve the problem in Safari.
.scroll {
border: 1px solid black;
width: 200px;
height: 200px;
overflow: scroll;
background-color: yellow;
}
.inner {
height: 100%;
overflow: auto;
}
.content {
height: 100%;
margin: 50px 0;
background-color: red;
}
<div class="scroll">
<div class="inner">
<div class="content">
</div>
</div>
</div>

Position fixed and width 25% not taking correct width

I have two divs. outer div taking 25%. And the inner div is placed at the bottom (position: fixed; bottom: 0; width: 25%; border-top: 1px solid red) But this is not taking 25%.
I am adding border for this div. So there is an white space is showing because of the width.
HTML:
<div id="main-div">
<div id="outer-div">
<div id="div-1"></div>
<div id="div-2">
<div id="inner-div"></div>
</div>
</div>
</div>
CSS:
#main-div{
height: 100%;
width: 100%;
display: table;
}
#outer-div {
width: 100%;
}
#div-1, #div-2 {
width: 100%;
}
#inner-div {
position: fixed;
bottom: 0; width: 25%;
border-top: 1px solid red;
}
How to apply exactly apply 25% width to inner-div which has position fixed ?
UPDATE Added js fiddle in comment
Remove your body margin . This issue because of you don't remove your body margin you can simply fix this
body {
margin:0;
}
body {
margin:0;
}
#main-div{
height: 100%;
width: 100%;
display: table;
}
#outer-div {
width: 100%;
}
#div-1, #div-2 {
width: 100%;
}
#inner-div {
position: fixed;
bottom: 0; width: 25%;
border-top: 1px solid red;
}
<body>
<div id="main-div">
<div id="outer-div">
<div id="div-1"></div>
<div id="div-2">
<div id="inner-div"></div>
</div>
</div>
</div>
</body>
The real reason why inner-div has more width than outer-div is because inner-div has position: fixed applied to it.
Now when you apply position: fixed, it makes the element position relative to the viewport.
So, in this case inner-div is relative to the body which has some user-agent margin styles applied. To make them have same width apply margin: 0 to the body.
Also, apply box-sizing: border-box to outer-div to exclude the border in the width.
I have updated the fiddle for you. So both divs have the same width.
https://jsfiddle.net/nashcheez/uur2h5w3/4/
Fixed position is relative to the browser window hence percentage values will be relative to the <html> element (http://www.w3schools.com/cssref/pr_class_position.asp). Although experimental position:sticky might accomplish what you need since it is relative to the viewport (parent relative element).
You can use below css for this
#inner-div {
box-sizing: border-box;
}
You can check updated fiddle
You need to reset body for browser. For this reason "inner-div" is taking space.
body{margin:0;padding:0;}
body{margin:0;padding:0;}
#main-div{
height: 100%;
width: 100%;
display: table;
background: blue none repeat scroll 0 0;
border: 1px solid blue;
}
#outer-div {
width: 25%;
border: 1px solid green;
}
#div-1 {
width: 100%;
}
#div-2 {
display: table;
height: 0;
padding-right: 2px;
width: 100%;
}
#inner-div {
text-align: center;
position: fixed;
bottom: 0;
width: 25%;
border-top: 1px solid red;
padding-bottom: 27px;
padding-top: 10px;
}
<div id="main-div">
<div id="outer-div"> //list
<div id="div-1"> //parent-scrol
<div id="div-2"> //scroll
<div id="div-3"> //inner-list
<div id="inner-div">wefffef</div> //create-new
</div>
</div>
</div>
</div>
</div>

CSS background color for child container extending till parent container

Need background color for child container extending till width of view point. Properties needed should be applied to child container only.
I tried giving huge border to child container till parent container, but it did not work in high resolution screens.
Background color should applied only to the area of text.
.outer{
height: auto;
border: 1px solid red;
width: 420px;
}
.inner{
margin-left: 100px;
margin-right: 100px;
width: 200px;
height: 300px;
border: 1px solid green;
}
<div class="outer">
<div class="inner">Need background color for child container extending till width of view point. properties needed have to be given only within child container.
</div>
</div>
Here is the jsfiddle link to better understand the scenario:
https://jsfiddle.net/5qp1a3um/
You can set a wrapper to contain the desired color like this:
.bg-wrapper{
background: #54BCDF; /*change to desired color*/
}
.outer {
height: auto;
border: 1px solid red;
width: 420px;
margin: 0 auto;
}
.inner {
margin-left: 100px;
margin-right: 100px;
width: 200px;
height: 300px;
border: 1px solid green;
}
<div class="bg-wrapper">
<div class="outer">
<div class="inner">Need background color for child container extending till width of view point. properties needed have to be given only within child container.</div>
</div>
</div>
Bearing in mind that you can only change the css of child container you can try with this modification of the answer of Rick to extend the background:
.outer{
height: auto;
border: 1px solid red;
width: 420px;
}
.inner{
margin-left: 100px;
margin-right: 100px;
width: 200px;
height: 300px;
border: 1px solid green;
}
.inner:before {
content: '';
background: #54BCDF; /*change to desired color*/
position: absolute;
width: 100%;
height: 300px;
left: 0;
z-index: -1;
}
<div class="outer">
<div class="inner">
Need background color for child container extending till width of view point. properties needed have to be given only within child container.
</div>
</div>
But to center .outer I'm afraid that you'll have to add the style margin: 0 auto
Set the parent's position to relative:
.outer {
position: relative;
}
Then create a pseudo-element on the child, which covers the extent of the parent (width and height 100%).
Give it a negative z-index so its background won't hide the content:
.inner:before {
content: '';
background: lightgreen;
position: absolute;
width: 100%;
height: 100%;
left: 0;
z-index: -1;
}
Fiddle 1
Update based on the fact that you can't style the parent
Set the child's position to relative:
.inner {
position: relative;
}
The pseudo-element's width should now be 100% plus the difference between the child's and parent's widths.
You'll need to move the pseudo-element left to account for the child's left margin:
.inner:before {
content: '';
background: lightgreen;
position: absolute;
height: 100%;
width: calc(100% + 220px); /* parent's width - child's width = 220 */
left: -100px; /* account for left margin */
z-index: -1;
}
Fiddle 2
Not completely sure if I understand what you are trying to do, but I gave it a shot.
In the CSS if you change the margin to padding, then any background color on the child element will extend to the parent. background color is includes the padding but not the margin.
I also had to bump up the width of the child 20px for it to fill properly.
Updated fiddle: https://jsfiddle.net/5qp1a3um/1/
.inner{
padding-left: 100px;
padding-right: 100px;
background-color: blue;
width: 220px;
height: 300px;
border: 1px solid green;
}
Use padding instead of margin, that's the right way to do it.
padding: 0 100px;
https://jsfiddle.net/5qp1a3um/2/

How to make child divs always fit inside parent div?

Is there a way, without using JavaScript, to cause child divs to extend to the borders of their parent, without exceeding those borders, when you cannot know beforehand the size of the parent div?
Below is a sample markup/style demonstrating my issue. If you load it into a browser, you will see that #two and #three extend outside their parent, #one, and cause scrollbars to appear.
My issue is not so much the scrollbars but that I need to learn how to tell the child divs to occupy the width or height remaining to them rather than the full height or width of the parent.
<html>
<head>
<style>
html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:100%;height:100%;}
#two {width:100%;height:50px;}
#three {width:100px;height:100%;}
</style>
</head>
<body>
<div id="one" class="border">
<div id="two" class="border margin"></div>
<div id="three" class="border margin"></div>
</div>
</body>
</html>
I had a similar problem, but in my case, I have content in my div that height-wise will exceed the boundaries of the parent div. When it does, I want it to auto-scroll. I was able to accomplish this by using
.vscrolling_container { height: 100%; overflow: auto; }
you could use display: inline-block;
hope it is useful.
In your example, you can't: the 5px margin is added to the bounding box of div#two and div#three effectively making their width and height 100% of parent + 5px, which will overflow.
You can use padding on the parent Element to ensure there's 5px of space inside its border:
<style>
html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
#one {padding:5px;width:500px;height:300px;}
#two {width:100%;height:50px;}
#three {width:100px;height:100%;}
</style>
EDIT: In testing, removing the width:100% from div#two will actually let it work properly as divs are block-level and will always fill their parents' widths by default. That should clear your first case if you'd like to use margin.
There are two techniques commonly used for this:
Absolute Positioning
Table Styles
Given the HTML you provided here is the solution using Absolute positioning:
body #one {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: auto;
height: auto;
}
body #two {
width: auto;
}
body #three {
position: absolute;
top: 60px;
bottom: 0;
height: auto;
}
<html>
<head>
<style>
html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:100%;height:100%;}
#two {width:100%;height:50px;}
#three {width:100px;height:100%;}
</style>
</head>
<body>
<div id="one" class="border">
<div id="two" class="border margin"></div>
<div id="three" class="border margin"></div>
</div>
</body
You can always just use the table, tr, and td elements directly despite common criticisms as it will get the job done. If you prefer to use CSS there is no equivalent for colspan so you will likely end up with nested tables. Here is an example:
html, body {
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
#one {
box-sizing: border-box;
display: table;
height: 100%;
overflow: hidden;
width: 100%;
border: 1px solid black;
}
#two {
box-sizing: border-box;
display: table;
height: 50px;
padding: 5px;
width: 100%;
}
#three {
box-sizing: border-box;
display: table;
height: 100%;
padding-bottom: 60px;
padding-left: 5px;
}
#four {
display: table-cell;
border: 1px solid black;
}
#five {
display: table-cell;
width: 100px;
border: 1px solid black;
}
#six {
display: table-cell;
}
<html>
<div id="one">
<div id="two">
<div id="four"></div>
</div>
<div id="three">
<div id="five"></div>
<div id="six"></div>
</div>
</div>
</html>
For width it's easy, simply remove the width: 100% rule. By default, the div will stretch to fit the parent container.
Height is not quite so simple. You could do something like the equal height column trick.
html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:500px;height:300px; overflow: hidden;}
#two {height:50px;}
#three {width:100px; padding-bottom: 30000px; margin-bottom: -30000px;}
you could use inherit
#one {width:500px;height:300px;}
#two {width:inherit;height:inherit;}
#three {width:inherit;height:inherit;}
Make sure the outermost div has the following CSS properties:
.outer {
/* ... */
height: auto;
overflow: hidden;
/* ... */
}
I think I have the solution to your question, assuming you can use flexbox in your project. What you want to do is make #one a flexbox using display: flex and use flex-direction: column to make it a column alignment.
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.border {
border: 1px solid black;
}
.margin {
margin: 5px;
}
#one {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
#two {
height: 50px;
}
#three {
width: 100px;
height: 100%;
}
<html>
<head>
</head>
<body>
<div id="one" class="border">
<div id="two" class="border margin"></div>
<div id="three" class="border margin"></div>
</div>
</body>
</html>
If I've understood you correctly, the easiest method is to float the children. For example:
#one { width: 500px; height: 1%; overflow: hidden; background: red; }
#two { float: left; width: 250px; height: 400px; background: aqua; }
#two { float: left; width: 250px; height: 200px; background: lime; }
Setting a dimension (height/width) and overflow to auto or hidden on the parent element causes it to contain any floated child elements.
Note that overflow:hidden; can occasionally cause problems with content getting cut off, in which case you might want to try this alternative method:
http://www.positioniseverything.net/easyclearing.html
For closure, I think the answer to this question is that there is no solution. The only way to get the behavior I want is with javascript.
If you want the child divs to fit the parent size, you should put a margin at least of the size of the child borders on the child divs (child.margin >= child.bordersize).
For this example, just remove the width:100%; and the height:100% in #one and remove the width:100% in #two. It should be something like this:
html, body {width:100%; height:100%; margin:0; padding:0;}
.border {border:1px solid black;}
.margin {margin:5px;}
\#one {}
\#two {height:50px;}
\#three {width:100px; height:100%;}