Circle with two borders - css

How can I style a a circle (a div) with two borders responsively so that it reacts to a container's size?
Suppose circles like this for example:
Here is a working CSS for a circle:
div.circle {
width: 90%;
height: 0;
padding-bottom: 90%;
margin: auto;
float: none;
border-radius: 50%;
border: 1px solid green;
background: pink;
}
<div class="circle"></div>
How can I add a border with two colors? I tried outline but it came out as a rectangle. I tried to place another div inside the circle div and use background color but I can't align the inner div vertically.

I'd suggest, with the following HTML:
<div></div>
The CSS:
div {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red;
}
div {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red;
}
<div></div>
JS Fiddle demo.
The box-shadow gives the outermost ring of colour, the border gives the white 'inner-border'.
Alternatively, you can use a box-shadow with the inset keyword, and use the box-shadow to generate the 'inner-border' and use the border as the outermost border:
div {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid red;
box-shadow: inset 0 0 0 5px white;
}
div {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid red;
box-shadow: inset 0 0 0 5px white;
}
<div></div>
JS Fiddle demo.
Obviously, adjust the dimensions to your own taste and circumstances.
Using the box-shadow to generate the outermost border, however, allows for multiple borders (alternating red and white in the following example):
div {
width: 20em;
height: 20em;
margin: 20px;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red, 0 0 0 10px white, 0 0 0 15px red;
}
div {
width: 20em;
height: 20em;
margin: 20px;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red, 0 0 0 10px white, 0 0 0 15px red;
}
<div></div>
JS Fiddle demo.

There are already two very good answers on this thread but here are a couple of more approaches to make this thread more complete with all possible approaches. The output produced by these are also responsive.
Using a pseudo-element:
You can use a pseudo-element that is smaller in size than the parent and position it absolutely within the parent. When the background is added to the pseudo-element and a border is added to the parent it looks like there is a gap between the border and the background. If the gap needs to be transparent then we need not add any background on the parent. If the gap needs to be of a solid color (that is, it needs to look like a second border) then a border of that color and required width should be added to the pseudo-element.
While using this approach, the inner area can also have image or a gradient as the fill (background).
.circle {
position: relative;
height: 200px;
width: 200px;
text-align: center;
line-height: 200px;
color: white;
border-radius: 50%;
border: 2px solid brown;
}
.circle:after {
position: absolute;
content: '';
top: 4px;
left: 4px;
height: calc(100% - 8px);
width: calc(100% - 8px);
border-radius: inherit;
background: brown;
z-index: -1;
}
.circle.white:after {
top: 0px;
left: 0px;
border: 4px solid white;
}
.circle.image:after {
background: url(http://lorempixel.com/200/200/abstract/4);
}
/* Just for demo */
div {
float: left;
margin-right: 10px;
transition: all 1s;
}
div:hover{
height: 250px;
width: 250px;
}
body {
background: url(http://lorempixel.com/500/500/nature/3);
background-size: cover;
}
<div class='circle'>Hello!</div>
<div class='circle white'>Hello!</div>
<div class='circle image'>Hello!</div>
Using Radial Gradients:
This is also a possible approach but has very low browser support and hence it is not recommended but the idea could be of use elsewhere. Essentially what is done is that a radial-gradient (circular shaped) is added to the element such that it leaves a transparent or a solid colored gap (extra border) between the solid background color and the actual border.
.circle{
height: 200px;
width: 200px;
text-align: center;
line-height: 200px;
color: white;
border-radius: 50%;
border: 2px solid brown;
background: radial-gradient(circle at center, brown 66.5%, transparent 68%);
}
.circle.white{
background: radial-gradient(circle at center, brown 66.5%, white 68%);
}
/* Just for demo */
div{
float: left;
margin-right: 10px;
transition: all 1s;
}
div:hover{
height: 250px;
width: 250px;
}
body{
background: url(http://lorempixel.com/500/500/nature/3);
background-size: cover;
}
<div class='circle'>Hello!</div>
<div class='circle white'>Hello!</div>

Another approach would be to use the background-clip property. It wont allow you to choose the color of the innner border but it will show the background in that gap :
div {
width: 150px;
height: 150px;
padding:2px;
border-radius: 50%;
background: #DD4814;
border: 2px solid #DD4814;
background-clip: content-box;
margin:0 auto;
}
/** FOR THE DEMO **/
body {background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size: cover;}
<div></div>
Note that you control the gap size with the padding value.

Here is a fiddle where I draw one circle with a border and box-shadow to create the outer circle effect https://jsfiddle.net/salientknight/k18fmepL/1/
Tested and works in Chrome, Safari and Opera -- Fails in Firefox if text gets too large Good for about 3 characters font size 1em then height and width get out of sync -- will work in FireFox with a fixed size height and width...
<!-- Inside H1 -->
<h1><p class='circleBlue'>10000%</p></h1>
<!-- Regular -->
<p class='circleBlue'>10000%</p>
p.circleBlue{
display: inline-flex;
align-items: center;
justify-content: center;
background-color: #159fda;
border: 5px Solid #fff;
color: #fff;
min-width: 1em;
border-radius: 50%;
vertical-align: middle;
padding:20px;
box-shadow: 0px -0px 0px 3px #159fda;
-webkit-box-shadow: 0px -0px 0px 3px #159fda;
-moz-box-shadow: 0px -0px 0px 3px #159fda;
margin:5px;
}
p.circle:before{
content:'';
float: left;
width: auto;
padding-bottom: 100%;
}
update I could not get this to work with a variety of text sizes and in all browsers so I added some js. I'm pasting it here so their is one complete solution all together. changesSizes is a function that makes sure that height and width always match... first checking which is bigger and then setting the value of both to the larger of the two (yes one of these assignments is redundant but it gives me peace of mind). The final effect is that I can add content of many shapes and sizes. The only real limitation I have found is taste.
changeSizes(".circleBlue");
//changeSizes(".circleGreen");
//changeSizes(".circleOrange");
---------
function changeSizes(cirlceColor){
var circle = $(cirlceColor);
circle.each(function(){
var cw = $(this).width();
var ch = $(this).height();
if(cw>ch){
$(this).width(cw);
$(this).height(cw);
}else{
$(this).width(ch);
$(this).height(ch);
}
});
}
Example:

Related

Unwanted border-radius artefact with box-shadow spread

Goal is a borderless circle with a soft edge, containing text or other elements. How do I get rid of the thin black border line in the following example? I've tried adding a border with the same or transparent color. It can be done with 1px x 1px and large spread, but I want to put stuff inside.
body { background: black; }
div {
width: 50px;
height: 50px;
margin: 50px;
padding: 50px;
border-radius: 50%;
background: white;
box-shadow: 0 0 10px 10px white;
}
<div>some text</div>
do it with a radial-gradient()
body { background: black; }
div {
width: 50px;
height: 50px;
margin: 50px;
padding: 70px;
border-radius: 50%;
background: radial-gradient(farthest-side,white calc(100% - 15px),transparent );
}
<div>some text</div>

Spiky left border in css

Suppose I have an element in display: block with property left-margin: solid 3px black.
How do I make the border three pixels at the top left and one pixel at the bottom left? Here's a diagram of what I mean.
Usingborder-image:
b {
display: block;
width: 200px;
height: 100px;
background: #ccc;
border-left: solid 3px;
border-image: linear-gradient(to bottom right, #000 50%, #fff 63%) 0 0 0 100% / 0 0 0 3px
}
<b></b>
In below case i have used :after to add border effect by adding skew
.parent {
border: 1px solid black;
width: 200px;
height: 100px;
position: relative;
overflow: hidden;
margin: 20px;
}
.parent.left-border {
border: 0;
border-left: 1px solid black;
}
.parent:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 3px;
background: black;
-webkit-transform: skewX(-2deg);
transform: skewX(-2deg);
bottom: 0;
transform-origin: top;
}
<div class="parent"></div>
<div class="parent left-border"></div>

how to add box shadow to half of its height

I am trying add shadow to a div. shadow should be at top and half of its height from top ( to both left and right side), someone please help me.
.test {
width: 200px;
height: 200px;
margin: 10px;
border: solid 1px red;
position: relative;
background-color: white;
}
you can increase offset and reduce size of box shadow and draw 2 of them.
https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow
/* offset-x | offset-y | blur-radius | spread-radius | color */
<spread-radius>
This is a fourth value. Positive values will cause the shadow to expand and grow bigger, negative values will cause the shadow to shrink. If not specified, it will be 0 (the shadow will be the same size as the element).
#test {
width: 200px;
height: 200px;
margin: 10px;
border: solid 1px red;
position: relative;
background-color: white;
box-shadow: -50px -50px 5px -50px, 50px -50px 5px -50px
}
<div id="test"></div>
This could be a simple way to do it, quite a few possibilities.
.parent{
width: 200px;
height: 200px;
margin: 10px;
position: relative;
}
.test {
z-index: 2;
width: 100%;
position: relative;
height: 100%;
border: solid 1px red;
background-color: white;
}
.halfshadow{
position: absolute;
width: 100%;
top: 0;
height: 50%;
box-shadow: 1px 0px 10px rgba(0, 0, 0, 0.5);
}
<div class="parent">
<div class="test"></div>
<div class="halfshadow"></div>
</div>

Offset border effect in pure css

I am trying to create an offset border effect. Can this be done with pure css.
These are buttons so will be different sizes and colours.
I use pseudo-element :after to create offset border effect.
body {
background: black;
padding: 30px;
}
div {
background: white;
height: 75px;
width: 175px;
position: relative;
}
div:after {
content: '';
background: transparent;
border: 1px solid white;
top: 7px;
right: 7px;
bottom: -7px;
left: -7px;
position: absolute;
z-index: -1;
}
<div></div>
Update
As web-tiki pointed out in comments on this answer, you can achieve the entire affect entirely with box-shadow. Take a look at their JSFiddle demo here: https://jsfiddle.net/5a0bvyup.
I'm going to leave my answer in the state I submitted it in because it does give some idea of how their implementation works (and if you look closely you'll see how their box-shadow differs from the one described below).
Note: In my answer I've made the foreground box red instead of white to demonstrate that this 'offset border' does not overlap the initial element. You'll need to change this back to white yourself.
The Left and Bottom Borders
You can achieve the left and bottom borders really easily with box-shadow. You simply need to create a solid shadow which matches the background colour, and then behind that add a second shadow which matches the foreground colour, offset by one pixel:
body {
background: black;
padding: 30px;
}
div {
background: red;
height: 72px;
width: 192px;
box-shadow: -2px 2px 0 5px black, -7px 7px 0 1px white;
}
<div></div>
The Top and Right Borders
You can then use pseudo-elements (::before and ::after) to fill in those extra borders:
body {
background: black;
padding: 30px;
}
div {
background: red;
height: 72px;
width: 192px;
box-shadow: -2px 2px 0 5px black, -7px 7px 0 1px white;
position: relative;
}
div::before {
background: white;
content: '';
position: absolute;
height: 1px;
width: 7px;
top: 6px;
right: 100%;
}
div::after {
background: white;
content: '';
position: absolute;
height: 7px;
width: 1px;
top: 100%;
right: 6px;
}
<div></div>

How can I get multiple borders with rounded corners? CSS

Any idea on how I can get round corners work with multiple borders?
The box will be dynamic, depending what will be inputed into the box, so I can't add static width or height.
body { background: #d2d1d0; }
#box {
border-radius: 15px;
background: #f4f4f4;
border: 1px solid #bbbbbb;
width: 100%;
height: 100%;
margin: 10px auto;
position: relative;
}
DIV#box, #box:before, #box:after {
-moz-border-radius: 15px;
border-radius: 15px;
}
#box:before {
border-radius: 15px;
border: 1px solid white;
width: 99%;
height: 94%;
content: '';
position: absolute;
}
#box:after {
border-radius: 15px;
content: '';
position: absolute;
border: 1px solid #bbbbbb;
width: 98%;
height: 90%;
left: 1px; top: 1px;
}
HTML
<div id="box">Hello World!!!!<br>THIS IS SECOND LINE - THERE MIGHT BE MORE LINES OF TEXT LATER ON.</div>
The problem I am currently having is when I stretch window not all borders stretch symmetrically, so how can I fix that? FYI I am currently interested getting CSS working in FF and Chrome.
There are a few ways to get multiple borders with round corners. I personally go for a method that uses shadows. For your html code you could do something like this.
The HTML
<div id="box">
Hello World!!!!<br>
THIS IS SECOND LINE - THERE MIGHT BE MORE LINES OF TEXT LATER ON.
</div>
The CSS
#box{
border-radius: 15px;
background: #f4f4f4;
border: 3px solid #bbbbbb;
box-shadow: 0 0 0 3px #8B2323,
0 0 0 6px #FF7F00,
0 0 0 9px #458B00;
width: 100%;
height: 100%;
margin: 10px auto;
position: relative;
}​
Demo: http://jsfiddle.net/GdSfh/
I suggest if you want to find out more on multiple borders please read my tutorial on Multiple borders in css as it has a few other methods that might help you in the future. If you want to find more about shadows please also refer to my tutorial Shadows in css.
<div id="box">
<p>Hello World!!!!<br>
THIS IS SECOND LINE - THERE MIGHT BE MORE LINES OF TEXT LATER ON.</p>
Above is for the HTML, below is for the CSS.
body { background: #d2d1d0; }
#box {
background: #F4F4F4;
border: 3px solid blue;
position: relative;
height: 100%;
width: 100%;
}
#box p {
padding: 10px;
}
#box:before {
-moz-border-radius: 15px;
border-radius: 15px;
}
#box {
-moz-border-radius: 9px;
border-radius: 9px;
}
#box:after {
-moz-border-radius: 12px;
border-radius: 12px;
}
#box:before {
border: 3px solid red;
content: '';
position: absolute;
top: -9px;
right: -9px;
bottom: -9px;
left: -9px;
}
#box:after {
border: 3px solid green;
content: '';
position: absolute;
top: -6px;
right: -6px;
bottom: -6px;
left: -6px;
}
http://jsfiddle.net/H7QjP/7/ [Live Example with code]
Like this. Credits to to jnpcl for giving me something to build off, I just changed the border radii so that they lined up a little tighter.
The only CSS solution I can offer is limited to a double border, with the space between those borders the same colour as the background of the bordered element, for example the html:
<div id="box">
<p>Some content</p>
</div>
Coupled to the css:
#box {
border: 10px double #f90;
border-radius: 1.5em;
padding: 1em;
color: #000;
background-color: #ffa;
}
Gives a JS Fiddle demo...
Just found another cleaner way to do it
Live demo and code here: http://jsfiddle.net/mYGsh/1/
[This demo has 8 different borders]
The HTML:
<p class="gradient-border">This is an example of a box with a gradient border. This example will currently work in Mozilla and Firefox browsers.</p>
The CSS:
.gradient-border {
border: 8px solid #000;
-moz-border-radius: 12px;
-moz-border-bottom-colors: #555 #FF0000 #777 #888 #00FF00 #aaa #0000FF #ccc;
-moz-border-top-colors: #555 #FF0000 #777 #888 #00FF00 #aaa #0000FF #ccc;
-moz-border-left-colors: #555 #FF0000 #777 #888 #00FF00 #aaa #0000FF #ccc;
-moz-border-right-colors: #555 #FF0000 #777 #888 #00FF00 #aaa #0000FF #ccc;
padding: 5px 5px 5px 15px;
}
I came up with this code for a linked image using an inline block border wrapped in a box shadow with a 2nd box shadow for a 2 layer border with a shadow, 3 layers total & No css styling needed.
inline block creates the 1st border then a box shadow creates the 2nd & icing on the cake adds the shadow followed by the rounding code that captures the inline block border as well.
To use it for text, just change image style to span style & replace image src with text & remove the link if you don't need it.
<a href="http://url" target="_blank">
<img style="display:inline-block;padding:1px;padding-left:2px;padding-top:10px;padding-bottom:10px;width:130px;border: 5px solid#001aff; box-shadow:0px 0px 0px 1px #000000, 0px 0px 25px 14px #001EA3;background: #000000;
border-radius: 5px;
-moz-border-radius: 5px
-khtml-border-radius: 5px;
-webkit-border-radius: 5px;"
src="http://image.gif" height="41" align="absmiddle" /></a>
I suggest using the excellent jQuery round corner plugin.
http://jquery.malsup.com/corner/
It's supported in all browsers including IE. It draws corners in IE using nested divs (no images). It also has native border-radius rounding in browsers that support it (Opera 10.5+, Firefox, Safari, and Chrome). So in those browsers the plugin simply sets a css property instead.
Here's How to use it
You need to include the jQuery and the Corner js script before </body>. Then write your jQuery like $('div, p').corner('10px'); and place before ''. So your html will look like the below code. Here i'm making round corners for all div and p tags. If you want to do it for specific id or class then you can do something like $('#myid').corner();
<body>
<div class="x"></div>
<p class="y"></p>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://github.com/malsup/corner/raw/master/jquery.corner.js?v2.11"></script>
<script>$('div, p').corner();</script>
</body>
Check working example at http://jsfiddle.net/VLPpk/1
To add to David's solution :
The double border is fairly limited. However, if you are willing to modify your markup, you can solve your problem by doing :
<div id="outerbox">
<div id="box">Hello World!!!!<br>THIS IS SECOND LINE - THERE MIGHT BE MORE LINES OF TEXT LATER ON.</div>
</div>
In your CSS :
#box
{
border-radius: 15px;
border: 1px solid #bbbbbb;
width: 100%;
height: 100%;
position: relative;
}
#outerbox
{
padding:10px;
border : 1px solid #bbbbbb;
background: #f4f4f4;
border-radius: 15px;
}
This will allow you to set the background color between the two borders to what you want.
It will also let you play with the width of your border.
http://jsfiddle.net/rPsdK/1/
Try this one:
Live Demo
<style type="text/css">
body { background: #d2d1d0; }
#box {
background: #F4F4F4;
border: 1px solid blue;
position: relative;
height: 100%;
width: 100%;
}
#box p { padding: 10px; }
#box, #box:before, #box:after {
-moz-border-radius: 15px;
border-radius: 15px;
}
#box:before {
border: 1px solid red;
content: '';
position: absolute;
top: -7px;
right: -7px;
bottom: -7px;
left: -7px;
}
#box:after {
border: 1px solid green;
content: '';
position: absolute;
top: -4px;
right: -4px;
bottom: -4px;
left: -4px;
}
</style>
<div id="box">
<p>Hello World!!!!<br>
THIS IS SECOND LINE - THERE MIGHT BE MORE LINES OF TEXT LATER ON.</p>
</div>

Resources