Absolute positioned elements have same width but look different - html

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.

Related

top/bottom:[%] based on parent element's borders instead of height

I found a weird behavior when positioning a child element using top:[%]. On mobile-safari, given top/bottom borders of sufficient size, the behavior seems to switch: Instead of the percentage being applied to the parent's height, its applied to the parent's borders (plus a little extra).
The following code reproduces the bug:
.parent {
position: relative;
border-bottom: 200px;
border-style: solid;
height: 100px;
width: 100%;
}
.normal {
position: absolute;
top: 10px;
width: 50%;
background-color: blue;
}
.defective {
position: relative;
top: 10%;
width: 50%;
left: 50%;
background-color: red;
}
* {
/*style reset*/
margin: 0;
border: 0;
}
<body>
<div class="parent">
<div class="normal">
<p>The top is 10px</p>
</div>
<div class="defective">
<p>I should be at the same height</p>
</div>
</div>
In this example, the top should be 10px, but when I inspect the element, it's actually 20.3px. Here is what it looks like:
Other details:
The bug seems to kick in when the sum of the vertical borders of the parent are 98% or more of its height.
The child element doesn't have to be a div, it can be an image.
The bug does NOT appear if the child has position:absolute.
Am I the only one who sees this? Is is documented somewhere?
Reproduced on the following:
iPhone XS Max 12 (real device on browserstack.com)
iPad mini iOS 9
iPhone8, with Safari 13.6 (simulated on lamdatest.com)
The relatively placed element is displaced vertically depending on the width of the border on some versions of IOS. This did not show on an iPad running Safari IOS14 but did on a mini iPad running IOS 9.
This appears to be a bug in at least some IOS versions.
A workaround might be to put the border into a pseudo element on parent. This snippet then worked on IOS 9 on the mini iPad:
<style>
.parent {
position: relative;
height: 100px;
width: 100%;
}
.parent::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-bottom: 200px;
border-style: solid;
}
.normal {
position: absolute;
top: 10px;
width: 50%;
background-color: blue;
rdisplay: none;
}
.defective {
position: relative;
top: 10%;
width: 50%;
left: 50%;
background-color: red;
}
* {
/*style reset*/
margin: 0;
border: 0;
}
</style>
<body>
<div class="parent">
<div class="defective">
<p>I should be at the same height</p>
</div>
<div class="normal">
<p>The top is 10px</p>
</div>
</div>

Position:sticky element which is nested into another sticky element doesn't work in Edge

I'm trying to develop table with fixed header and fixed sevelar columns.
I use position: sticky for this and it works well in Chrome/Safari/Firefox, but I found issue in Microsoft Edge.
If you create element with position:sticky; top: 0; and insert other element with position: sticky; left: 0;, Edge ignores nested element.
Open this example in Edge and check this: https://codepen.io/finethanks/pen/aRWByx
Is it a bug of Edge?
.wrapper {
border: 1px solid #ccc;
width: 200px;
height: 200px;
overflow: auto;
}
.content {
width: 1000px;
height: 1000px;
}
.sticky-wrapper {
height: 30px;
background: red;
position: sticky;
top: 0;
}
.item {
width: 50px;
height: 20px;
background: yellow;
position: sticky;
left: 0;
}
<div class="wrapper">
<div class="content">
<div class="sticky-wrapper">
<div class="item"></div>
</div>
</div>
</div>
"sticky" value not supported in Edge version less than 16.
Please see the browser compatibility of position css property on this link: https://developer.mozilla.org/en-US/docs/Web/CSS/position#Browser_compatibility

IE with position absolute element will create horizontal scroll

I want to use position: absolute to create a centered element, but it will create a horizontal scrollbar on Internet Explorer 11. Please see the script below. Anyone here knows how to fix this problem?
*Update: I figured out that using overflow:hidden seems to solve this problem somehow. But when there are another one outside of the container, it will be hidden as well.
.container {
width: 80%;
margin: 0 auto;
height: 100vh;
border: 1px solid green;
position: relative;
overflow: hidden; /*This one is not the solution, though*/
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 50%;
transform: translate(-50%, 0);
border: 1px solid red;
}
.another-content {
width: 40px;
height: 40px;
border: 1px solid blue;
position: absolute;
bottom: 20px;
right: -20px;
}
<div class="container">
<div class="content"></div>
<div class="another-content"></div>
</div>
You need to add following properties with the position absolute in IE
position: absolute;
top:0;
right: 0;
left: 0;
bottom:0; //specify all including bottom:0
The scrollbar show up in all browsers, not only IE. You can do the following:
The biggest issue is that the left: 50% and width: 80% together are adding to the total width and forcing the horizontal scrollbar to show up in some browsers (e.g. Internet Explorer and MS Edge). You set the width to 80%, so divide the remaining 20% between the left and right border and you'll end up with 10% each. Simply use left: 10% to achieve the same result, but without the side effect of the horizontal scrollbar.
Also when you set the size to 100% and then add border, those borders will be out of the view and cause the scrollbars to show up. This is the same in all browsers. Use box-sizing: border-box to force the browser to include the border in the height and width calculation.
The height: 100vh makes the box height equals to the view port. However, the body has default margins which vary from one browser to another. You can either set those margins to zero body { margin: 0; }, or change the height to height: 100% which is 100% of the container which the body in this case.
Try this:
.container {
width: 100%;
height: 100%;
border: 1px solid green;
position: relative;
box-sizing: border-box;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 10%;
border: 1px solid red;
}
<div class="container">
<div class="content"></div>
</div>
Thanks for your replies. Though they are not direct solution, they helped me a lot to figure out how to solve it.
The cause is as what Racil Hilan said. When I use left:50% and width:80%, the content width will be added up and create a horizontal scroll, which is not ignored by only IE. And my point is to avoid creating that added-up width. Here is my two way to workaround this one.
* {
box-sizing: border-box;
}
.container {
width: 100%;
height: 100vh;
border: 1px solid green;
position: relative;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 0;
right: 0;
border: 1px solid red;
margin: 0 auto;
}
.content-wrapper {
border: 1px solid black;
height: 30px;
position: absolute;
top: 100px;
left: 0;
right: 0;
}
.another-content {
width: 80%;
display: block;
height: 100%;
border: 1px solid red;
margin: 0 auto;
}
<div class="container">
<div class="content"></div>
<div class="content-wrapper">
<div class="another-content"></div>
</div>
</div>

Maintain aspect ratio and keep <div> from expanding

I have a <div> in which I am trying to keep a constant aspect ratio in (because the inner elements will need to be squares). I have been able to work out the CSS so that when you make the window less wide, the height will shrink accordingly and that works great. However, when I make the window more wide, the <div> keeps expanding beyond the height of the parent. How can I stop this .BoardWrapper <div> from expanding past its parent?
.BoardWrapper {
width: 100%;
padding-bottom: 50%;
position: relative;
border: 1px solid red;
}
.Board {
position: absolute;
top: 5px; bottom: 5px; left: 5px;right: 5px;
border: 1px solid green;
}
.Left {
height: 100%;
position: absolute;
left: 0; right: 30px;
border: 1px solid blue;
}
.Right {
height: 100%;
width: 20px;
float: right;
border: 1px solid black;
}
.Container {
position: absolute;
top: 10vh; bottom: 5vh; left: 5vw; right: 5vw;
}
<div class='Container'>
<div class='Right'></div>
<div class='Left'>
<div class='BoardWrapper'>
<div class='Board'></div>
</div>
</div>
</div>
I do not really want to have to deal with a JS solution here since these are all React components. However, a solution that incorporates React or Semantic-UI would be fine (although, it seems like there should be a raw CSS solution).
I'd prefer not to edit .Left, .Right, or .Container, but I can certainly add in extra elements if it would help.
Remove the padding-bottom
.BoardWrapper {
padding-bottom: 50%;
}
and add height
.BoardWrapper {
height: 100%;
}
Working Example:
https://jsfiddle.net/zwp8vwob/

Relative positioned block shows nonexistent right margin

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>