Relative positioned block shows nonexistent right margin - html

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>

Related

Absolute positioned elements have same width but look different

I have 3 absolute positioned elements within a container, each with a width of 1px. However, these elements do not look to be all the same size when rendered. Why is this?
.container {
position: relative;
border: 1px solid red;
width: 100px;
height: 100px;
margin: 50px;
}
div > * {
position: absolute;
width: 1px;
height: 100%;
top: 0px;
border: 1px solid red;
}
#child1 {
left: -15px;
}
#child2 {
left: -21px;
}
#child3 {
left: -27px;
}
<div class="container">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
</div>
JSFiddle here
Here is what I see in my browser (using Chrome 102.0.5005.115):
The second child does not seem to be the same width as the other children.
Looks like a bug on your browser. For me, the code snippet works on Chrome(Version 103.0.5060.53), Firefox (Version 102.0), and Safari(Version 15.5).
I suggest updating Chrome from chrome://settings/help.

How can I show a div out of the box with overflow hidden

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

Inner container is pushing the outer container's position due to inner container margin [duplicate]

This question already has answers here:
CSS margin terror; Margin adds space outside parent element [duplicate]
(7 answers)
Closed 3 years ago.
The row div has a top/bottom margin of 10px (margin: 10px 2px). However, the 10px is pushing the position of the main container. What I am trying to achieve is the row has a top/bottom margin inside the main-container. The margin is some how escaping and pushing the main-container.
Here is my code:
body {
padding: 0;
margin: 0;
}
.main-container {
position: relative;
display: block;
width: 183px;
height: 101px;
background-color: red;
}
.row {
position: relative;
display: block;
margin: 10px 2px;
width: 175px;
height: 15px;
background-color: green;
}
<div class="main-container">
<div class="row">
</div>
<div class="row">
</div>
</div>
But if you run this code (below), without the row div. You can see the position of the main-container is different. This is the position the main-container should be in.
body {
padding: 0;
margin: 0;
}
.main-container {
position: relative;
display: block;
width: 183px;
height: 101px;
background-color: red;
}
<div class="main-container">
</div>
How can I fix this?
You should change your position in the .main-container class to be position: absolute instead of position: relative.
Relative positioning will move the element with the flow of the page, whereas absolute positioning will essentially lock it in whatever position you set it to be in. Relative positioning is more for situations like your .row class, where you want it to depend on the positioning of the .main-container class. Absolute positioning should be used when you don't want other elements (specifically the parent element) to determine it's position.
body {
padding: 0;
margin: 0;
}
.main-container {
position: absolute;
display: block;
width: 183px;
height: 101px;
background-color: red;
}
.row {
position: relative;
display: block;
margin: 10px 2px;
width: 175px;
height: 15px;
background-color: green;
}
<div class="main-container">
<div class="row">
</div>
<div class="row">
</div>
</div>
This article does a great job of explaining why you are having issues when both the parent and child have position: relative. If you take the position off of the parent entirely, you won't even notice a difference. Why? Because there's nothing to position it relative to. If you remove it from the .row class, you will find the same results. Relative positioning looks for an element that has a positioning other than static. In this case, there isn't one, so it's not really doing anything since all of the parents (body, html, etc) have position: static by default.
body {
padding: 0;
margin: 0;
}
.main-container {
display: block;
width: 183px;
height: 101px;
background-color: red;
}
.row {
position: relative;
display: block;
margin: 10px 2px;
width: 175px;
height: 15px;
background-color: green;
}
<div class="main-container">
<div class="row">
</div>
<div class="row">
</div>
</div>
<div class="main-container">
<div class="row">
</div>
<div class="row">
</div>
</div>
body {
padding: 10px;
margin: 0;
}
.main-container {
position: relative;
width: 183px;
height: 101px;
background-color: red;
}
.row {
position: relative;
left: 50%;
top: 35%;
transform: translate(-50%, -50%);
margin: 10px 0;
width: 175px;
height: 15px;
background-color: green;
}
Check it out in https://codepen.io/3rdsty4bl00d/pen/OGbENg?editors=1100#0

Select which overlapping div is on top

I have written a simple code with a main box containing two smaller boxes inside.
I have set the position of the smaller boxes to absolute, in order to set their positioning according to their parent.
What i would like to do is to bring the son2 div in front, since now is hidden by sondiv
I tried the z-index property but (as i expected) my element gets under the parent element, and not under the small blue box
#parent {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
margin-top: 200px;
margin-left: 200px;
}
#son2 {
position: absolute;
background-color: green;
width: 50px;
height: 50px;
margin-top: 20px;
}
#son {
position: absolute;
background-color: blue;
width: 50px;
height: 50px;
margin-top: 10px;
}
<div id="parent">
<div id="son2"></div>
<div id="son"></div>
</div>
Demo on Codepen: https://codepen.io/mattiasu96/pen/KbpyNQ
Tiny change (just add z-index: 1; to son2).
By the way you don't want to set position: absolute for the parent unless you need to change its position from the natural one as well, otherwise go with position: relative so that it's rendered normally but the absolute positioned children still behave as intended.
I've removed the margins from the parent just so you don't have to scroll in the snippet in order to see the divs, but no difference if you need that in your original problem.
#parent {
position: relative;
background-color: red;
width: 100px;
height: 100px;
}
#son2 {
position: absolute;
background-color: green;
width: 50px;
height: 50px;
margin-top: 20px;
z-index: 1;
}
#son {
position: absolute;
background-color: blue;
width: 50px;
height: 50px;
margin-top: 10px;
}
<div id="parent">
<div id="son2"></div>
<div id="son"></div>
</div>

Ensure relatively positioned element stays inside of top container

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>