Glue div to bottom of other div (not bottom of window) - html

So I want a div to always be on the bottom of another div it's in.
I've used bottom:0, position: absolute. This works as long as the window is the same size as the main div (which is the size of the windows too), but the main div has a min-height set, when the window gets smaller then this height the div start moving up with the bottom of the window.
vertical-align also doesn't work for this purpose as it glues it to the bottom of the other divs in the main div, but that results in it not being in the bottom of the main div, which is my goal.
How can I achieve this?

You can use flexbox for that:
.parent {
width: 50%;
height: 200px;
border: 1px solid grey;
margin: 1em auto;
display: flex;
flex-direction: column;
align-items: center;
}
.child {
width: 60%;
height: 50px;
background: rebeccapurple;
margin-top: auto;
}
<div class="parent">
<div class="child"></div>
</div>

From my understanding, you want to make sure that a div is always anchored to the bottom of a div, no matter what. In that case, all you need to do is make sure that the parent div has position:relative, while the child has position: absolute and is absolutely positioned to the bottom of the div.
Screen size shouldn't affect this, even if the parent div has a min-height.
But if I'm off, if you post your code, we may be able to better help.
HTML
<div class="parent">
<div class="child"></div>
</div>
CSS:
<style>
.parent {
position: relative;
min-height:--px
}
.child {
position: absolute;
bottom: 0;
}

Related

Positioning full-height absolute element inside relative one

Please help me to solve the quest. We have 3 div blocks. Height of the first div set to 100px (but in real world it's dynamic value). Second block has fixed height, and has another block as a child. The child block should have height stretched down to the bottom of the screen. But since our second block is relative, bottom:0 will mean bottom of the second block. What is the best practice for such cases, pure CSS please?
body > div { height: 100px; }
.first { background: lightblue; }
.second {
background: lightgreen;
position: relative;
}
.second div {
position: absolute;
background: pink;
width: 50%;
height: 200px;
top: 100px;
}
<div class="first">The height of the block may vary greately.</div>
<div class="second">
<div>This DIV should take whole free space to the bottom of the screen.</div>
</div>
UPD:
I can achieve the effect by wrapping second div into additional div (width position absolute and bottom: 0) and leave it with transparent background, but then static content "behind it" become unusable. Here is an example.
This is based on your update fiddle, since it's not that clear what you wish to achieve but you mentioned this example was close, I made your link to be above with z-index so it's clickable:
Check external Fiddle, embedded seems to break bottom
body > div { height: 100px; }
.first { background: lightblue; }
.second {
background-color: lightgreen;
top: 100px;
}
.second >div {
background: pink;
width: 50%;
height: 100%;
}
<div class="first">The height of the block may vary greately.</div>
<div class="second">
<div>This DIV should take whole free space to the bottom of the screen.</div>
</div>

Get div outside parent div without position absolute

I've got a little css problem.
I got a div with a max-width. In this div there is a img that needs to be positioned outside his div (to the bottom). Unfortunately I can't use position absolute because of the max-width. When I would use position absolute, at some point the width of the screen reaches the max-width and the img with position absolute will go outside the div on the right side.
I know this must sound a little messy, so I've made a Jsfiddle:
https://jsfiddle.net/te93s8h1/
This JS Fiddle shows a example of the issue I got. I need the green block outside the div (at the bottom) but the green block can not go outside the div on the right side. How can I achieve this?
I prefer css only.
Never mind my question, I think I understand what you're trying to achieve. You should add a position: relative; statement to the style block of your .grid class as demonstrated in this JSFiddle.
Just simply try this without using position absolute.
.container {
background-color: #00f;
width: 98%;
height: 100px;
margin: auto;
max-width: 1300px;
}
.grid {
position: relative; /* Added Position */
background-color: #f00;
width: 50%;
margin: auto;
min-width: 600px;
height: 100px;
}
.block_outside_div {
position: inherit; /* Added Position */
background-color: #0f0;
height: 50px;
width: 50px;
left: 45%; /* 45% Percentage value for move from left */
top: 120px; /* 120px value for move from top */
}
<div class="container">
<div class="grid">
<div class="block_outside_div">
</div>
</div>
</div>

Css: Position element by it's bottom relative to it's container's top

I have an div element with variable height which I need to be positioned by it's bottom relative to the containers top.
This must be done without changing the html.
e.g.
<div id="container">
<h1>Some Text<br/>more...</h1>
</div>
h1's bottom should be 100px below #container's top.
Thanks a lot
EDIT:
So by Request what I did (or didn't) tried:
Searching with Google for css bottom top position relative but that's not the best search terms in the world...
Normally I would put a container around h1 and give it a height of 100px but then I would need to change the html and that I can't
using bottom: somevalue but that positions the element's bottom relative to the container's bottom.
slain some vampires
You could make use of transform: translateY(-100%), to make the bottom of the element relative when you apply margin-top: 100px to h1.
#container {
width: 200px;
height: 200px;
background: tan;
overflow: hidden;
}
#container h1 {
transform: translateY(-100%);
margin-top: 100px;
background: papayawhip
}
<div id="container">
<h1>Some Text<br/>more...</h1>
</div>
Depending on browser support requirements:
#container {
position: relative;
}
#container h1 {
position: absolute;
bottom: calc(100% - 100px);
}
Example
Only way through it is to add a height to the h1 unless you want to go with calc which isn't supported yet by some browsers. Then set your top margin to be top: 100px - h1's height. Hope this works
<div id="container">
<h1>Some Text<br/>more...</h1>
</div>
#container {
width: 300px;
height: 300px;
background: #222;
overflow: hidden;
}
#container h1 {
background: #444;
position:relative;
height:80px;
top:20px;
}
http://jsfiddle.net/ms889w57/
#container
{
position: absolute;
height: 100px;
bottom:0px;
}
This code is not affecting html at all. I added css for id-container.
An absolute position element is positioned relative to the first parent element that has a position other than static. You can change it to fixed it you wants to.
Height of the container, help you to calculate spacing from bottom.

Position div tag at the bottom right of an image

I am trying to position an div element at the bottom right of an image, that is inside a container element. I set position relative to the container, and position absolute to the inner div, but it does not work. Here is the (http://jsfiddle.net/ZC84G/). Please, help.
<div class="container">
<div class="icon"></div>
<img src="/images/someImage.png" />
</div>
CSS:
body {
background-color: black;
}
.container {
position: relative;
}
.container img {
max-width: 75%;
max-height: 80%;
}
.icon{
background-image: url('http://icons.iconarchive.com/icons/iconfactory/star-wars-lego/32/Biggs-No-Helmet-icon.png');
width: 31px;
height: 31px;
position: absolute;
bottom: 5px;
right: 5px;
}
This is because by default div has block display mode, and it's width is 100% of the parent container. Try to add display: inline to .container
.container {
position: relative;
display: inline;
}
Here's the corrected jsfiddle: http://jsfiddle.net/ZC84G/4/
Your container div has no width and height set. And since a <div> is a block-level element by default, it will be set to 100% width ie expand to however much horizontal space is left.
Plus, you're also constraining your image size:
max-width: 75%;
max-height: 80%;
If you replace the img CSS with:
max-width: 75%;
max-height: 80%;
It works fine, and as expected: http://jsfiddle.net/ZC84G/3/
I've modified your CSS on the image a bit.
Basically, I set it to scale properly to the size of its container, and now it sits where I think you wanted it. The way you could find this yourself in the future would be to inspect the element by using right click from your browser, and looking at the size of the different elements to see what was expanding larger/smaller than it should.
.container img {
max-width: 100%;
height: auto;
}

How to set the margin or padding as percentage of height of parent container?

I had been racking my brains over creating a vertical alignment in css using the following
.base{
background-color:green;
width:200px;
height:200px;
overflow:auto;
position:relative;
}
.vert-align{
padding-top:50%;
height:50%;
}
<!-- and used the following div structure. -->
<div class="base">
<div class="vert-align">
Content Here
</div>
</div>
While this seemed to work for this case, i was surprised that when i increased or decreased the width of my base div, the vertical alignment would snap. I was expecting that when I set the padding-top property, it would take the padding as a percentage of the height of the parent container, which is base in our case, but the above value of 50 percent is calculated as a percentage of the width. :(
Is there a way to set the padding and/or margin as a percentage of the height, without resorting to using JavaScript?
The fix is that yes, vertical padding and margin are relative to width, but top and bottom aren't.
So just place a div inside another, and in the inner div, use something like top:50% (remember position matters if it still doesn't work)
An answer to a slightly different question: You can use vh units to pad elements to the center of the viewport:
.centerme {
margin-top: 50vh;
background: red;
}
<div class="centerme">middle</div>
Here are two options to emulate the needed behavior. Not a general solution, but may help in some cases. The vertical spacing here is calculated on the basis of the size of the outer element, not its parent, but this size itself can be relative to the parent and this way the spacing will be relative too.
<div id="outer">
<div id="inner">
content
</div>
</div>
First option: use pseudo-elements, here vertical and horizontal spacing are relative to the outer. Demo
#outer::before, #outer::after {
display: block;
content: "";
height: 10%;
}
#inner {
height: 80%;
margin-left: 10%;
margin-right: 10%;
}
Moving the horizontal spacing to the outer element makes it relative to the parent of the outer. Demo
#outer {
padding-left: 10%;
padding-right: 10%;
}
Second option: use absolute positioning. Demo
#outer {
position: relative;
}
#inner {
position: absolute;
left: 10%;
right: 10%;
top: 10%;
bottom: 10%;
}
To make the child element positioned absolutely from its parent element you need to set relative position on the parent element AND absolute position on the child element.
Then on the child element 'top' is relative to the height of the parent. So you also need to 'translate' upward the child 50% of its own height.
.base{
background-color: green;
width: 200px;
height: 200px;
overflow: auto;
position: relative;
}
.vert-align {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
<div class="base">
<div class="vert-align">
Content Here
</div>
</div>
There is another a solution using flex box.
.base{
background-color:green;
width: 200px;
height: 200px;
overflow: auto;
display: flex;
align-items: center;
}
<div class="base">
<div class="vert-align">
Content Here
</div>
</div>
You will find advantages/disavantages for both.
This can be achieved with the writing-mode property. If you set an element's writing-mode to a vertical writing mode, such as vertical-lr, its descendants' percentage values for padding and margin, in both dimensions, become relative to height instead of width.
From the spec:
. . . percentages on the margin and padding properties, which are always calculated with respect to the containing block width in CSS2.1, are calculated with respect to the inline size of the containing block in CSS3.
The definition of inline size:
A measurement in the inline dimension: refers to the physical width (horizontal dimension) in horizontal writing modes, and to the physical height (vertical dimension) in vertical writing modes.
Example, with a resizable element, where horizontal margins are relative to width and vertical margins are relative to height.
.resize {
width: 400px;
height: 200px;
resize: both;
overflow: hidden;
}
.outer {
height: 100%;
background-color: red;
}
.middle {
writing-mode: vertical-lr;
margin: 0 10%;
width: 80%;
height: 100%;
background-color: yellow;
}
.inner {
writing-mode: horizontal-tb;
margin: 10% 0;
width: 100%;
height: 80%;
background-color: blue;
}
<div class="resize">
<div class="outer">
<div class="middle">
<div class="inner"></div>
</div>
</div>
</div>
Using a vertical writing mode can be particularly useful in circumstances where you want the aspect ratio of an element to remain constant, but want its size to scale in correlation to its height instead of width.
Other way to center one line text is:
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
line-height: 0;
}
or just
.parent{
overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}
.child{
margin-top: 50%;
line-height: 0;
}
This is a very interesting bug. (In my opinion, it is a bug anyway) Nice find!
Regarding how to set it, I would recommend Camilo Martin's answer. But as to why, I'd like to explain this a bit if you guys don't mind.
In the CSS specs I found:
'padding'
Percentages: refer to width of containing block
… which is weird, but okay.
So, with a parent width: 210px and a child padding-top: 50%, I get a calculated/computed value of padding-top: 96.5px – which is not the expected 105px.
That is because in Windows (I'm not sure about other OSs), the size of common scrollbars is per default 17px × 100% (or 100% × 17px for horizontal bars). Those 17px are substracted before calculating the 50%, hence 50% of 193px = 96.5px.
A 50% padding wont center your child, it will place it below the center. I think you really want a padding-top of 25%. Maybe you're just running out of space as your content gets taller? Also have you tried setting the margin-top instead of padding-top?
EDIT: Nevermind, the w3schools site says
% Specifies the padding in percent of the width of the containing element
So maybe it always uses width? I'd never noticed.
What you are doing can be acheived using display:table though (at least for modern browsers). The technique is explained here.
CSS Grid with empty row
This approach probably only makes sense if you're already using css-grid for the container in question, but if you are you can create an empty row with a percentage that (because it is a row) will be a percentage of the height.
.wrapper
{
border: 2px solid red;
width: 400px;
height: 200px;
display: grid;
grid-template-rows: 10% 1fr;
}
.child
{
background: orange;
width: 50px;
height: 50px;
grid-area: 2/1;
}
<div class="wrapper">
<div class="child">
</div>
</div>