The relative and absolute positioning are great tools, but they take elements out of the flow and this leads to some restrictions in their use. I think I just encountered one of them but I'd love someone to prove me wrong.
To state it clearly: I have a div positioned relatively to its parent. The problem is, under certain conditions, this out-of-flow element can go further than the top element (e.g. the body) and add a horizontal scrollbar. Demo below:
.top-container {
width: 80%;
height: 100px;
margin: auto;
border: dashed 2px red;
}
.container {
width: 80%;
height: 50px;
margin: 25px auto;
border: dotted 1px blue;
position: relative;
}
.absolute {
width: 100%;
background-color: black;
color: white;
position: absolute;
top: 30%;
right: -50%;
}
<div class="top-container">
<div class="container">
<div class="absolute">
absolutely
</div>
</div>
</div>
My question is: is there a way to tell CSS absolutely positioned elements should not go further left or right than the borders of .top-container? Something that would behave like a sort of max-left/max-right.
(e.g. in my example, move the black div so that it does not go outside of the red dashed line)
If you decided to position the element in an exact position - you can't say that you want it to be positioned somewhere. You can use right/left margin (or position with percentages).
Another option is to use the overflow option to set the scroller on the container (or to specify that if the element is getting out of it's container it should be hidden):
.top-container {
width: 80%;
height: 100px;
margin: auto;
border: dashed 2px red;
}
.container {
width: 80%;
height: 50px;
margin: 25px auto;
border: dotted 1px blue;
position: relative;
overflow: auto;
}
.hidden-overflow {
overflow: hidden;
}
.absolute {
width: 100%;
background-color: black;
color: white;
position: absolute;
top: 30%;
right: -50%;
}
<div class="top-container">
<div class="container">
<div class="absolute">
absolutely
</div>
</div>
</div>
<div class="top-container">
<div class="container hidden-overflow">
<div class="absolute">
absolutely
</div>
</div>
</div>
Related
I rarely do html/css stuff so I'm struggling trying to implement what seems like a pretty basic layout. I have a bunch of div elements stacked vertically as well as centered horizontally across my html page. The problems I'm facing are
a) the top div (orange) is slightly wider than the other divs.
b) I want the top (orange) div to be visible even when scrolling, which currently isn't the case.
Actually, in order to make the top div always visible, I set its corresponding class' position attribute to fixed but it doesn't work since I also have other divs, and their position is set to relative. If I remove the relative position on the other divs, the orange div works as expected but the rest of divs are not horizontally centered anymore.
.fiksan {
background-color: orange;
position: fixed;
top: 0;
height: 40px;
}
div {
padding: 10px;
color: white;
width: 60%;
left: 20%;
position: relative;
top: 40px;
}
.naslov {
background-color: lightblue;
text-align: justified;
height: 180px;
position: relative;
}
.elementi {
background-color: blue;
height: 650px;
}
.css_elementi {
background-color: purple;
height: 400px;
position: relative;
}
<div class="fiksan">
</div>
<div class="naslov">
</div>
<div class="elementi">
</div>
<div class="css_elementi">
</div>
This is what it looks like now (when scrolling the top div is covered by other divs, and I don't want that)
position:sticky might be what you look for : see https://css-tricks.com/position-sticky-2/
.fiksan {
background-color: orange;
position: sticky;
top: 0;
height: 40px;
}
div {
padding: 10px;
color: white;
width: 60%;
margin:auto;
}
.naslov {
background-color: lightblue;
text-align: justified;
height: 180px;
}
.elementi {
background-color: blue;
height: 650px;
}
.css_elementi {
background-color: purple;
height: 400px;
}
<div class="fiksan">
</div>
<div class="naslov">
</div>
<div class="elementi">
</div>
<div class="css_elementi">
</div>
I have a child div, who's position is absolute and the left property is like -20px (just negative). The parent div has overflow:scroll but it does not allow to scroll to the left.
I've tried to delete parents or add wrappers, tried without the position properties, etc...
html
<div class="container">
<div class="levels">
<div class="level">
<div class="node">Node1</div>
<div class="node">Node2</div>
<div class="node">Node3</div>
<div class="node">Node4</div>
<div class="node">Node5</div>
</div>
</div>
</div>
css
.container {
border: 1px solid red;
margin: 20px;
height: 200px;
width: 900px;
overflow: scroll;
}
.levels {
width: 100%;
height: 100%;
position: relative;
}
.level{
border: 2px solid black;
width: 536px;
position: absolute;
left: -20px;
}
.node {
background-color: blue;
border: 2px green solid;
width: 100px;
display: inline-block;
}
I've simulated a scenario in a CodePen
Id like to have more of those 'level' divs and even more aligned to the left, so i can simulate like a flow tree. If this isn't the way to go i'd like to hear.
I am trying to create a scrollable list of items on the left, and use CSS to generate an arrow that pops out of the list, over the scroll bar, and on top of the content on the right. The issue is that since the list is scrollable it has to be relative to that scrollable list, and I can't use absolute positioning to get the pseudo element on the top of everything else.
Anyone have any ideas?
Here is my JSFiddle:
https://jsfiddle.net/184syueh/3/
And here is my HTML/CSS:
#left-scrollbar {
width: 30%;
float: left;
display: inline-block;
height: 500px;
overflow-y: scroll;
overflow-x: hidden;
position: relative;
}
#left-scrollbar .item {
height: 200px;
border-top: 1px solid #000;
}
.item.selected {
background-color: #00cc00;
}
.selected::after {
left: 97%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(136, 183, 213, 0);
border-left-color: #88b7d5;
border-width: 30px;
margin-top: -30px;
}
#right-content {
background-color: #ff0000;
width: 70%;
float: right;
display: inline-block;
position: relative;
height: 100vh;
}
<div id="main-container">
<div id="left-scrollbar">
<div class="item">
abcd
</div>
<div class="item selected">
abcd
</div>
<div class="item">
abcd
</div>
</div>
<div id="right-content">
a
</div>
</div>
The issue is that since the list is scrollable it has to be relative to that scrollable list.
This is solved by applying a position of anything but static (the default value) to the parent element which you wish to absolutely position relative to.
Further explaination:
https://css-tricks.com/absolute-positioning-inside-relative-positioning/
https://www.w3schools.com/css/tryit.asp?filename=trycss_position_absolute
In your case, applying position: relative to .item.selected works just great and is a common solution to this problem.
Updated Fiddle:
https://jsfiddle.net/d35x1bp4
Is it possible to make a div absolute to a specific relative div rather than just the parent?
For example. I have a div that's contained inside of a row. But, I want it to be absolute in the section rather than the row. Both divs are positioned relative because of a WordPress themes styling. If I use position absolute it will just make it absolute to the row.
How can I get around this issue?
.section {
width: 100%;
height: 100%;
position: relative;
background: #f5f5f5;
}
.row {
width: 80%;
height: 100%;
position: relative;
background: #000000;
margin: 0 auto;
}
.content {
width: 200px;
height: 200px;
background: pink;
position: absolute;
right: 0;
top: 0;
}
<div class="section">
<div class="row">
<div class="content">
</div>
</div>
</div>
This is not how positioning works. A div or any other element is relevant to its parent regarding its positioning. In case you want to position an element inside the section that you have, it's better to construct your code as follows:
<div class="section">
<div class="absoluteDiv">
</div>
<div class="row">
</div>
</div>
You could find some more examples here
Hope it helps,
Konstantinos.
Although you can not make a div absolute to a specific div, one way to get the results you are looking for is to add overflow:visible; to the row and left:100%; to content container. I changed the section height to 300px for demonstration purposes but it will behave the same with 100%.
.section {
width: 100%;
height: 300px;
position: relative;
background: #f5f5f5;
}
.row {
width: 80%;
height: 100%;
position: relative;
background: #000000;
margin: 0 auto;
overflow:visible;
}
.content {
width: 200px;
height: 200px;
background: pink;
position: absolute;
left: 100%;
top: 0;
}
<div class="section">
<div class="row">
<div class="content">
</div>
</div>
</div>
I need to have div border responsive. However, as you can see .buttonsDiv needs to be at the bottom and wrapper border needs to be stretched underneath .buttonsDiv. But when I use this code buttons are at the bottom but border stays at the top. I can't use margin because content div contains elements that are shown/hidden and the page needs to be fixed aka disabled scrolling.
html
.wrapper {
border: 1px solid black;
}
.buttonsDiv {
position: fixed;
bottom: 10px;
}
<div class="wrapper">
<div class="borderedDiv">Content</div>
<div class="buttonsDiv">Butons</div>
</div>
Put position: absolute; to the parent and define top, bottom, left, right as 0;
PS: This solution will not add scroll bar which appears if you put height 100vh
.wrapper {
border: 1px solid black;
position: absolute;
bottom: 0;
top: 0;
right: 0;
left: 0
}
.buttonsDiv {
position: fixed;
bottom: 10px;
}
<div class="wrapper">
<div class="borderedDiv">Content</div>
<div class="buttonsDiv">Butons</div>
</div>
Its hard to understand what you are after. Do you mean something like this?
html, body{
margin: 0;
padding: 0;
}
.wrapper{
height: 100vh;
width: 100vw;
padding: 10px;
box-sizing: border-box;
}
.inner_wrap{
position:relative;
width: 100%;
height: 100%;
border: 1px solid black;
box-sizing: border-box;
}
.buttonsDiv{
position: absolute;
bottom: 10px;
}
<div class="wrapper">
<div class="inner_wrap">
<div class="borderedDiv">Content</div>
<div class="buttonsDiv">Butons</div>
</div>
</div>
To add to the previous answer:
.wrapper {
border: 1px solid black;
height: 100vh;
}
.buttonsDiv {
position: absolute;
bottom: 1px;
}
<div class="wrapper">
<div class="borderedDiv">Content</div>
<div class="buttonsDiv">Butons</div>
</div>
The wrapper doesn't need an position: relative, position static will do fine.
With the position absolute of the button div you place the element relative to its parent element. Therefore if we put .buttonsDiv to bottom:1px it will stick to the bottom of the element.