'CSS Pseudo Element Changes Height When Moving its Position

I'm creating tabs, where each link inside the tab list is in a div with a border - something like:

enter image description here

In order to hide the bottom border of the tabset below the selected tab, I'm adding a pseudo element (:after) that is the full width of the link, and whose height is the same as the bottom border (2px), and also has a bottom value of negative the border height (-2px). I'm running into an issue where, depending on the position (bottom value) of the pseudo element, its rendered height changes. If I set its height to 2px, it fluctuates between 1px and 2px, and does this every 2px when moving its position.

For example, at bottom: 3px, it looks like this (I've made the background red for illustration purposes):

enter image description here

But then if I set bottom: 2px, I get this:

enter image description here

I see this behavior on both firefox and chrome. Here's a codepen illustrating.

And here's an inline snippet of the same code:

.main-container {
	padding: 50px;
	font-family: arial;
}

.link-container {
	display: inline-block;
	border: 2px solid #000;
}

a {
	position: relative;
	display: block;
	text-decoration: none;
	font-weight: bold;
	color: #000;
	padding: 5px 5px 15px;
}


a:hover {
	background: #ccc;
}

a:after {
	content: "";
	position: absolute;
	z-index: 1;
	height: 2px;
	left: 0;
	right: 0;
	bottom: 2px;
	background: red;
}

a.tab2:after {
	bottom: 3px;
}
<div class="main-container">
	<div class="link-container">
		<a class="tab1" href="#">Test Tab</a>
	</div>
	<div class="link-container">
		<a class="tab2" href="#">Test Tab</a>
	</div>
</div>

What's going on?



Solution 1:[1]

I don't know if it's still relevant or not, but I run into the same problem and I couldn't find any solution online so I came up with my own - I think this problem related either with float size of the parent element, either with something else.

But adding "transform: scaleY(1.0001);" to your pseudo-element seems to work for me

.main-container {
    padding: 50px;
    font-family: arial;
}

.link-container {
    display: inline-block;
    border: 2px solid #000;
}

a {
    position: relative;
    display: block;
    text-decoration: none;
    font-weight: bold;
    color: #000;
    padding: 5px 5px 15px;
}


a:hover {
    background: #ccc;
}

a:after {
    content: "";
    position: absolute;
    z-index: 1;
    height: 2px;
    left: 0;
    right: 0;
    bottom: 2px;
    background: red;
    transform: scaleY(1.0001);
}

a.tab2:after {
    bottom: 3px;
}
<div class="main-container">
    <div class="link-container">
        <a class="tab1" href="#">Test Tab</a>
    </div>
    <div class="link-container">
        <a class="tab2" href="#">Test Tab</a>
    </div>
</div>

Solution 2:[2]

Most likely your browser is zoomed in on the page. Make sure that you're viewing the page at 100% size by clicking ctrl + 0 and see if the height still changes with the position.

Other than that, if I understand correctly what you want to achieve, you're making things much more complicated than needed.

Firstly, unless you have a reason, the link-container divs are not needed. You can just put the links directly as childs of the main-container div and add borders to them directly.

Secondly, you can just use border-bottom and set it to whatever you like.

Solution 3:[3]

Why don't you just do it like this: Remove the pseudo element completely and reduce the border to three sides:

.link-container {
    display: inline-block;
    border-top: 2px solid #000;
    border-left: 2px solid #000;
    border-right: 2px solid #000;
}

Here it is in your snippet:

.main-container {
	padding: 50px;
	font-family: arial;
}

.link-container {
	display: inline-block;
	border-top: 2px solid #000;
	border-left: 2px solid #000;
	border-right: 2px solid #000;
}

a {
	position: relative;
	display: block;
	text-decoration: none;
	font-weight: bold;
	color: #000;
	padding: 5px 5px 15px;
}


a:hover {
	background: #ccc;
}
<div class="main-container">
	<div class="link-container">
		<a class="tab1" href="#">Test Tab</a>
	</div>
	<div class="link-container">
		<a class="tab2" href="#">Test Tab</a>
	</div>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Serge Markeloff
Solution 2 slacle
Solution 3 Johannes