Strange 1px offset in MSIE for :after and :before - css

I'm trying to build a tag system with 'negative border radius' (I lack a better description).
I use :after and :before to create some faux border the 'bends outside'. It worked well, but there is some strange behaviour in MSIE. Normally I have top:5px on the :after and :before, but in IE I have to add an extra pixel (results in top: 6px) (See in IE8: the horizontal lines to the left and right should not be visible)
What could that be?
http://jsfiddle.net/rhGZw/3/
<div class="test"><div>foo</div></div>
body {
background: gold;
margin: 10px;
}
.test {
display: inline-block;
height: 30px;
overflow: hidden;
}
.test > div {
background: white;
border-top-left-radius: 5px;
border-top-right-radius : 5px;
height: 20px;
padding: 5px;
display: inline-block;
}
.test:before {
content: '';
width: 5px;
height: 20px;
position: relative;
top: 5px;
margin-right: -5px;
background: none;
border-color: white;
border-style: solid;
border-width: 0px;
border-bottom-width:5px;
border-right-width:5px;
border-bottom-right-radius: 10px;
display: inline-block;
vertical-align: middle;
z-index: -1;
}
.test:after {
content: '';
width: 5px;
height: 20px;
position: relative;
top: 5px;
margin-left: -5px;
background: none;
border-color: white;
border-style: solid;
border-width: 0px;
border-bottom-width:5px;
border-left-width:5px;
border-bottom-left-radius: 10px;
display: inline-block;
vertical-align: middle;
z-index: -1;
}
​

I managed to get the error by myself. It was the vertical-align:middle with the :after and :before which caused the 1px offset

The white borders are visible in Firefox and Opera too, not just IE. However, they blend into the border-radius.
It's easy to see at http://jsfiddle.net/CrxQG/ and http://jsfiddle.net/CrxQG/1/ with black border color and border-radius removed, respectively.

Related

::after pseudo-element width is different of content

I am creating a horizontal menu with navigation tabs. When these tabs float left in small devices, to pretend that they look more real I add a ::after pseudo-element for extend their height.
But the li width is 2px bigger than li::after width.
sass without :hover, :focus and other tags style looks like this:
.nav-tabs {
& > li {
border: 1px solid $gray-light;
border-bottom-color: white;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
padding: 0 $margin-default;
&::after {
display: block;
position:absolute;
height:200px;
width: 100%;
z-index: -2;
left: 0;
border-left: 1px solid $border-color;
border-right: 1px solid $border-color;
}
}
}
Absolute positioning width does not take account of borders...that's the issue.
So you will have to adjust accordingly
calc is a good option here.
div {
width: 200px;
border-width: 0 10px 0;
border-style: solid;
border-color: red;
height: 200px;
margin: 3em auto;
position: relative;
}
div::after {
content: "";
width: 100%;
width: calc(100% + 20px);
/* 2 x 10px */
height: 2em;
position: absolute;
bottom: 100%;
background: pink;
left: -10px;
/* 1x border-width */
}
<div></div>
This is because you have used position: absolute; to &::after, there is no parent which has position: relative; Apply position: relative to .nav-tabs
.nav-tabs {
position: relative;
& > li {
/* Your styles */
}
&::after {
/* Your styles */
}
}
Try this, this will really help you.

Vertical align :after element

I've tried the various responses here but no luck.
I need to vertical align an after element:
content: "";
width: 30px;
height: 15px;
background: transparent url('/img/test.png') no-repeat;
float: right;
border: 1px solid red;
This does not work:
vertical-align: middle;
Nor does:
vertical-align: -50%;
From those answers linked to, the vertical-align:inherit; on the element worked for me when I set the parent element to vertical-align:top;, nothing else seemed to work for me.
You can use line-height on the parent element and display:inline-block on the pseudo :after
.box {
width: 100px;
height: 100px;
background: #CCC;
line-height: 100px;
text-align: center;
}
.box:after {
content: "";
width: 30px;
height: 15px;
background: transparent;
border: 1px solid red;
display: inline-block;
}
DEMO: https://jsfiddle.net/tianes/zhwL3rrq/

Inner border that does not push contents

I'm trying to fill an element with multiple colors using CSS. Currently, I have this CSS:
div.container {
width: 100px;
border: 1px dotted;
font-size: 10px;
}
.box {
box-sizing:border-box;
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
border: 6px solid #99FF99;
border-bottom-color: #FF9966;
border-right-color: #FF9966;
}
fiddle
Problem is that the contents are not over the border, so it looks like this:
How can I get the contents of span class="box" to stay in the middle of the element (i.e. over the colored circle)?
How about using absolute and relative positions, and making the circle as a pseudo element.
DEMO: http://jsfiddle.net/d0cv4bc8/8/
div.container {
width: 100px;
border: 1px dotted;
font-size: 12px;
}
.box {
position: relative;
}
.box::before {
content: "";
box-sizing:border-box;
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
border: 6px solid #99FF99;
border-bottom-color: #FF9966;
border-right-color: #FF9966;
position: absolute;
z-index: -1;
}
Only way I can get the contents centered vertically and horizontally is to put contents inside a span, moved left and up by half of box's border width.
http://jsfiddle.net/d0cv4bc8/11/
CSS
.box .contents {
display:inline-block;
position: relative;
left: -3px;
top: -3px;
}
HTML
<div class="container">
<span class="box"><span class="contents">1</span></span>
</div>

I cant seem to get a border on my arrow tooltip

I need help turning the arrow white with a blue border like the box containing the text. I need to use the title inside an a tag as the content but feel free to edit everything else I managed to get it to a certain point but cant seem to get past this:
CSS
.toop {
position: relative;
padding: 0 5px;
line-height: 23px;
}
.toop:hover:after {
content: attr(title);
color: #474747;
font-size: 14px;
line-height: 150%;
text-align: left;
background-color: #ffffff;
border-radius: 5px;
border: 2px solid #2192ce;
padding: 5px 10px;
opacity: 0.9;
display: block;
width: 180px;
position: absolute;
left: 10px;
bottom: 40px;
z-index: 98;
}
.toop:hover:before {
content: "";
border: solid;
border-color: #2191ce transparent;
border-width: 10px 10px 0 10px;
opacity: 0.9;
display: block;
left: 30px;
bottom: 30px;
position: absolute;
z-index: 99;
}
HTML
<br>
<br>
<br>
<br>
<br>
Tooltip is here
you can not do that , you can not have a border around the "arrow" . making that arrow is a trick you can do with css to manipulate the :after and :before to make it appear like an arrow , but you can not have a border outside of that unless you wanted to use an image and put it in that place.
see an example I made of your code to show
outline: 2px solid #000;
outline can be used to make a border outside of the actual border, but it is not going to be anything like what you wanted.
http://jsfiddle.net/pp9t0vqb/4/
The best you can do is fake the arrow with an entire block:
.toop:hover:before {
content: "";
width:10px;
height:10px;
background:white;
border: 2px solid #2192ce;
border-width:0 2px 2px 0;
transform:rotate(45deg);
display: block;
left: 30px;
bottom:35px;
position: absolute;
z-index: 99;
}
But in this case you can't handle the opacity property.
Check this Demo Fiddle

Span's pseudo-elements overlay the element itself

I'm stuck with CSS pseudo-elements :before and :after when I was trying to stylize button's background. The problem is this: when I'm using only positive z-indices to place span itself and its pseudo-elements in right order, :before and :after are always overlapping the element. When I'm using negative z-indices, it's all right, but I don't want to change other underlying elements' z-indices just to make the button working.
So that's the problem and that's the goal to be achieved except the negative z-indices.
Problem code:
.button {
display: inline-block;
z-index:3;
position: relative;
left: 25px;
top: 25px;
height: 60px;
padding-left: 20px;
padding-right: 20px;
background: rgb(96,96,100);
border: 1px solid #202020;
color: #dddddd;
}
.button:before {
content: "";
width: 100%;
height: 100%;
z-index: 2;
position: absolute;
background: rgba(85,85,90, .7);
padding: 10px;
left: -10px;
top: -10px;
}
.button:after {
content: "";
width: 100%;
height: 100%;
z-index: 1;
position: absolute;
background: rgba(85,85,90, .4);
padding: 20px;
left: -20px;
top: -20px;
}
go for borders ! :)
http://jsfiddle.net/RwGV9/1/
basically
border:solid 10px rgba(85,85,90, .7);
left: -10px;
top: -10px;
and same thing for the other one with the right left, top and padding !
if you don't mind putting attributes in your html, you could do like that :
http://jsfiddle.net/RwGV9/
in the HTML :
<span data-text='button !' class="button">button</span>
and in the CSS :
.button:before {
content: attr(data-text);
Basically put the text in the highest layer using button using content: attr(); and make you text disappear in the deepest one (bg color = type color is not very elegant but it keeps the text of the button selectable for the user !)
http://jsfiddle.net/D8gDK/
.button {
display: inline-block;
position: relative;
left: 25px;
top: 25px;
width: 100px;
height: 60px;
padding-left: 20px;
padding-right: 20px;
background: rgb(96,96,100);
border: 1px solid #202020;
color: #dddddd;
}
.button:before {
content: "";
display: block;
width: 140px;
height: 60px;
position: relative;
background: rgba(85,85,90, .7);
border: 10px solid rgba(85,85,90, .4);
padding: 10px;
left: -40px;
top: -20px;
}
I got rid of the second pseudo element and put the before behind the button.
Might need some work with the colors...
Works only if you know the width of the button, though

Resources