Is it possible to make an element with position: absolute; have the full height of its parent, including overflowed content?
In the following code snippet the .line element gets cut off when scrolling the .container:
.container {
position: relative;
height: 150px;
width: 300px;
overflow-y: scroll;
}
.line {
position: absolute;
background: #000;
width: 2px;
left: 50%;
height: 100%;
}
<div class="container">
<div class="line"></div>
<div style="height: 500px;"></div>
</div>
Adding another wrapper can solve the issue:
.container {
height: 150px;
width: 300px;
overflow-y: scroll;
}
.container > div {
position: relative;
}
.line {
position: absolute;
background: #000;
width: 2px;
left: 50%;
height: 100%;
}
<div class="container">
<div>
<div class="line"></div>
<div style="height: 500px;"></div>
</div>
</div>
The height: 100%; of the absolutely positioned element refers to the given CSS heigth (i.e. the height defined in the CSS rule) of the relative parent, not to its stretched "real height" when it overflows. So it will always have the initial parent height which is defined via CSS.
To achieve what you want, you'd have to get the parent height via javascript and apply it to the child.
Related
I have a container which has a sticky element that sticks to the top, within the container, there's also a position absolute element at the bottom. I only want the sticky element to be sticky up to the point when it reaches the bottom element.
My solution requires knowing the bottom element height in order to reserve a min-height for the sticky element to be sticky.
Is there a way to do it without know the height of the bottom position absolute element?
.container {
height: 1000px;
}
aside {
background: palegoldenrod;
height: 600px;
width: 300px;
position: relative;
}
.stickyWrapper {
min-height: calc(100% - 100px);
}
.sticky {
position: sticky;
top: 0;
}
.stickyItem {
background: pink;
height: 100px;
color: #000;
}
.bottomThing {
position: absolute;
bottom: 0;
height: 100px;
background: blue;
color: #fff;
width: 100%;
}
<div class="container">
<aside>
<div class="stickyWrapper">
<div class="sticky">
<div class="stickyItem">
sticky item
</div>
</div>
</div>
<div class="bottomThing">
position absolute
</div>
</aside>
</div>
I've worked out a solution by using flexbox. I will also no longer need the bottom element to be position absolute.
.container {
height: 1000px;
}
aside {
background: palegoldenrod;
height: 600px;
width: 300px;
position: relative;
display: flex;
flex-direction: column;
}
.stickyWrapper {
flex-grow: 1;
}
.sticky {
position: sticky;
top: 0;
}
.stickyItem {
background: pink;
height: 100px;
color: #000;
}
.bottomThing {
height: 100px;
background: blue;
color: #fff;
width: 100%;
}
<div class="container">
<aside>
<div class="stickyWrapper">
<div class="sticky">
<div class="stickyItem">
sticky item
</div>
</div>
</div>
<div class="bottomThing">
position absolute
</div>
</aside>
</div>
I am trying to overlay an image using a pseudo-element that is aligned to the bottom of a parent element. Then parent then hides part of both the image and the pseudo element using overflow: hidden. This should make the parent clip both the image and the pseudo element at the same place. However the image extends beyond the pseudo element by 1px. This happens in both Chrome and IE at specific breakpoints.
I inserted the code to stackoverflow but I can not reproduce using their code viewer. I can however reproduce on codepen using a screen width of 800px:
https://codepen.io/dwigt/pen/PXyrXq
.wrapper {
margin: auto;
}
.item {
background: lightgrey;
max-height: 500px;
min-height: 500px;
height: 100%;
max-width: 800px;
}
.image {
overflow: hidden;
max-height: 250px;
position: relative;
}
.image img {
max-height: 100%;
width: 100%;
position: relative;
}
.image::after {
z-index: 10;
content: "";
position: absolute;
left: -50%;
top: calc(80%);
width: 200%;
height: 200%;
display: block;
background: lightgrey;
border-radius: 100%;
}
<div class="wrapper">
<div class="item">
<div class="image">
<img src="https://images.unsplash.com/photo-1547039963-8bebea5ff026?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1933&q=80"/>
</div>
<div class="text">
Lorem Ipsum
</div>
</div>
</div>
I'm using Swipe.js to create a page with several screens. Swipe requires a structure of 3 nested divs, with some style defined. I want to position an element 70% towards the bottom of one of the screens, but I'm finding that its Y position remains at the top when defined as a percentage. My guess is that the height of the containing div is somehow still 0, though I have set all min-height properties to 100%.
I'm testing on Chrome in desktop, for now. My stylesheet:
/* required by swipe.js */
.swipe {
overflow: hidden;
position: relative;
min-height: 100%; /* added this everywhere I could just in case */
}
.swipe-wrap {
overflow: hidden;
position: relative;
min-height: 100%;
}
.swipe-wrap > div {
float: left;
width: 100%;
min-height: 100%;
position: relative;
}
.page {
min-height: 100%;
}
html,body {
height: 100%;
margin: 0px;
padding: 0px;
}
/* element I want to position */
.myElement {
position: relative;
width: 200px;
top: 70%;
left: 50%;
transform: translate(-50%, -50%);
}
Body:
<div id="slider" class="swipe">
<div class="swipe-wrap">
<div class="page">
<div class="myElement">
<h1>I should be more than halfway down.</h1>
</div>
</div>
</div>
</div>
The result is that the inner div is centred horizontally, but vertically it's at the top (in fact, cut off because of the transform offset).
I have tried using flex and align-items: center. That does work. I'm not sure if I can use flex to define arbitrary relative positions, though.
Please check below example
.swipe {
overflow: hidden;
position: relative;
height: 100%;
}
.swipe-wrap {
overflow: hidden;
position: relative;
height: 100%;
}
.swipe-wrap > .page {
display: table;
width: 100%;
height: 100%;
table-layout: fixed;
text-align: center;
}
.myElement{
display: table-cell;
vertical-align: middle;
}
.page {
min-height: 100%;
}
html,body {
height: 100%;
margin: 0px;
padding: 0px;
}
<div id="slider" class="swipe">
<div class="swipe-wrap">
<div class="page">
<div class="myElement">
<h1>I should be more than halfway down.</h1>
</div>
</div>
</div>
</div>
I'm trying to center a wide div inside a smaller one, and center it. Can this be done?
I've got this:
HTML
<body>
<div id="full_container">
<div id="machine_mask">
<div id="machine_container">
<!---- SOME CONTENT HERE --->
</div>
</div>
<div class="machine_footer">
<img src="sprites/base_maquina.png" alt="panel de control" />
</div>
</div>
</body>
CSS
body {
margin :0;
}
div#full_container {
width: 100%;
height: 100%;
background: #805080;
}
div#machine_mask {
margin-top: 30px;
width: 100%;
display: inline-block;
height: 600px;
background: #805080;
position: relative;
overflow: hidden;
}
div#machine_container {
width: 1230px;
height: 500px;
background: #805080;
position: relative;
margin-left: auto;
margin-right: auto;
overflow: hidden;
}
When the window is wider than 1230px, it centers, but I really need for it to be centered when the window is smaller...
Is there a way to do this? (I was thinking about using jQuery and repositioning it, but I'd really prefer to do this in css)
Thank you very much!
You could use the absolute positioning hack.
div#machine_container {
width: 1230px;
height: 500px;
background: #805080;
position: absolute;
left: 50%;
margin-left: -615px; //half of 1230px
overflow: hidden;
}
I have a div element wrapping other div elements like so:
<div style="overflow:hidden">
<div id="a"></div>
<div id="b"></div>
</div>
I have other css rules that manage the dimensions of the outer div. In my actual code, I want to position the div#a exactly 10 px below the outer div. However, I want div#b to still be cut off by the outer div's overflow:hidden.
What is the best way to achieve this?
Method 1
A good way to do it is by setting the overflowing element to position:fixed (which will make it ignore the parent overflow), and then positioning it relative to the parent using this technique:
.parent {
position: relative;
.fixed-wrapper {
position: absolute;
.fixed {
position: fixed;
}
}
}
One caveat is that you cannot have any of the top,right,left,bottom properties set on the fixed element (they must all be default 'auto'). If you need to adjust the position slightly, you can do so using positive/negative margins instead.
Method 2
Another trick I recently discovered is to keep the overflow:hidden element with position:static and position the overriding element relative to a higher parent (rather than the overflow:hidden parent). Like so:
http://jsfiddle.net/kv0bLpw8/
#wrapper {
width: 400px;
height: 50px;
position: relative;
z-index: 1000;
left: 0px;
top: 0px;
}
#wrapper #insideDiv {
width: 400px;
height: 50px;
overflow: hidden;
position: absolute;
z-index: 2000;
left: 0px;
top: 0px;
}
#wrapper #a {
position: absolute;
height: 30px;
width: 100px;
bottom: -40px;
z-index: 1000;
left: 0px;
}
<div id="wrapper">
<div id="a">AAA</div>
<div id="insideDiv">
<div id="b">BBB</div>
</div>
</div>
The easiest and most convenient way is to wrap your container div inside another div and set position: relative on the external div.
.outer-container {
position: relative;
height: 50px;
}
.container {
background: gray;
overflow: hidden;
height: 50px;
}
#a,
#b {
height: 100px;
width: 100%;
}
#a {
background: green;
position: absolute;
top: 60px;
}
#b {
background: red;
font-size: 60px;
}
<div class="outer-container">
<div class="container">
<div id="a"></div>
<div id="b">Cut off</div>
</div>
</div>
as people said, the element must be presented outside the parent in order to be not cropped. But you can do this with JavaScript to achieve the similar concept without having to change your actual markup:
function breakOverflow(elm) {
var top = elm.offset().top;
var left = elm.offset().left;
elm.appendTo($('body'));
elm.css({
position: 'absolute',
left: left+'px',
top: top+'px',
bottom: 'auto',
right: 'auto',
'z-index': 10000
});
}
then pass the element you want to exclude from the cropping of its parent:
breakOverflow($('#exlude-me'));