CSS Pseudo Element Changes Height When Moving its Position - html

I'm creating tabs, where each link inside the tab list is in a div with a border - something like:
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):
But then if I set bottom: 2px, I get this:
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?

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>

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.

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>

Related

CSS 3 special rounded border [duplicate]

This question already has answers here:
Invert rounded corner in CSS?
(10 answers)
Closed last month.
I have tried to create that rounded border corners on the bottom but I can't figure it out how to make them ....
.test {
border-bottom: 2px solid #EEF7FF;
display: inline-flex;
}
.test li {
float: left;
list-style-type: none;
}
.test li a {
text-decoration: none;
padding-left: 30px;
padding-right: 30px;
padding-top: 5px;
color: #A6B5C7;
}
<div class="" style="margin-top: 20px;">
<ul class="test" style>
<li>
<a style="border-top: 2px solid #EEF7FF;border-left: 2px solid #EEF7FF;border-right: 2px solid #EEF7FF;border-bottom: 5px solid white;color: #000000 !important;padding-bottom: 5px;vertical-align: super;border-radius: 5px 5px 0px 0px; " href="">All</a>
</li>
<li>
Solved
</li>
</ul>
</div>
Connecting border-radius from adjacent elements
Those borders might be achieved connecting the borders of the adjacent list item elements.
After finishing the demo I realized it's not the best approach to get there actually. But since it shows how to deliver an idea I think it's still worth remaining here.
Styling the active item - border-left and border-top:
I added the class active to distinguish between active and inactive navigation links.
The item with the active has only the border left and top styled:
li.active a {
position: relative;
color: black;
vertical-align: super;
border-top: solid var(--border-size) var(--border-color);
border-left: solid var(--border-size) var(--border-color);
border-radius: var(--border-radius-active) var(--border-radius-active) 0px 0px;
}
Styling the active item - border-right:
While the right border gets styled using the pseudoelement ::after positioned absolute. The reason why we couldn't style directly the right border it's because its lenght can't be the whole height since we are trying to connect with this segment the border radius coming from two different elements and if we used the whole lenght it wouldn't look right:
li.active a::after {
content:"";
background: var(--border-color);
position: absolute;
bottom: var(--border-offset-bottom);
right: 0;
height: calc(100% - var(--border-offset-top) - var(--border-offset-bottom));
width: var(--border-size);
}
Styling the next item - border-bottom:
And eventually the last portion of the line is styled by the next element:
li.active + li a {
border-bottom: solid var(--border-color) var(--border-size);
border-radius: 0 0 0 var(--border-radius-inactive);
}
Custom properties:
I encoded the core parameters as custom properties in the :root element:
--border-color: #EEF7FF;
--border-size: 1px;
--border-offset-top: 4px;
--border-offset-bottom: 2px;
--border-radius-active: 10px;
--border-radius-inactive: 3px;
The demo:
In the demo you can toggle the border color to red to better see in contrast the result:
:root{
--border-color: #EEF7FF;
--border-size: 1px;
--border-offset-top: 4px;
--border-offset-bottom: 2px;
--border-radius-active: 10px;
--border-radius-inactive: 3px;
}
.red{
--border-color: red;
}
*{
box-sizing: border-box;
}
body{
font-size: 30px;
font-family: sans-serif;
}
.test {
display: inline-flex;
}
.test li {
float: left;
list-style-type: none;
}
.test li a{
text-decoration: none;
padding-left: 30px;
padding-right: 30px;
padding-top: 5px;
padding-bottom: 5px;
color: #A6B5C7;
}
li.active a {
position: relative;
color: black;
vertical-align: super;
border-top: solid var(--border-size) var(--border-color);
border-left: solid var(--border-size) var(--border-color);
border-radius: var(--border-radius-active) var(--border-radius-active) 0px 0px;
}
li.active a::after {
content:"";
background: var(--border-color);
position: absolute;
bottom: var(--border-offset-bottom);
right: 0;
height: calc(100% - var(--border-offset-top) - var(--border-offset-bottom));
width: var(--border-size);
}
li.active + li a {
border-bottom: solid var(--border-color) var(--border-size);
border-radius: 0 0 0 var(--border-radius-inactive);
}
button{
cursor: pointer;
padding: 1em;
}
<div style="margin-top: 20px;">
<ul id="nav" class="test" style>
<li class="active">
All
</li>
<li>
Solved
</li>
</ul>
</div>
<button onclick="document.getElementById('nav').classList.toggle('red')">change color to red!</button>

Align link bottom and right

I'm trying to move the green link so that it's sitting on the line like the span. This is my HTML
<div class="adminpanel-span" id="approved-users">
<span>Approved Users</span>
Download List
</div>
This is my CSS
.adminpanel-span {
font-size: 36px;
border-bottom: 1px solid #777777;
padding-bottom: 10px;
}
I've looked at other posts and found how to get it to the right, but I couldn't find how to bring it down to the line. How can you position the link on the line?
.adminpanel-span {
font-size: 36px;
border-bottom: 1px solid #777777;
padding-bottom: 10px;
position: relative;
}
.adminpanel-span > a{
position: absolute;
bottom: 0px;
right: 0px;
}
<div class="adminpanel-span" id="approved-users">
<span>Approved Users</span>
Download List
</div>
Try to use postion: absolute and position: relative

Control side that shortens when changing div height on hover

I'm using this hover effect for buttons, but in a few cases when the height changes, the top remains the same and the bottom moves up, instead of vice versa like it should. How can I make sure it always goes in the correct direction?
jsfiddle
.button {
box-sizing: border-box;
display: inline-block;
width: 215px;
height: 55px;
color: white;
font-family: $arial;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
text-align: center;
text-decoration: none;
text-shadow: 1px 1px 1px rgba(43, 36, 36, 0.35);
letter-spacing: .1em;
border-radius: 3px;
position: relative;
background: #009ee0;
border: 1px solid #148fc6;
border-bottom: 4px solid #148fc6;
}
.button:hover {
border-bottom: 1px;
height: 53px;
}
.button span {
position: absolute;
width: 90%;
left: 0;
right: 0;
margin: auto;
top: 50%;
transform: translateY(-43%);
line-height: 1.2;
}
div {
padding: 20px 5px;
}
<div>
<a href="#" class="button">
<span>Wrong way</span>
</a>
</div>
<div>
<a href="#" class="button">
<span>I work fine</span>
</a>
<a href="#" class="button">
<span>I work fine</span>
</a>
</div>
You're reducing the height from 55px to 53px. That 2px has to go somewhere. The top button is just collapsing it. (The bottom two are doing the same, it just doesn't look like it because they are being affected by vertical text alignment). change your hover rule to this to accommodate for the height loss.
.button:hover {
border-bottom: 1px;
margin-top: 2px;
height: 53px;
}
https://jsfiddle.net/exd6hhvz/
I was able to make it work consistently by adding margin-top: 2px; to .button:hover
Here's an example: https://jsfiddle.net/vf03czp5/

show the div inside that div next to it

I want to make a vertical menu with submenu's and the submenu have to go next to the parent div.
Hope you guys know how to do that, I did a look on google but only found results like 2 divs next to eachother. But I need that the child div have to get next of it.
My code for now:
HTML
<div id="menuCont">
<div class="menuItem">
Applicatie Ontwikkeling
<div class="subMenuCont">
<div class="subMenuItem">HTML</div>
<div class="subMenuItem">CSS</div>
<div class="subMenuItem">jQuery</div>
</div>
</div>
<div class="menuItem">
Netwerk Beheer
</div>
<div class="menuItem">
Server Beheer
</div>
</div>
CSS
#menuCont {
width: 17.5%;
text-align: center;
}
.menuItem {
width: 100%;
padding: 1em;
background-color: #ffffff;
color: #000000;
font-family: Lato;
font-size: 125%;
border: 1px solid #7266ff;
border-bottom: 0;
cursor: pointer;
}
.menuItem:first-child {
border-top-left-radius: 1.5em;
}
.menuItem:last-child {
border-bottom: 1px solid #7266ff;
border-bottom-right-radius: 1.5em;
}
.menuItem:hover {
background-color: #7266ff;
color: white;
}
.subMenuCont {
/*display: none;*/
position: relative;
/*left: 100%;*/
/*width: 90%;*/
}
.subMenuItem {
border: 1px solid #7266ff;
border-bottom: 0;
}
.subMenuItem:last-child {
border-bottom: 1px solid #7266ff;
}
Do you need any more info, please say it. for now I don't know what to give as more info.
In your CSS Code I changed the position element to absolute, that allows you to place the element exactly where you want:
.subMenuCont {
position: absolute;
top:0;
left: 17.5%;
width: 17.5%;
}

CSS dropdown with caret

I am trying to make sth like this:
So far i have done:
Html:
<div class="panel-heading" data-toggle="collapse" href="#data2">
<div class="heading">
APPLICATION
</div>
<span class="caret icon"></span
</div>
And css:
.panel-heading {
padding: 0px;
overflow: hidden;
}
.panel-heading>.heading {
padding: 5px;
float: left;
}
.panel-heading>.icon {
float: right;
background: yellow;
height: 100%;
padding: 5px 10px;
}
.item-detail .mini-title {
font-size: 14pt;
margin-bottom:5px;
color: orange;
font-weight: bold;
margin-top: 10px;
}
.panel-heading {
background: #FF6600;
}
.panel-body {
background: #EAECED;
}
.caret {
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #000000;
width:1px;
}
JSFiddle result:
JSFiddle
And i don't know how to handle right side of div.
I want to make a square a yellow color, and rest - orange. Caret should be black and centered in small square.
Thanks
You cannot add the icon class and the caret class to the same element, because you want to use the borders to create the arrow.
Try something like this:
<div class="panel-heading" data-toggle="collapse" href="#data2">
<div class="heading">
APPLICATION
</div>
<div class="icon"><div class="caret"></div></div>
</div>
(It works in your fiddle)
To center an element horizontally, I usually use the margins, set the left and right margins to 'auto', for example:
.caret { margin: 8px auto 0px auto; }
this will center your element and set its top margin to 8px