Positioning a div at the bottom of a “absolute” <div> - html

I'm having troubles positioning my divs. I want to have my child div stick to the bottom of the parent div, with grandchild_1 and grandchild_2 staying correctly put. By that, I mean having grandchild_1 before grandchild_2, like on the picture.
This is what I've tried, but the "child" div sticks to the top :
#parent {
position: relative;
}
#child {
position: absolute; bottom: 0;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">
</div>
<div id="grandchild_2">
</div>
</div>
</div>
Anyone knows how I should proceed ? Thanks !

If you specify a height on the parent it will stick to the bottom.
Example: http://codepen.io/anon/pen/wGqzVd
HTML
<div id="parent">
Parent
<div id="child">
Child
<div id="grandchild_1">
Grandchild 1
</div>
<div id="grandchild_2">
Grandchild 2
</div>
</div>
</div>
CSS
div {
padding: 5px;
}
#parent {
position: relative;
background: lightgray;
height: 200px;
width: 150px;
}
#child {
position: absolute;
bottom: 5px;
background: yellow;
}
#grandchild_1 {
background: pink;
}
#grandchild_2 {
background: lightblue;
}

The provided code works as is...assuming that the parent has a height greater than that of the child.
#parent {
position: relative;
height: 200px;
background: pink;
}
#child {
position: absolute;
width: 100%;
bottom: 0;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>
As an alternative to positioning, flexbox can do the same...and the child will affect the height of the parent which an absolutely positioned child cannot.
#parent {
position: relative;
height: 200px;
background: pink;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
#child {
width: 100%;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>

Related

Visible overflow on X axis, but auto/scroll on axis Y

To keep things neat and short:
https://jsfiddle.net/m53ockLu/
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-x: scroll;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally? I'm totally out of ideas, I thought that overflow-x & overflow-y should do the trick, but no dice.
Thank you very much for any help.
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally?
No.
I tried Ethan's suggestion and couldn't get the purple box to visibly overflow the scrollbar:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-y: scroll;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
I don't think the browser will let you overflow the scrollbar, I even put z-index, explicitly said to visibly overflow, played around with the position property etc.
Consider this example of letting the content dictate the size:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: max-content;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
background: green;
}
.first {
display: block;
height: 20px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
You made the parent div sidebar have overflow-x: scroll;, overflow-y: auto;. Instead, make each child have its own overflow properties instead of the parent.

Resume normal HTML flow after absolutely positioned div element

Is it possible to resume normal HTML after an absolutely positioned div element? I'm trying to use particle.js background in header div on top of which is child element (with some text only). Then from the end of parent div (particle-js div), I'd like normal HTML flow.
#parent {
position: absolute;
height: 200px;
width: 200px;
background-color: red;
}
#child {
position: relative;
left: 50px;
top: 50px;
height: 50px;
width: 50px;
background-color: green;
}
#after-parent {
background-color: blue;
}
<div id="parent">
<p>Parent div</p>
</div>
<div id="child">
<p>child div</p>
</div>
<div id="after-parent">
<h1>Normal HTML flow after parent div</h1>
</div>
You can wrap #parent and child inside another relative div e give it the height https://jsfiddle.net/f6phun8a/2/
#parent {
position: absolute;
height: 200px;
width: 200px;
background-color: red;
}
#outer {
position: relative;
height: 200px;
}
#child {
position: relative;
left: 50px;
top: 50px;
height: 50px;
width: 50px;
background-color: green;
}
#after-parent {
background-color: blue;
}
<div id="outer">
<div id="parent">
<p>Parent div</p>
</div>
<div id="child">
<p>child div</p>
</div>
</div>
<div id="after-parent">
<h1>Normal HTML flow after parent div</h1>
</div>
#flexwrap {
display:flex;
flex-direction:column;
}
#parent {
flex:0 0 200px;
position: absolute;
height: 200px;
width: 200px;
background-color: red;
}
#child {
flex:1;
position: relative;
margin-top: 200px;
margin-left: 50px;
height: 50px;
width: 50px;
background-color: green;
}
#after-parent {
flex:1;
background-color: blue;
}
<div id="flexwrap">
<div id="parent">
<p>Parent div</p>
</div>
<div id="child">
<p>child div</p>
</div>
<div id="after-parent">
<h1>Normal HTML flow after parent div</h1>
</div>
</div>

Second DIV on all remaining space

I want to create two divs, one under other without JS and with IE8 support.
Each has 100% width.
Each with relative or absolute positioning for nested layout.
Top div have height by content, not fixed (it is important) and bottom div on whole leftover space.
In my example bottom div is too short, how i can stretch it to bottom?
<html>
<head>
<style type="text/css"><!--
* {
padding: 1px;
margin: 0px;
border: solid 1px;
width: 100%;
}
#super {
position: absolute;
height: 100%;
}
#top {
position: relative;
}
#bottom {
position: relative;
top: 0px;
bottom: 0px;
}
--></style>
</head>
<body>
<div id="super">
<div id="top">top</div>
<div id="bottom">bottom</div>
</div>
</body>
</html>
You can use css table properties to create this layout.
HTML:
<div id="super">
<div id="top">
<div class="content">
top
</div>
</div>
<div id="bottom">
<div class="content">
bottom
</div>
</div>
</div>
Necessary CSS:
html,
body {
height: 100%;
}
#super {
height: 100%;
width: 100%;
display: table;
}
#super > div {
display: table-row;
}
#top {
background: green;
}
#bottom {
background: blue;
}
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
#super {
height: 100%;
width: 100%;
display: table;
}
#top {
background: green;
overflow: hidden;
height: 1%;
}
.content {
padding: 10px;
}
#bottom {
background: blue;
}
#super > div {
display: table-row;
}
<div id="super">
<div id="top">
<div class="content">
top
</div>
</div>
<div id="bottom">
<div class="content">
bottom</div>
</div>
</div>
Output Image:
You can use display: table for wrapping container and table-row for top and bottom divs:
* {
padding: 1px;
margin: 0px;
border: solid 1px;
width: 100%;
}
#super {
display: table;
position: absolute;
height: 100vh;
}
#top {
display: table-row;
height: 1px;
position: relative;
background: orange;
}
#bottom {
display: table-row;
position: relative;
top: 0px;
bottom: 0px;
background: teal;
}
<div id="super">
<div id="top">top<br>top text</div>
<div id="bottom">bottom</div>
</div>
Use flex-box
.parent{
display: flex;
flex-direction: column;
min-height: 100vh
}
.child2{
flex: 1;
background: blue;
}
<div class="parent">
<div class="child1"> first child</div>
<div class="child2"> second child</div>
</div>
Demo here
Try this :
#bottom {
position: relative;
top: 0px;
bottom: 0px;
HEIGHT: 800px;
}

Positioning the content of a div on another div

I don't understand why the float: right doesn't work on the other box.
Anyone who can help me about this?
This is my code:
.main-box {
height: 400px;
width: 400px;
position: relative;
background: black;
}
.right-box {
float: right;
width: 100px;
height: 100px;
background: red;
}
.left-box {
width: 100px;
height: 100px;
background: red;
}
.bottom-boxes {
position: absolute;
bottom: 0;
}
<div class="main-box">
<div class="top-boxes">
<div class="right-box"></div>
<div class="left-box"></div>
</div>
<div class="bottom-boxes">
<div class="right-box"></div>
<div class="left-box"></div>
</div>
</div>
This is the resulting image of my code:
This is the resulting image I want to achieve:
Because of position: absolute on bottom-boxes so you need to add width: 100%
.main-box {
height: 400px;
width: 400px;
position: relative;
background: black;
}
.right-box {
float: right;
width: 100px;
height: 100px;
background: red;
}
.left-box {
width: 100px;
height: 100px;
background: red;
}
.bottom-boxes {
position: absolute;
bottom: 0;
width: 100%;
}
<div class="main-box">
<div class="top-boxes">
<div class="right-box"></div>
<div class="left-box"></div>
</div>
<div class="bottom-boxes">
<div class="right-box"></div>
<div class="left-box"></div>
</div>
</div>
But here is better solution using flexbox
.main-box {
height: 200px;
width: 200px;
display: flex;
flex-direction: column;
justify-content: space-between;
background: black;
}
.row {
display: flex;
justify-content: space-between;
}
.box {
width: 50px;
height: 50px;
background: red;
}
<div class="main-box">
<div class="row">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="row">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
Here's a working fiddle
When you put absolute position on a container, you have to specify also top, right and left property with bottom property to set a width and a height of it.
.bottom-boxes{
position:absolute;
bottom: 0;
left: 0;
right: 0;
}
In this case, left: 0; and right: 0; are equivalent to width: 100%; and top: 0 and bottom: 0; are equivalent to height: 100%;
When you don't specify a value, by default it's "auto;"
float won't work on an absolutely positioned element - you need to give top or bottom and right or left parameters to it (the default setting is top: 0; and left: 0;, i.e. the upper left corner of the parent element).

One div dynamic height one div remaining height and scroll

I have 2 divs inside a parent:
<div class="parent">
<div class="foo1"></div>
<div class="foo2"></div>
</div>
foo1 will have a dynamic height, so I can't use the style below:
height: calc(100% - foo1Height);
Now, what I want to do is make sure that the lower child foo2 never expands outside of the parent div, and to show the scrollbar if it gets too big. I would prefer CSS only solutions.
You can either use flexbox. no markup changes.
.parent {
display: flex;
flex-direction: column;
height: 100px;
}
.foo2 {
flex: 1; /*expand to fit*/
background: silver;
overflow: auto; /*scroll as needed*/
}
<div class="parent">
<div class="foo1">1</div>
<div class="foo2">2<br>2<br>2<br>2<br>2<br>2<br>2<br>2</div>
</div>
Or use CSS table, additional markup is required.
.parent {
display: table;
width: 100%;
height: 100px;
}
.foo1, .foo2 {
display: table-row;
}
.cell {
display: table-cell;
position: relative;
}
.foo2 {
height: 100%; /*expand to fit*/
background: silver;
}
.scroll {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto; /*scroll as needed*/
}
<div class="parent">
<div class="foo1">
<div class="cell">1</div>
</div>
<div class="foo2">
<div class="cell">
<div class="scroll">2<br>2<br>2<br>2<br>2<br>2<br>2<br>2</div>
</div>
</div>
</div>