Absolute positioning inside a div positioned in grid - css

I am trying out CSS grid layout and currently facing a problem. I would like to use position: absolute for a child of a div positioned in a grid. As you can see below (code snippet) the red box is set with position: absolute and is a child of .left.
How do I make it so that the red box visually stays in the orange div (left side) and doesn't "overflow" in the brown div (right side)?
I have tried setting position: relative to the parent element, without result.
Below is a simplified version showing the problem (you can modify the value to see the separator move)
html,
body,
section {
height: 100%;
margin: 0px;
padding: 0px;
}
.window {
display: grid;
grid-template-areas: "first seperator last";
grid-template-columns: 100px 10px auto;
/* | this one */
}
.left {
background: #ff9e2c;
grid-area: first;
position: relative;
}
.right {
background: #b6701e;
grid-area: last;
}
.separator {
background: white;
}
.abs-pos {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 100px;
left: 75px;
}
<section class="window">
<div class="left">
<div class="abs-pos"></div>
</div>
<div class="separator"></div>
<div class="right"></div>
</section>
The following is a GIF of the problem:
PS: In the actual file I have a JS script that allows me to move the .separator div horizontally to change the sizes of the two divs: .left and .right. It basically modìfies the property grid-template-columns: 100px 10px auto of .window therefore resizing the grid.

Setting overflow: hidden; on the .left pane will keep the red box from showing up outside its parent's bounds.
html,
body,
section {
height: 100%;
margin: 0px;
padding: 0px;
}
.window {
display: grid;
grid-template-areas: "first seperator last";
grid-template-columns: 100px 10px auto;
/* | this one */
}
.left {
background: #ff9e2c;
grid-area: first;
position: relative;
overflow: hidden;
}
.right {
background: #b6701e;
grid-area: last;
}
.separator {
background: white;
}
.abs-pos {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 100px;
left: 75px;
}
<section class="window">
<div class="left">
<div class="abs-pos"></div>
</div>
<div class="separator"></div>
<div class="right"></div>
</section>

Have you tried to give your classes a z-index
z-index: -1;
Z index sets the stack order And works with positioned elements. I.e absolute, relative, fixed.
So if you can give your .right and or .seperator class a position relative it should work.
.right {
position:relative;
z-index: 1;
}
.separator {
position:relative;
z-index: 1;
}
.abs-pos {
position:absolute;
z-index: -1;
}

Related

CSS margin-top moving element down

I have a context of 3 divs, one parent, and two children.
The two children are placed one on top of the other and I want to add a margin-top on the bottom one to move the one on top 50px up.
What ends up happening is that the one on the bottom moves down 50px instead.
Here is the code:
.container {
background-color: red;
width: 500px;
height: 300px;
position: relative;
margin: auto;
font-size: 30px;
}
.top,
.bottom {
height: 100px;
width: 100px;
}
.top {
background-color: purple;
}
.bottom {
margin-top: 50px;
background-color: blue;
}
<body>
<div class="container">
<div class="top">top</div>
<div class="bottom">bottom</div>
</div>
</body>
Any suggestions?
CSS allows you to move an element relative to its position without affecting other elements' positions if you use transform.
In this case you can translate the top element in the Y direction by -50px to move it up:
.container {
background-color: red;
width: 500px;
height: 300px;
position: relative;
margin: auto;
font-size: 30px;
}
.top,
.bottom {
height: 100px;
width: 100px;
}
.top {
background-color: purple;
transform: translateY(-50px);
}
.bottom {
background-color: blue;
}
<body>
<div class="container">
<div class="top">top</div>
<div class="bottom">bottom</div>
</div>
</body>
gap (grid-gap) Syntax
gap: 50px;
As you can see the first element is already on the highest point inside the parent container.
html
What you can do is in case you want to increase its height is scaling its y position by a negative number.

Overflow element without cutting absolutely positioned elements in it

In a container element I have floated element and an absolutely positioned image that needs to protrude from container. However I need container to keep its height because it has a margin-bottom that separate it from the next block below it.
Problem: container's overflow: hidden cuts the image off so it cannot protrude from it. So I have to choose between 2 things I absolutely need: the image to protrude and container to keep its height.
How to solve this dilemma?
HTML
<div class='container'>
<div class='col1'>
content
</div>
<div class='col2'>
<img src='whatever.jpg'/>
</div>
</div>
CSS
.container {
overflow: hidden;
}
.col1,
.col2 {
float: left;
width: 50%;
}
.col2 {
position: relative;
}
img {
position: absolute;
top: -100px;
left: -100px;
}
Is the overflow to contain the floats? If so there are several other methods.
These can be found here
The modern method is:
.container:after {
content:"";
display:table;
clear:both;
}
.container {
width: 80%;
border: 1px solid grey;
margin: 100px auto;
background: pink;
}
.container:after {
content: "";
display: table;
clear: both;
}
.col1,
.col2 {
float: left;
width: 50%;
height: 150px;
}
.col2 {
position: relative;
background: #c0ffee;
}
img {
position: absolute;
top: -100px;
left: -100px;
}
<div class='container'>
<div class='col1'>
content
</div>
<div class='col2'>
<img src='http://www.fillmurray.com/200/200' />
</div>
</div>

Is there a CSS equivalent to float: down

I was wondering if there is some sort of CSS equivalent to:
float: down;
or some way make a element or div go to the bottom of the page. Any help is appreciated.
Using flexboxes, you could set the child element to align-self: flex-end.
Example Here
.parent {
display: flex;
}
.child {
align-self: flex-end;
}
.parent {
height: 200px;
border: 5px solid #000;
display: flex;
}
.child {
height: 40px;
width: 100%;
background: #f00;
align-self: flex-end;
}
<div class="parent">
<div class="child">
Align to the bottom
</div>
</div>
Alternatively, you would have to use absolute/fixed positioning.
Example Here
.align-bottom {
position: absolute;
bottom: 0;
}
In some cases, you would also have to relatively position the parent element so that the absolute positioning is relative to it.
body {
min-height: 100vh;
}
.align-bottom {
position: absolute;
bottom: 0;
}
<div class="align-bottom">Align to the bottom</div>
You can set it that way:
bottom: 0;
position: fixed;
I suppose you'll like this as well with it additionally:
z-index: 9999;
All above together will make the element stick to the bottom even when you scroll the page.

CSS width is automatically maximum in one row

I have 2 divs in a row (with inline-blocks). One of them has a fixed width and the other one is supposed to automatically fill the left space. How can I do that?
My favorite solution is to use padding on the container block and absolute position on the fixed with object:
.wrapper {
padding-left: 100px;
position: relative;
}
.stay {
width: 100px;
position: absolute;
left: 0;
top: 0;
/* for demo */
height: 50px;
background-color: pink;
}
.fit {
width: 100%;
/* for demo */
height: 50px;
background-color: red;
}
HTML:
<div class="wrapper">
<div class="stay"></div>
<div class="fit"></div>
</div>

How to make side-by-side blocks fill the rest of the container when one is fixed size?

I have two blocks that are side-by-side. One size is fixed, 90px and other one is not, I want the other one to extend itself to the rest of the container since container size is will be changing.
Here is fiddle with commends displaying the problem: http://jsfiddle.net/L6CSG/
HTML
<div class="container">
<span class="left"></span>
<span class="right"></span>
</div>
CSS
.left, .right {
height: 30px;
display: inline-block;
margin: 0px;
float: left;
}
.left {
background: green;
width: 90px;
}
.right {
background: blue;
width: 100%; // How can I make it fit the rest of the container?
}
.container {
width: 400px; // This value is NOT STATIC
}
You can do it by pure CSS, here is working example jsFiddle
Make sure filler element is last in DOM tree
Make sure rest of the elements have position: relative specified and width+height
This is nice trick I learned:
HTML:
<div id="container">
<div class="left"></div>
<div class="rest"></div>
</div>
CSS:
#container {
width:50%;
height: 50px;
background-color: red;
min-width: auto;
}
.left {
position: relative;
float: left;
width: 90px;
height: 100%;
background: blue;
}
.rest {
display: block;
height: 100%;
overflow: hidden;
background: yellow;
}
Solution 1:
Make the width of .right width: calc(100% - 90px);
Solution 2:
http://jsfiddle.net/L6CSG/4/ In case of this solution you should probably use divs instead of span since I changed your spans to block elements.
You have to set float: left only for the left one
see result:
http://jsfiddle.net/L6CSG/2/
also you need display: block and width: auto for the right one
Here is the solution:
HTML:
<div class="container">
<span class="left"></span>
<span class="right"></span>
</div>
CSS:
.left, .right {
height: 30px;
margin: 0px;
display: block;
}
.left {
background: green;
width: 90px;
float: left
}
.right {
background: blue;
width: auto;
}
.container {
width: 400px;
}
JavaScript is needed to calculate the extra space that can be filled, as the container is not a fixed width.
var con = document.querySelector(".container");
var left = document.querySelector(".left");
var right = document.querySelector(".right");
window.addEventListener('resize', function() {
calcSize();
});
function calcSize() {
var diff = con.offsetWidth - left.offsetWidth;
right.style.width = diff + "px";
}
calcSize();
http://jsfiddle.net/L6CSG/7/

Resources