CSS multiple outlines with negative outline-offset - html

I got with image as a background, and want to get effect of multiple inner outlines.
Outlines should be solid white 2px, but in different position - say -4px, -8px, -12px.
Goal is to get more than 2 outlines.
I know i can make box-shadow and outline to get double outilne, but noticed that i cannot attach to div 3 classes with different outline-offset - div have applied only last of class.
My code:
<div class="imgfield effect1 effect2 effect3"> </div>
and example css:
.imgfield { background: url(someimage.jpg); ... width, height etc. }
.effect1 { outline: yellow 2px solid; outline-offset: -4px; }
.effect2 { outline: red 2px solid; outline-offset: -8px; }
.effect3 { outline: blue 2px solid; outline-offset: -12px; }
In this example there will be only blue inner outline but now red niether yellow. How to workaround this?
-----------edit-----------------
All answers are good. I must admit i try handling after and before but i'm not enough familiar with it. Box-sizing: border-box was also important.

to complete #Mr.Alien demo/answer , i would use border's pseudo for a better compatibility.
.effect {
height: 200px;
width: 200px;
outline: 1px solid #000;
position:relative;/* pick as reference for pseudo absolute */
-moz-box-sizing:border-box; /* keep box within size given */
box-sizing:border-box;
}
/* size pseudo within from coordonates */
.effect:before {
content:"";
top:2px;
left:2px;
right:2px;
bottom:2px;
border: green 2px solid;
position: absolute;
}
.effect:after {
content:"";
top:6px;
left:6px;
right:6px;
bottom:6px;
border: red 2px solid;
position: absolute;
}
DEMO

How about using pseudo elements for this? Here, I am using a single class with a single element, but am positioning the pseudo elements i.e :before and :after using position: absolute;.
Demo
You can surely play with z-index if you have any issue with the element overlapping.
.effect {
height: 200px;
width: 200px;
outline: 1px solid #000;
}
.effect:before {
content: "";
height: 200px;
width: 200px;
outline: green 2px solid;
outline-offset: -4px;
display: block;
position: absolute;
}
.effect:after {
content: "";
display: block;
height: 200px;
width: 200px;
outline: red 2px solid;
outline-offset: -8px;
position: absolute;
}

Related

Why does IE apply opacity to border-style: dotted?

The title says it all, I've just discovered that IE (9 - 11) automatically applies about 50% opacity to any element's border with border-style: dotted.
The weirdest thing is, it only happens on dotted in particular, solid and dashed are fine.
You can test it yourself: http://jsfiddle.net/ptv74f4q/1/
Any ideas?
This appears to be due to IE anti-aliasing the dotted border. If you make the border-width bigger than 1px (say 5px) the border will appear white again.
One way to get around this would be to overlay some pseudo elements with the same dotted border on top to counteract the opacity:
div {
width: 200px;
height: 200px;
background: #000;
}
span {
transform: rotate(0deg);
display: inline-block;
width: 180px;
height: 85px;
line-height: 85px;
text-align: center;
margin: 8px 8px 0 8px;
border: #fff 1px solid;
color: #fff;
position: relative;
}
span.dotted {
border-style: dotted;
}
span.dotted::before, span.dotted::after {
border: #fff 1px dotted;
content: "";
height: 100%;
left: -1px;
position: absolute;
top: -1px;
width: 100%;
}
<div>
<span>I'm with normal border</span>
<span class="dotted">I'm with dotted border</span>
</div>
JS Fiddle: http://jsfiddle.net/oyrbLyjc/1/
Alternative method
Alternatively you could try using border-image. There are online tools (e.g. https://developer.mozilla.org/en-US/docs/Web/CSS/Tools/Border-image_generator) that would be able to help you generate a similar border using this method.

HR with two colors

I'm trying to make an hr with two colors on it, one dark red on the bottom and one orange on the top. An image is attached that gives an example of what I'm trying for. Is there any way to do this using pure CSS?
EDIT: If not, is there a way to set an hr to be an image? Like a png? Something that will stretch for different sizes?
Use CSS with 2 borders like so:
hr {
border-top: 1px solid gray;
border-bottom: 1px solid white;
}
Example in JSFiddle.
And to mimic what you have in your picture with text floating on top of the HR, you can do something like this JSFiddle.
Another solution could be to just simply use a CSS gradient. Like so:
hr {
border: 0;
height: 1px;
background: #1e5799;
background: linear-gradient(to right, #1e5799 50%,#7db9e8 50%);
}
so if i understand correctly.. u want one hr..with lets say 1px height of blue and another 1px height of red sitting on top of each other..
u can do this with pure css, by using pseudo classes.
hr{
position:relative;
height:1px;
background-color:red;
}
hr:before {
position:absolute;
content : ' ';
left:0;
right:0;
height:1px;
top:-1px;
background-color:blue;
}
You don't need to use hr just a single element (Div) with Pseudo-elements like this:
:root {
background-color: red;
text-align: center
}
:root:hover {
background-color: orange;
}
div {
position: relative;
width: 40px;
display: inline-block;
font-style: italic
}
div:before, div:after{
content: '';
position: absolute;
width: 100px;
height: 1px;
background: black;
top: 50%;
border-radius: 4px;
box-shadow: 0 1px 1px white;
}
div:before{
left: -100px;
}
div:after{
right: -100px;
}
<div>or</div>

How to pixel-perfect mockup this border?

I'm trying to mockup this design:
But, I can't render the red border correctly. I tried with the obvious solution:
border: 1px solid #939393;
border-left: 4px solid red;
But It's affected by the top and bottom borders, leaving the red stripe with diagonal corners, as you can see in this fiddle:
http://jsfiddle.net/anp0e03k/
Is there any way correct way to fix this?
The only thing that I can think is to add a div inside with red background and negative margins on top and bottom, but it seems to be an overkill and would love to find something that doesn't ruins the html semantic.
Apply the left border to a :before pseudo element of the div and remove the divs left border.
Compatibility: All modern browsers and IE8 +
Give the :before
height: 100% to span the entire height of your div
margin-top: -1px to overlap the top border
padding-bottom: 2px to overlap the bottom border
Then use either
position: absolute on the :before with position: relative on the div like this example:
body {
background-color: #c2c2c2;
}
div {
margin: 50px;
background-color: #FFF;
border: 1px solid #939393;
height: 50px;
width: 200px;
border-left: none;
position: relative;
}
div:before {
content: '';
display: block;
border-left: 4px solid red;
height: 100%;
margin-top: -1px;
padding-bottom: 2px;
position: absolute;
top: 0;
left: 0;
}
<div>
</div>
or
display: inline-block for the :before like this example:
Note: You will probably want to use vertical-align: top / middle / bottom for the :before. This example uses the value top.
body {
background-color: #c2c2c2;
}
div {
margin: 50px;
background-color: #FFF;
border: 1px solid #939393;
height: 50px;
width: 200px;
border-left: none;
}
div:before {
content: '';
display: inline-block;
border-left: 4px solid red;
height: 100%;
margin-top: -1px;
padding-bottom: 2px;
vertical-align: top;
}
<div>
There is text in this
</div>
Final result

CSS Hyperbola Shape

I've seen all kinds of shapes from tvs to eggs to simple triangles. But how would one make a hyperbolic shape, filled in similar to this nuclear tower shape?
How about using a border-radius with :before and :after pseudo elements?
Demo
Here am using a wrapper element with a class - .wrap and than am nesting a child element with a class - .object, now I will break up the selectors explanation for you, first, am assigning position: relative; for the parent element so that the absolute positioned child elements don't fly out in the wild.. second is I am using an element with overflow: hidden; which is important so that the rounded pseudo elements are hidden..
And at last, I use :before and :after pseudo elements and position them using absolute, and than we have to set it correctly using top, left, right properties respectively.
<div class="wrap">
<div class="object"></div>
</div>
.wrap {
position:relative;
}
.object {
margin: 100px;
position: relative;
overflow: hidden;
background: #fafafa;
width: 180px;
height: 215px;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.object:before,
.object:after {
content: "";
background: #fff;
position: absolute;
top: -53px;
width: 300px;
height: 320px;
border-radius: 300px;
}
.object:before {
left: -263px;
border-right: 1px solid #aaa;
}
.object:after {
right: -263px;
border-left: 1px solid #aaa;
}

CSS: outline-offset alternative for IE?

I'm using the following code for the 2 borders of different colors, and space between the borders. I'm using the property outline-offset for the space between the borders. However it is not supported in IE (not even IE9).
Is there any alternate solution which works in the IE as well, without adding another div in the html.
HTML:
<div class="box"></div>
CSS:
.box{
width: 100px;
height: 100px;
margin: 100px;
border: 2px solid green;
outline:2px solid red;
outline-offset: 2px;
}
The height and width is not fixed, i have just used for the example.
JSFiddle:
http://jsfiddle.net/xyXKa/
Here are two solutions. The first is IE8+ compatible, utilizing pseudoelements. View it on JSFiddle here.
HTML:
<div class="box"></div>
CSS:
.box {
position: relative;
width: 100px;
height: 100px;
margin: 100px;
border: 2px solid green;
}
.box:after {
content: "";
position: absolute;
top: -6px;
left: -6px;
display: block;
width: 108px;
height: 108px;
border: 2px solid red;
}
​
The second idea I have is a non-semantic solution, but gives you IE6+ support. View it on JSFiddle here.
HTML:
<div class="outer-box"><div class="inner-box"></div></div>
​
CSS:
.outer-box {
width: 104px;
height: 104px;
margin: 100px;
border: 2px solid red;
padding: 2px;
}
.inner-box {
width: 100px;
height: 100px;
border: 2px solid green;
}
​
Oh woops, I just saw that you requested leaving just a single div. Well, that first solution fits those requirements!
Some more solutions. I've used them successfully:
1.
.box {
outline:2px solid green;
border:2px solid transparent;
box-shadow: 0 0 0 2px red inset;
}
Restriction of this solution: "outline" property ignores "border-radius" one.
2.
.box {
border: 2px solid green;
box-shadow: 0 0 0 2px #fff inset, 0 0 0 4px red inset;
}
Restriction of this solution: space between red and green borders can't be transparent because red box-shadow will be visible through it. So, any solid color needed, I've set #fff.
My issues with other solutions toward this end:
"outline-offset" is not compatible with IE; pseudoelements method requires absolute positioning and pixel ratios (no good for my responsive design); inset box-shadow does not display over an image.
Here is the fix I used to responsively frame images in an IE compatible way:
.container img {
border:2px solid white;
outline:4px solid red;
background-color: green;
padding: 2px;
}
"outline" defines the outer border, "border" defines the space in between, while the inner border is actually the background color with padding determining its width.
In cases where you're styling the ::focus pseudo-class, you won't have the luxury of using ::after or ::before pseudo-class as those methods are only effective on container elements (see W3C spec. for more information).
A cross-browser solution to give-off that offsetting effect is to use box-sizing, border, and padding.
You simply negate and alternate the padding and border width values.
Default / base styles:
input[type="text"] {
...
padding:10px;
border:1px solid grey;
}
Pseudo-class styles:
input[type="text"]:focus {
padding:8px;
border:3px solid red;
}