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
Related
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 want to display a tool tip for each element of a list, this list is big so it has its own div with a scroll. The problem is that, for the first element, the tool tip is out of the box and it is not visible, even it has position absolute and z-index.
If you take a look at this code, basically what I want is nothing but display the square in block 2 inside the block 1.
.square {
position: absolute;
z-index: 9999;
display: block;
top: -20px;
background-color: black;
height: 10px;
width: 10px;
}
.block {
overflow-y: overlay;
display: block;
height: 100px;
width: 100px;
position: relative;
border-style: solid;
}
<div class="block">Block 1</div>
<div class="block">
Block 2
<div class="square"></div>
</div>
Note, I really need to have the position relative and the scroll, is it possible to achieve that? Which other options I have?
https://jsfiddle.net/daczfw64/
Like this?
<div class="container">
<div class="block">Block 1</div>
<div class="block">
Block 2
<div class="square"></div>
</div>
</div>
.container {
overflow-y: overlay;
}
.block {
display: block;
height: 100px;
width: 100px;
position: relative;
border-style: solid;
}
.square {
position: absolute;
z-index: 9999;
display: block;
top: -20px;
background-color: green;
height: 10px;
width: 10px;
}
https://codepen.io/chocopuff/pen/PoYzbPw
Brief question: Click the first link below and explain me why Chrome shows margin on the right, if it doesn't have any.
Long question:
I'd like to understand why Google Chrome shows different graphical representations from absolute and relative positioned blocks.
On an absolute positioned block, Chrome shows the element the way I've expected.
On an relative positioned block, the element's width shows something more. It looks like some margin or padding, but I zeroed the paddings and margins from this div and it still looks the same on Chrome Inspect Tools.
Look how the relative div has an "extension" to its width.
inspected relative div screenshot
And here, the absolute div doesn't have this "extension".
inspected absolute div screenshot
And here's a code where this can be demonstrated.
.wrapper {
border: solid 1px red;
display: block;
width: 300px;
position: relative;
height: 150px;
}
.absolute-class, .relative-class {
display: block;
width: 100px;
left: 20px;
font-size: 24px;
}
.absolute-class {
position: absolute;
top: 10px;
}
.relative-class {
position: relative;
top: 30px;
}
<body>
<div class="wrapper">
<div class="absolute-class">Text 1</div>
<div class="relative-class">Text 2</div>
</div>
</body>
I'm worried about this, because I think this extra "margin" is causing an horizontal scrolling on the page I am developing. So I would like to understand what this is, to be able to solve this problem.
This goes outside the div because you give left:20px and set the fixed width, so left will push your div to outside the wrapper div. Use padding-left:20px;
.wrapper {
border: solid 1px red;
display: block;
width: 300px;
position: relative;
height: 150px;
}
.absolute-class, .relative-class {
display: block;
width: 100px;
padding-left: 20px;
font-size: 24px;
}
.absolute-class {
position: absolute;
top: 10px;
}
.relative-class {
position: relative;
top: 30px;
display: inline-block;
}
<body>
<div class="wrapper">
<div class="absolute-class">Text 1</div>
<div class="relative-class">Text 2</div>
</div>
</body>
Or you can also use display: inline-block; in .relative-class
.wrapper {
border: solid 1px red;
display: block;
width: 300px;
position: relative;
height: 150px;
}
.absolute-class, .relative-class {
display: block;
width: 100px;
left: 20px;
font-size: 24px;
}
.absolute-class {
position: absolute;
top: 10px;
}
.relative-class {
position: relative;
top: 30px;
display: inline-block;
}
<body>
<div class="wrapper">
<div class="absolute-class">Text 1</div>
<div class="relative-class">Text 2</div>
</div>
</body>
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>
Please see JSfiddle:
http://jsfiddle.net/76yKL/
Is there a way to align "ruler-mark-short" and "ruler-mark-high" divs to the bottom and center of their parents("ruler-mark-container") ?
Since width of "ruler-mark-short" and "ruler-mark-high" can be changed dynamically by JavaScript, I can't use 'margin' or 'left' in pixels.
So, I have to use something like "margin: 0 auto" or "text-align: center", but non of this works.
I'm struggling with aligning ruler-marks to both bottom and center without using additional wrapper container.
Any help is appreciated, thanks.
Code From JSfiddle above:
HTML:
<div class="container">
<div class="ruler">
<div class="ruler-mark-container">
<div class="ruler-mark-high"></div>
</div>
<div class="ruler-mark-container">
<div class="ruler-mark-short"></div>
</div>
<div class="ruler-mark-container">
<div class="ruler-mark-short"></div>
</div>
<div class="ruler-mark-container">
<div class="ruler-mark-short"></div>
</div>
<div class="ruler-mark-container">
<div class="ruler-mark-short"></div>
</div>
<div class="ruler-mark-container">
<div class="ruler-mark-high"></div>
</div>
</div>
</div>
CSS:
.container {
border: 1px solid grey;
position: absolute;
width: 700px;
height: 200px;
}
.ruler {
border: 1px solid orange;
position: absolute;
width: 100%;
height: 100px;
bottom: 0px;
}
.ruler-mark-container {
border: 1px solid blue;
position: relative;
width: 30px;
height: 100%;
/*display: inline-block;*/
float: left;
bottom: 0px;
}
.ruler-mark-high {
position: absolute;
border: 1px solid black;
background-color: grey;
bottom: 0px;
width: 3px;
height: 50px;
}
.ruler-mark-short {
position: absolute;
border: 1px solid black;
background-color: grey;
bottom: 0px;
width: 3px;
height: 25px;
}
text-align:center does not work with absolutely positioned elements. So remove absolute position, and format them using display:inline-block.
Without absolute positioning, they won’t be at the bottom any more of course. To fix that, stop floating the container elements, and display them as table-cell instead, and add vertical-align:bottom to both containers and markers.
http://jsfiddle.net/76yKL/7/
You just need to add the following css:
.ruler-mark-short, .ruler-mark-high{
left: 50%;
margin-left: -1.5px;
}
Working Fiddle
UPDATED: (IE9+)
.ruler-mark-short, .ruler-mark-high{
left: 50%;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
/* Add other vendor prefixes here */
}
Working Fiddle