How to make a relative div span its absolute content? - css

Very basic question here, but it has been puzzling me for hours:
How do I make a relatively positioned div span its absolutely positioned content?
http://jsfiddle.net/X6ay2/10/
HTML
<div class="outer">
<div class="inner"></div>
</div>
CSS:
.outer {
display: inline-block;
position: relative;
background: blue;
height: 100px;
padding: 20px;
}
.inner {
position: absolute;
width: 50px;
height: 50px;
background: red;
}

You can't directly really, as absolute positioned elements are out of the document flow and so don't really 'belong' to their parents anymore. A kind of workaround though is to set the absolute positioned div to 100% width and left:0, which will force it to extend to the width of the parent.
.outer {
display: inline-block;
position: relative;
background: blue;
height: 100px;
padding: 20px;
}
.inner {
position: absolute;
width: 100%;
left: 0;
height: 50px;
background: red;
}
http://jsfiddle.net/X6ay2/14/
A caveat to this is if the inner div has padding, it will extend beyond 100%. To stop this, make the inner div use the border-box box-sizing property.
.inner {
padding: 10px;
box-sizing: border-box;
-moz-box-sizing:border-box;
}
http://jsfiddle.net/X6ay2/15/

set width of the outer to suit your needs. The example has
width:50px
http://jsfiddle.net/X6ay2/12/

Related

why absolute element is involved in calculating size of overflow parent ?

There are lots of card to be showed and I need to show menu when I hover one of the cards.
I use position: absolute; for menu and use position: relative; for the card, but why the scrollbar appeared when I hover on the card ?
<!DOCTYPE html>
<html>
<head>
<style>
.box {
height: 240px;
width: 200px;
overflow: auto;
border: 1px dashed red;
}
.card {
height: 120px;
width: 120px;
border: 1px solid blue;
position: relative;
}
.menu {
display: none;
height: 400px;
width: 200px;
position: absolute;
top: 0;
left: 0;
background: linear-gradient(orange, pink);
}
.card:hover .menu {
display: block;
}
</style>
</head>
<body>
<div class="box">
<div class="card">
<div class="menu"></div>
</div>
</div>
</body>
</html>
The scrollbar has nothing to do with your positioning, it is a result of overflow: auto; on your .box element.
overflow: auto; will show a scrolling bar if a child element overflows its parent container where overflow: auto; is set.
Seeing as the .box parent-element has a fixed size value height: 240px; while its child element .menu has height: 400px;, it will cause a scrollbar to appear because there is an overflow of 160px.
While #Yong is correct with document flow in his answer with the position: absolute; property, seeing as you have fixed height and width on all your elements, position: absolute; doesn't actually do anything in this exact reproducible example.
If I understand your problem correctly, a simple solution to your problem if you want to keep the fixed width and height on your .box element, you can simply disable the scrollbar by applying display: none; to the .box pseudo-element ::-webkit-scrollbar.
(NOTE: As of February 28th, 2022 this is still not supported in Firefox).
Read more about browser support at https://caniuse.com/?search=%3A%3A-webkit-scrollbar
Example with no positioning properties & -::webkit-scrollbar
.box {
height: 240px;
width: 200px;
border: 1px dashed red;
overflow: auto;
}
.box::-webkit-scrollbar{
display: none;
}
.card {
height: 120px;
width: 120px;
border: 1px solid blue;
/*position: relative;*/
}
.menu {
display: none;
height: 400px;
width: 200px;
/*position: absolute;
top: 0;
left: 0;*/
background: linear-gradient(orange, pink);
}
.card:hover .menu {
display: block;
}
<!DOCTYPE html>
<html>
<body>
<div class="box">
<div class="card">
<div class="menu"></div>
</div>
</div>
</body>
</html>
If you want to remove overflow altogether, you can apply overflow: hidden; to .box.
Keep in mind the fixed height of 400px on the .menu element will not apply as the fixed height of 240px on the .box element will hide the remaining 160px. I hope this solves your problem, but a little more detail would help!
absolute
The element is removed from the normal document flow, and no space is
created for the element in the page layout. It is positioned relative
to its closest positioned ancestor, if any; otherwise, it is placed
relative to the initial containing block. -MDN
.menu is positioned absolute therefore it is positioned relative to .card which is the closes positioned ancestor to it.
relative
The element is positioned according to the normal flow of the
document, ... -MDN
And because .card is positioned relative it would still take space and position according to the normal flow of the document. Therefore, it would still be taken into consideration whether the .box or its parent would overflow or not.
with set position: absolute; for .menu and position: relative; for .card you able to change the position of .menu with top bottom left right properties relative to its first positioned (not static) ancestor element( .card position ).
but in your question, the absolute or relative position is not the cause of the scrollbar appear . The reason is the owerflow property .
the default value for owerflow is visible that create no owerflowing . And you created the scrollbar by setting it auto because the size of menu is larger than card.
.box {
height: 240px;
width: 200px;
/* overflow: auto; */
border: 1px dashed red;
}
.card {
height: 120px;
width: 120px;
border: 1px solid blue;
position: relative;
}
.menu {
display: none;
height: 400px;
width: 200px;
position: absolute;
top: 0;
left: 0;
background: linear-gradient(orange, pink);
}
.card:hover .menu {
display: block;
}
<div class="box">
<div class="card">
<div class="menu"></div>
</div>
</div>

Extend image to left such that it covers whole screen

Recently I have come across a problem for which I am not finding any appropriate solution.
Below is the image which gives an idea of what i am trying to achieve:
The div shown by the arrow is the mark of the problem which i am finding a solution for.
The problem is I want the div to be extended to full screen.
This div is inside a parent div who has a fixed width due to which i am not able to extend my image to full screen.
Have tried giving overflow to parent but isn't working.
I have tried below solution which is working to a certain extent but need a reliable solution.
width: 100%;
left: 0;
position: absolute;
margin-left: calc(-31.5vw);
align-content: center;
Could someone please provide some solution to this?
html, body
{width: 100%; height: 100%; overflow: hidden;}
#parent{
display: block;
background-color: yellow;
border: 1px solid red;
position: fixed;
width: 200px;
height:100%;
}
#child1{
background-color: red;
display: block;
border: 1px solid yellow;
position: absolute;
width: 100vw;
margin-left: calc(200px - 100%);
//top:0px
}
<div id="parent">parent with position: fixed
<div id="child1">child wrapper (uncomment top to fit the parent wrapper)</div>
</div>
use Viewport Sizes so it will cover the whole page (vw and vh)
#first {
width: 100px;
height: 100px;
background:gray;
position: fixed;
top: 0;
left: 0;
}
#second{
width: 100vw;
height: 100vh;
background:blue;
position:absolute;
}
<div id="first">
<div id="second">
something
</div>
</div>
The below code snippet should work, if I understand your question correctly. Setting the width of the child div to 100vw makes the div 100% of the width of the viewport (window).
Also note that in order to get the child to start at the left of the viewport and not the left of the parent, I gave the child a position of absolute and a left of 0. Because the parent is not positioned, it starts the left of the child at the left of the viewport (the closest positioned ancestor).
#parentDiv {
width: 250px;
height: 250px;
margin: 0 auto;
background-color: orange;
border: 2px solid red;
}
#childDiv {
/* 100vw is 100% of the viewport width. */
width: 100vw;
height: 50px;
background-color: lightblue;
box-sizing: border-box;
border: 2px solid green;
position: absolute;
left: 0;
}
p {
text-align: center;
}
<html>
<body>
<div id="parentDiv">
<p>Parent</p>
<div id="childDiv"><p>Child</p></div>
</div>
</body>
</html>

Position fixed 100 of parent

I'm in difficulty: I have a parent element that has a size that doesn't know. And I have an item that it must place permanently at the top of the body, then position: fixed, but I cann't because giving it width: 100%, is 100% of the body, but I want 100% of the parent element. How can I do?
Example: http://codepen.io/michele96/pen/jWbYQb
set .fixed's width as width: inherit; don't use 100%
body {
padding: 0;
margin: 0 auto;
}
.container {
position: relative;
width: 70%;
height: 1000px;
background: red;
}
.fixed {
position: fixed;
width: inherit; /*change here*/
line-height: 50px;
background: blue;
color: #f0f0f0;
text-align: center;
font-size: 20px;
}
<div class="container">
<div class="fixed">Navbar Fixed</div>
</div>
The problem is that, unlike absolutely positioned elements, the containing block of a fixedly positioned element is usually the viewport, not its nearest positioned element. Then, width: 100% is resolved with respect to the viewport width.
There are ways to change this behavior, e.g. elements with transform establish a containing block for their fixedly positioned descendants. But then your element won't be fixed at the top of the viewport.
Instead, you should use sticky positioning:
.fixed {
position: sticky;
top: 0;
}
body {
padding: 0;
margin: 0 auto;
}
.container {
width: 70%;
height: 1000px;
background: red;
}
.fixed {
position: sticky;
top: 0;
line-height: 50px;
background: blue;
color: #f0f0f0;
text-align: center;
font-size: 20px;
}
<div class="container">
<div class="fixed">Navbar Fixed</div>
</div>
Note it's not widely supported yet.
Set transform: translate3d(0, 0, 0); to the parent.

Why is my position:absolute <div> not positioned in relation to its parent?

I understand that if I wrap an outer div with a relative position around a div with an absolute position, then the absolute positioning of the inner div will be relative to the outer div (duh).
However when I do this:
<div class="outer">
<div class="inner"> </div>
</div>
CSS:
.outer {
margin: 0 auto;
padding: 20px;
width: 700px; }
.inner {
position: absolute;
text-decoration: none;
cursor: pointer;
bottom: 20px;
left: 5px;}
It makes the inner align with the browser window, not the relative div! I'm very stumped on this simple concept, I've been able to do this sort of thing before but I must be doing something wrong.
Here is the complete jsfiddle for you to see: http://jsfiddle.net/DDYUK/1/
.outer is never given the CSS property position:relative
.outer {
position: relative;
margin: 0 auto;
padding: 20px;
width: 700px;
}
If you do not apply position:relative; to the .outer div, it will default to position:static. Absolutely positioned divs will be positioned relative to the closest parent that is positioned relatively. If there is none, it will be positioned relative to the page itself.
update css here fiddle demo
i update in your jsfiddle
use relative in outer div
.twitter-box {
margin: 0 auto;
position:relative;
padding: 20px;
width: 700px; }
.twitter-box p {
text-decoration: none;
display: inline;
position: absolute;
margin-top: 69px; }
.twitter-box img {
height: 150px;
width: 150px;
text-align: center;
margin: 0 auto; }
.twit {
position: absolute;
text-decoration: none;
cursor: pointer;
bottom: 20px;
left: 5px;}

Centering inside div thats both centered in a div and bigger and its parent depends on document width

I have a div inside a div, the child both being centered in its parent and bigger than the parent making it overflow equally on both sides of it. The child has another div inside it with some text.
<div class="outer">
<div class="inner">
<div class="text">
testing testing
</div>
</div>
</div>
css:
.outer
{
width: 400px;
height: 400px;
background: beige;
margin: 0 auto;
}
.inner
{
width: 600px;
height: 200px;
background: pink;
position: absolute;
left:0;right:0;
margin: auto;
}
.text
{
margin-left: auto;
margin-right: auto;
width: 400px;
}
http://jsfiddle.net/msVVD/4/
Now, if the document width is narrowed by resizing the browser window, or in the jsfiddle case, resized by dragging the handle between "JavaScript" and "Result", the text will not stay on the same horizontal position, but "travel" to the right.
Why?
You need to set a min-width to the body (or parent container in which the absolutely positioned element is aligned according to) like so
body
{
min-width: 600px;
}
This will prevent the absolutely positioned from traveling
FIDDLE
You are not positioning the .inner element relatively to the .outer one. Add position: relative to .outer.
Changes in your CSS:
.outer
{
width: 400px;
height: 400px;
background: beige;
margin: 0 auto;
position: relative;
}
.inner
{
width: 600px;
height: 200px;
background: pink;
position: absolute;
left:0;right:0;
margin: auto;
margin-left: -100px;
padding-left: 100px;
}
Fiddle: http://jsfiddle.net/msVVD/7/

Resources