Set parent's (undefined width and height) dimension equal to child's - html

I have a parent div with undefined width or height.
The first child 'a' has set width and height. How can I make the parent have the size dimensions as the child.
.parent{
position: fixed;
background: green;
padding: 10px;
}
.child-a{
position:absolute;
width: 300px;
height:50px;
background: red;
}
.child-b{
width:100%;
height:120%;
background: blue;
}
<div class='parent'>
<div class='child-a'></div>
<div class='child-b'></div>
</div>
2nd part: I want the div 'c' to be 120% of the parent's height, and be positioned behind div 'a'. So only the bottom of 'c' is visible.
I've tried multiple solutions include display: table, overflow: overlay etc but nothing gives me the desired result. I'm looking for a CSS only solution.

function childSize () {
var parentHeight = document.getElementById( HAVE PARENTS ID HERE ).offsetHeight;
parentHeight = parentHeight / 100 * 120;
document.getElementById( HAVE CHILD C ID HERE ).offsetHeight = parentHeight;
}
This answer is only for the second part hope it helps :)

For height percentage to work, its parent has to have a height property too. See https://stackoverflow.com/a/16642908/5599288 . Therefore, the parent's height cannot be undefined or automatically sized.
You gotta set a fixed height on the parent, then control the child using percentage. This is how i would do it, in a pure CSS way,
https://codepen.io/jacobgoh101/pen/jZrvWw
.parent {
position: fixed;
background: green;
padding: 10px;
width: 300px;
height: 50px;
}
.child-a {
position: absolute;
background: red;
// set size, padding 10px and centering
width: calc(100% - 20px);
height: calc(100% - 20px);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.child-b {
width: 100%;
height: 120%;
background: blue;
}

Related

How to set the height of a div container having absolute positioned element

So basically I have a parent div element containing just one child div element.
Now I want to set the position of child div to absolute (for animation / page-transition effect). But on doing so, height of parent div element gets set to 0 which changes the whole layout which isn't desired.
How do I fix this to set height of parent div element to that of height of absolute positioned child div element
Here's how my that block of code looks
HTML
<div class='parent'>
<div class='child'></div>
</div>
CSS
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
}
Although stretching to elements with position: absolute is not possible, there are often solutions where you can avoid the absolute positioning while obtaining the same effect. Look at this fiddle that solves the problem in your particular case http://jsfiddle.net/gS9q7/
The trick is to reverse element order by floating both elements, the first to the right, the second to the left, so the second appears first.
.child1 {
width: calc(100% - 160px);
float: right;
}
.child2 {
width: 145px;
float: left;
}
Finally, add a clearfix to the parent and you're done (see the fiddle for the complete solution).
Generally, as long as the element with absolute position is positioned at the top of the parent element, chances are good that you find a workaround by floating the element.
One way you could do this is by setting a variable in CSS and using the variable on both the parent and child elements height and width.
html {
--height: 100px;
--width: 200px;
}
.parent {
position: relative;
border: 1px solid black;
height: var(--height);
width: var(--width);
}
.child {
position: absolute;
height: var(--height);
width: var(--width);
background: red;
top: 0;
}
<div class='parent'>
<div class='child'></div>
</div>
Another would be to use javascript to set the property of the parents width and height to that of the child elements.
const par = document.querySelector('.parent');
const child = document.querySelector('.child');
const getSetStyles = (p, c, arr) => {
const styleArr = {};
arr.map( a => styleArr[a] = getComputedStyle(c).getPropertyValue(a) );
Object.entries(styleArr).map( sArr => par.style.setProperty(sArr[0], `${sArr[1]}`) );
}
getSetStyles(par, child, ['width', 'height'])
html {
--height: 100px;
--width: 200px;
}
.parent {
position: relative;
border: 2px solid black;
}
.child {
position: absolute;
height: var(--height);
width: var(--width);
background: red;
top: 0;
}
<div class="parent">
<div class="child"></div>
</div>
I don't know if I have followed your question correctly, but please set a height for the parent then set the height of child to 100%
.parent {
position: relative;
height: 100px;
width: 100px;
}
.child {
position: absolute;
top: 0;
height: 100%;
width: 100%;
}

Can I make my div inherit height and position from one div and width from another?

I have a div (div1) inside some other divs. Now I want this div to have the same width as the body (take up full width of display), but always have the same height and position as its parent (div2). I've tried using position: absolute; on this div (div1). Then I can either
set body to position: relative; and have div1 take up 100% width, but now I'm having trouble making the height always follow div2.
or set the parent (div2) to position: relative; and have div 1 take up 100% height, but now I can't make it follow the width of body.
It would be cool if CSS had the option of saying:
.div1 {
height: 100%(.div2);
width: 100%(body);
position: 0(.div2);
}
Or something like that
JSFiddle with the relevant bits: https://jsfiddle.net/Hamleyburger/fqe5o46c/1/#&togetherjs=K02DaSO2nR
What I want is the div ".selectable" to have a div (inside?) that shows on hover and fits the heights of ".selectable" (parent) and the entire width of the body.
Extra, maybe relevant info:
I'm using Bootstrap and (Jinja2) templating. All the divs so far are taking their base widths from a wrapper container (.main) in my base template that I've set to be (responsively) narrower than body. If I were to remove .main
div I would have to set width on many individual divs. That would solve it (I could make all the divs that aren't div1 narrower), but it wouldn't be very DRY. I'm using SASS, if that helps.
It's possible to force a div to fill the whole viewport width using vw. It's a bit weird though:
body,
html {
margin: 0;
padding: 0;
}
.outer {
width: 300px;
height: 300px;
background-color: #eeeeee;
margin: 0 auto;
position: relative
}
.inner {
width: 100vw;
height: 100%;
background-color: rgba(0, 0, 0, 0.1);
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
<div class="outer">
<div class="inner"></div>
</div>
I'd recommend to make your outer div full width and give the inner one a specific width:
body,
html {
margin: 0;
padding: 0;
}
.outer {
width: 100%;
background-color: #eeeeee;
position: relative
}
.inner {
width: 300px;
height: 300px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.1);
}
<div class="outer">
<div class="inner"></div>
</div>

width: 100% of an absolute positioned element is bigger than the parent

I have a div with unknown width and height, this div is one of the children of a bigger div.
#myDiv {
/* Blah blah blah */
}
#inner {
position: absolute;
width: 100%;
height: 100%;
}
<div id="myDiv">
<div id="inner"></div>
</div>
But the problem is that the #inner div doesn't fit properly, it's way bigger than its parent #myDiv while its width and height are set to 100%.
What am I doing wrong?
By making any element position: absolute; means: place me to the first parent that is position: relative; which is not always equal to its parent element.
And if there are other children you need to remember that one of them will be places "under" the element posiotionated absolutely.
Accepted answer didn't solve it for me. Parent element was already position: relative;.
This is what worked for me:
In the child element, instead of using height:100% use top:0; bottom:0; to fill up height, and left:0; right:0; to fill width up.
.child {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
One reason an absolutely-positioned child element can stick out from its relatively-positioned parent is if the parent has padding.
Take the following example:
.parent {
position: relative;
padding: 50px;
width: 250px;
height: 50px;
margin: auto;
background-color: blue;
}
.child {
position: absolute;
width: 100%;
height: 100%;
background-color: #ff000099;
}
<div class="parent">
<div class="child"></div>
</div>
As you can see, the actual width and height of the child is the same as the parent, however since the parent has padding-top and padding-left, the child's content is placed after the parent's padding. This makes the child stick out at the bottom and the right.
There are different ways to handle this, depending on the desired outcome.
If you want the child to perfectly cover the parent, either use bets's solution and set the top, right, bottom and left attributes on the child instead of the width and height, or just keep the width and height at 100% and set top and left to 0, like this:
.parent {
position: relative;
padding: 50px;
width: 250px;
height: 50px;
margin: auto;
background-color: blue;
}
.child {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: #ff000044;
}
<div class="parent">
I am parent content
<div class="child">I am child content</div>
</div>
If you want the child to occupy all the space within the padding on the parent, you can use calc() to remove the parent's padding from the child div:
.parent {
position: relative;
padding: 50px;
width: 250px;
height: 50px;
margin: auto;
background-color: blue;
}
.child {
position: absolute;
width: calc(100% - 100px);
height: calc(100% - 100px);
background-color: #ff000099;
}
<div class="parent">
<div class="child"></div>
</div>
(Just remember to remove both the left and right padding from the child's width and the top and bottom from its height. That's why I am multiplying the padding by 2.)
Combining these, if you want the child to start after the top and left padding, but not stick out the right or bottom, only subtract the top and left paddings from the height and width of the child:
.parent {
position: relative;
padding: 50px;
width: 250px;
height: 50px;
margin: auto;
background-color: blue;
}
.child {
position: absolute;
width: calc(100% - 50px);
height: calc(100% - 50px);
background-color: #ff000099;
}
<div class="parent">
<div class="child"></div>
</div>

margin-top: 50% works strange

I would like to center a div both horizontally, and vertically. I tried to manage it like this:
div {
background: red;
width: 200px;
height: 200px;
position: absolute;
margin-top: 50%;
margin-left: 50%;
top: -100px;
left: -100px;
}
The margin-top xx% depends on the width of the page for some reason, not the height.
jsFiddle: http://jsfiddle.net/MxE8Y/embedded/result/
What do I wrong? How to fix it without using javascript?
the reason of vertical % related to parent's width:
The percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1.
http://www.w3.org/TR/CSS2/box.html#margin-properties
the answer of Hashem Qolami tells you what to do instead :)
Else, you can keep everything in the flow using display: (display:table) http://jsfiddle.net/MxE8Y/2/
body, html {
background: green;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display:table;
}
body {
display:table-cell;
vertical-align:middle;
}
div {
background: red;
width: 200px;
height: 200px;
margin:auto;
}
or http://codepen.io/anon/pen/iJgbv/ (display:flex) :
html,body {
height:100%;
width:100%;
margin:0;
}
body {
display:flex;
}
div {
width:100px;
height:100px;
background:gray;
margin:auto;
}
A percentage value for top/bottom padding/margin is relative to the width of box's containing block.
8.3 Margin properties: 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', and 'margin'
<percentage> The percentage is calculated with respect to the width
of the generated box's containing block. Note that this is true for
'margin-top' and 'margin-bottom' as well. If the containing block's
width depends on this element, then the resulting layout is undefined
in CSS 2.1.
Try using top and left properties for positioning the absolutely positioned element and use negative values on top/left margin:
EXAMPLE HERE
div {
background: red;
width: 200px;
height: 200px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
}
A 2016 option using the translate -50% method
css
div {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
}
fiddle
http://jsfiddle.net/Hastig/MxE8Y/6/

Is there a way to display a div with width in % and no content?

For example this div is displayed:
<div class="circle"></div
.circle {
width: 300px;
height: 300px;
background: red;
border-radius: 50%;
}
but when width and height are in % it collapses:
.circle {
width: 30%;
height: 30%;
background: red;
border-radius: 50%;
}
Is there a way to get it displayed?
This is because the div has no height. width: 30%; will always make the div 30% width of the parent (<body>, in this case), which is what you want. However, height behaves a little differently.
You need to specify a 100% height for body and html like so:
html,
body {
height: 100%;
}
Working Fiddle
You can read why height: 100%; behaves like that here
You need to declare a hard width/height somewhere, in this example I put a hard width/height on a container div:
http://jsfiddle.net/exrNm/1/
<div class="con">
<div class="circle"></div
</div>
.con{
width:300px;
height:300px
}
.circle {
width: 30%;
height: 30%;
background: red;
border-radius: 50%;
}
You could easily set a hard width somewhere up the parent chain. The % needs a hard value to calculate against.