[html] Outline radius?

Is there anyway of getting rounded corners on the outline of a div element, similar to border-radius?

This question is related to html css

The answer is


As far as I know, the Outline radius is only supported by Firefox and Firefox for android.

-moz-outline-radius: 1em;

enter image description here


I usually accomplish this using the :after pseudo-element:

of course it depends on usage, this method allows control over individual borders, rather than using the hard shadow method.

you could also set -1px offsets and use a background linear gradient (no border) for a different effect once again.

_x000D_
_x000D_
body {_x000D_
  margin: 20px;_x000D_
}_x000D_
_x000D_
a {_x000D_
  background: #999;_x000D_
  padding: 10px 20px;_x000D_
  border-radius: 5px;_x000D_
  text-decoration: none;_x000D_
  color: #fff;_x000D_
  position: relative;_x000D_
  border: 2px solid #000;_x000D_
}_x000D_
_x000D_
a:after {_x000D_
  content: '';_x000D_
  display: block;_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  border-radius: 5px;_x000D_
  border: 2px solid #ccc;_x000D_
}
_x000D_
<a href="#">Button</a>
_x000D_
_x000D_
_x000D_


I wanted some nice focus accessibility for dropdown menus in a Bootstrap navbar, and was pretty happy with this:

_x000D_
_x000D_
     a.dropdown-toggle:focus {_x000D_
         display: inline-block;_x000D_
         box-shadow: 0 0 0 2px #88b8ff;_x000D_
         border-radius: 2px;_x000D_
     }
_x000D_
<a href="https://stackoverflow.com" class="dropdown-toggle">Visit Stackoverflow</a>
_x000D_
_x000D_
_x000D_


The simple answer to the basic question is no. The only cross-browser option is to create a hack that accomplishes what you want. This approach does carry with it certain potential issues when it comes to styling pre-existing content, but it provides for more customization of the outline (offset, width, line style) than many of the other solutions.

On a basic level, consider the following static example (run the snippent for demo):

_x000D_
_x000D_
.outline {_x000D_
    border: 2px dotted transparent;_x000D_
    border-radius: 5px;_x000D_
    display: inline-block;_x000D_
    padding: 2px;_x000D_
    margin: -4px;_x000D_
}_x000D_
_x000D_
/* :focus-within does not work in Edge or IE */_x000D_
.outline:focus-within, .outline.edge {_x000D_
    border-color: blue;_x000D_
}_x000D_
_x000D_
br {_x000D_
    margin-bottom: 0.75rem;_x000D_
}
_x000D_
<h3>Javascript-Free Demo</h3>_x000D_
<div class="outline edge"><input type="text" placeholder="I always have an outline"/></div><br><div class="outline"><input type="text" placeholder="I have an outline when focused"/></div> *<i>Doesn't work in Edge or IE</i><br><input type="text" placeholder="I have never have an outline" />_x000D_
<p>Note that the outline does not increase the spacing between the outlined input and other elements around it. The margin (-4px) compensates for the space that the outlines padding (-2px) and width (2px) take up, a total of 4px.</p>
_x000D_
_x000D_
_x000D_

Now, on a more advanced level, it would be possible to use JavaScript to bootstrap elements of a given type or class so that they are wrapped inside a div that simulates an outline on page load. Furthermore, event bindings could be established to show or hide the outline on user interactions like this (run the snippet below or open in JSFiddle):

_x000D_
_x000D_
h3 {_x000D_
  margin: 0;_x000D_
}_x000D_
_x000D_
div {_x000D_
  box-sizing: border-box;_x000D_
}_x000D_
_x000D_
.flex {_x000D_
  display: flex;_x000D_
}_x000D_
_x000D_
.clickable {_x000D_
  cursor: pointer;_x000D_
}_x000D_
_x000D_
.box {_x000D_
  background: red;_x000D_
  border: 1px solid black;_x000D_
  border-radius: 10px;_x000D_
  height: 5rem;_x000D_
  display: flex;_x000D_
  align-items: center;_x000D_
  text-align: center;_x000D_
  color: white;_x000D_
  font-weight: bold;_x000D_
  padding: 0.5rem;_x000D_
  margin: 1rem;_x000D_
}
_x000D_
<h3>Javascript-Enabled Demo</h3>_x000D_
<div class="flex">_x000D_
  <div class="box outline-me">I'm outlined because I contain<br>the "outline-me" class</div>_x000D_
  <div class="box clickable">Click me to toggle outline</div>_x000D_
</div>_x000D_
<hr>_x000D_
<input type="text" placeholder="I'm outlined when focused" />_x000D_
_x000D_
<script>_x000D_
// Called on an element to wrap with an outline and passed a styleObject_x000D_
// the styleObject can contain the following outline properties:_x000D_
//   style, width, color, offset, radius, bottomLeftRadius,_x000D_
//  bottomRightRadius, topLeftRadius, topRightRadius_x000D_
// It then creates a new div with the properties specified and _x000D_
// moves the calling element into the div_x000D_
// The newly created wrapper div receives the class "simulated-outline"_x000D_
Element.prototype.addOutline = function (styleObject, hideOutline = true) {_x000D_
    var element = this;_x000D_
_x000D_
    // create a div for simulating an outline_x000D_
    var outline = document.createElement('div');_x000D_
_x000D_
    // initialize css formatting_x000D_
    var css = 'display:inline-block;';_x000D_
_x000D_
    // transfer any element margin to the outline div_x000D_
    var margins = ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'];_x000D_
    var marginPropertyNames = { _x000D_
        marginTop: 'margin-top',_x000D_
        marginBottom: 'margin-bottom',_x000D_
        marginLeft: 'margin-left',_x000D_
        marginRight: 'margin-right'_x000D_
    }_x000D_
    var outlineWidth = Number.parseInt(styleObject.width);_x000D_
    var outlineOffset = Number.parseInt(styleObject.offset);_x000D_
    for (var i = 0; i < margins.length; ++i) {_x000D_
        var computedMargin = Number.parseInt(getComputedStyle(element)[margins[i]]);_x000D_
        var margin = computedMargin - outlineWidth - outlineOffset;_x000D_
        css += marginPropertyNames[margins[i]] + ":" + margin + "px;";_x000D_
    }_x000D_
    element.style.cssText += 'margin:0px !important;';_x000D_
    _x000D_
    // compute css border style for the outline div_x000D_
    var keys = Object.keys(styleObject);_x000D_
    for (var i = 0; i < keys.length; ++i) {_x000D_
        var key = keys[i];_x000D_
        var value = styleObject[key];_x000D_
        switch (key) {_x000D_
            case 'style':_x000D_
                var property = 'border-style';_x000D_
                break;_x000D_
            case 'width':_x000D_
                var property = 'border-width';_x000D_
                break;_x000D_
            case 'color':_x000D_
                var property = 'border-color';_x000D_
                break;_x000D_
            case 'offset':_x000D_
                var property = 'padding';_x000D_
                break;_x000D_
            case 'radius':_x000D_
                var property = 'border-radius';_x000D_
                break;_x000D_
            case 'bottomLeftRadius':_x000D_
                var property = 'border-bottom-left-radius';_x000D_
                break;_x000D_
            case 'bottomRightRadius':_x000D_
                var property = 'border-bottom-right-radius';_x000D_
                break;_x000D_
            case 'topLeftRadius':_x000D_
                var property = 'border-top-left-radius-style';_x000D_
                break;_x000D_
            case 'topRightRadius':_x000D_
                var property = 'border-top-right-radius';_x000D_
                break;_x000D_
        }_x000D_
        css += property + ":" + value + ';';_x000D_
    }_x000D_
    _x000D_
    // apply the computed css to the outline div_x000D_
    outline.style.cssText = css;_x000D_
    _x000D_
    // add a class in case we want to do something with elements_x000D_
    // receiving a simulated outline_x000D_
    outline.classList.add('simulated-outline');_x000D_
    _x000D_
    // place the element inside the outline div_x000D_
    var parent = element.parentElement;_x000D_
    parent.insertBefore(outline, element);_x000D_
    outline.appendChild(element);_x000D_
_x000D_
    // determine whether outline should be hidden by default or not_x000D_
    if (hideOutline) element.hideOutline();_x000D_
}_x000D_
_x000D_
Element.prototype.showOutline = function () {_x000D_
    var element = this;_x000D_
    // get a reference to the outline element that wraps this element_x000D_
    var outline = element.getOutline();_x000D_
    // show the outline if one exists_x000D_
    if (outline) outline.classList.remove('hide-outline');_x000D_
}_x000D_
_x000D_
_x000D_
Element.prototype.hideOutline = function () {_x000D_
    var element = this;_x000D_
    // get a reference to the outline element that wraps this element_x000D_
    var outline = element.getOutline();_x000D_
    // hide the outline if one exists_x000D_
    if (outline) outline.classList.add('hide-outline');_x000D_
}_x000D_
_x000D_
// Determines if this element has an outline. If it does, it returns the outline_x000D_
// element. If it doesn't have one, return null._x000D_
Element.prototype.getOutline = function() {_x000D_
    var element = this;_x000D_
    var parent = element.parentElement;_x000D_
    return (parent.classList.contains('simulated-outline')) ? parent : null;_x000D_
}_x000D_
_x000D_
// Determines the visiblity status of the outline, returning true if the outline is_x000D_
// visible and false if it is not. If the element has no outline, null is returned._x000D_
Element.prototype.outlineStatus = function() {_x000D_
    var element = this;_x000D_
    var outline = element.getOutline();_x000D_
    if (outline === null) {_x000D_
        return null;_x000D_
    } else {_x000D_
        return !outline.classList.contains('hide-outline');_x000D_
    }_x000D_
}_x000D_
_x000D_
// this embeds a style element in the document head for handling outline visibility_x000D_
var embeddedStyle = document.querySelector('#outline-styles');_x000D_
if (!embeddedStyle) {_x000D_
    var style = document.createElement('style');_x000D_
    style.innerText = `_x000D_
        .simulated-outline.hide-outline {_x000D_
            border-color: transparent !important;_x000D_
        }_x000D_
    `;_x000D_
    document.head.append(style);_x000D_
}_x000D_
_x000D_
_x000D_
/*########################## example usage ##########################*/_x000D_
_x000D_
// add outline to all elements with "outline-me" class_x000D_
var outlineMeStyle = {_x000D_
    style: 'dashed',_x000D_
    width: '3px',_x000D_
    color: 'blue',_x000D_
    offset: '2px',_x000D_
    radius: '5px'_x000D_
};_x000D_
document.querySelectorAll('.outline-me').forEach((element)=>{_x000D_
  element.addOutline(outlineMeStyle, false);_x000D_
});_x000D_
_x000D_
_x000D_
// make clickable divs get outlines_x000D_
var outlineStyle = {_x000D_
    style: 'double',_x000D_
    width: '4px',_x000D_
    offset: '3px',_x000D_
    color: 'red',_x000D_
    radius: '10px'_x000D_
};_x000D_
document.querySelectorAll('.clickable').forEach((element)=>{_x000D_
    element.addOutline(outlineStyle);_x000D_
    element.addEventListener('click', (evt)=>{_x000D_
        var element = evt.target;_x000D_
        (element.outlineStatus()) ? element.hideOutline() : element.showOutline();_x000D_
    });_x000D_
});_x000D_
_x000D_
_x000D_
// configure inputs to only have outline on focus_x000D_
document.querySelectorAll('input').forEach((input)=>{_x000D_
    var outlineStyle = {_x000D_
        width: '2px',_x000D_
        offset: '2px',_x000D_
        color: 'black',_x000D_
        style: 'dotted',_x000D_
        radius: '10px'_x000D_
    }_x000D_
    input.addOutline(outlineStyle);_x000D_
    input.addEventListener('focus', (evt)=>{_x000D_
        var input = evt.target;_x000D_
        input.showOutline();_x000D_
    });_x000D_
    input.addEventListener('blur', (evt)=>{_x000D_
        var input = evt.target;_x000D_
        input.hideOutline();_x000D_
    });_x000D_
});_x000D_
</script>
_x000D_
_x000D_
_x000D_

In closing, let me reiterate, that implementing this approach may require more styling than what I have included in my demos, especially if you have already styled the element you want outlined.


If you want to get an embossed look you could do something like the following:

_x000D_
_x000D_
.embossed {_x000D_
  background: #e5e5e5;_x000D_
  height: 100px;_x000D_
  width: 200px;_x000D_
  border: #FFFFFF solid 1px;_x000D_
  outline: #d0d0d0 solid 1px;_x000D_
  margin: 15px;_x000D_
}_x000D_
_x000D_
.border-radius {_x000D_
  border-radius: 20px 20px 20px 20px;_x000D_
  -webkit-border-radius: 20px;_x000D_
  -moz-border-radius: 20px;_x000D_
  -khtml-border-radius: 20px;_x000D_
}_x000D_
_x000D_
.outline-radius {_x000D_
  -moz-outline-radius: 21px;_x000D_
}
_x000D_
<div class="embossed"></div>_x000D_
<div class="embossed border-radius"></div>_x000D_
<div class="embossed border-radius outline-radius">-MOZ ONLY</div>
_x000D_
_x000D_
_x000D_

I have not found a work around to have this work in other browsers.

EDIT: The only other way you can do this is to use box-shadow, but then this wont work if you already have a box shadow on that element.


Old question now, but this might be relevant for somebody with a similar issue. I had an input field with rounded border and wanted to change colour of focus outline. I couldn't tame the horrid square outline to the input control.

So instead, I used box-shadow. I actually preferred the smooth look of the shadow, but the shadow can be hardened to simulate a rounded outline:

_x000D_
_x000D_
 /* Smooth outline with box-shadow: */_x000D_
    .text1:focus {_x000D_
        box-shadow: 0 0 3pt 2pt red;_x000D_
    }_x000D_
_x000D_
    /* Hard "outline" with box-shadow: */_x000D_
    .text2:focus {_x000D_
        box-shadow: 0 0 0 2pt red;_x000D_
    }
_x000D_
<input type=text class="text1"> _x000D_
<br>_x000D_
<br>_x000D_
<br>_x000D_
<br>_x000D_
<input type=text class="text2">
_x000D_
_x000D_
_x000D_


I just found a great solution for this, and after looking at all the responses so far, I haven't seen it posted yet. So, here's what I did:

I created a CSS Rule for the class and used a pseudo-class of :focus for that rule. I set outline: none to get rid of that default light-blue non-border-radius-able 'outline' that Chrome uses by default. Then, in that same :focus pseudo-class, where that outline no longer exists, I added my radius and border properties. Leading to the following

outline: none;
border-radius: 5px;
border: 2px solid maroon;

to have a maroon-colored outline with a border radius that now appears when the element is tab-selected by the user.


COMBINING BOX SHADOW AND OUTLINE.

A slight twist on Lea Hayes answer I found

input[type=text]:focus {
    box-shadow: 0 0 0 1pt red;
    outline-width: 1px;
    outline-color: red;
}

gets a really nice clean finish. No jumping in size which you get when using border-radius


No. Borders sit on the outside of the element and on the inside of the box-model margin area. Outlines sit on the inside of the element and the box-model padding area ignores it. It isn't intended for aesthetics. It's just to show the designer the outlines of the elements. In the early stages of developing an html document for example, a developer might need to quickly discern if they have put all of the skeletal divs in the correct place. Later on they may need to check if various buttons and forms are the correct number of pixels apart from each other.

Borders are aesthetic in nature. Unlike outlines they are actually apart of the box-model, which means they do not overlap text set to margin: 0; and each side of the border can be styled individually.

If you're trying to apply a corner radius to outline I assume you are using it the way most people use border. So if you don't mind me asking, what property of outline makes it desirable over border?


I just set outline transparent.

input[type=text] {
  outline: rgba(0, 0, 0, 0);
  border-radius: 10px;
}

input[type=text]:focus {    
  border-color: #0079ff;
}

clip-path: circle(100px at center);

This will actually make clickable only circle, while border-radius still makes a square, but looks as circle.


Use this one: box-shadow: 0px 0px 0px 1px red;


There is the solution if you need only outline without border. It's not mine. I got if from Bootstrap css file. If you specify outline: 1px auto certain_color, you'll get thin outer line around div of certain color. In this case the specified width has no matter, even if you specify 10 px width, anyway it will be thin line. The key word in mentioned rule is "auto".
If you need outline with rounded corners and certain width, you may add css rule on border with needed width and same color. It makes outline thicker.


You're looking for something like this, I think.

div {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    border: 1px solid black;
    background-color: #CCC;
    height: 100px;
    width: 160px;
}

Edit

There is a Firefox-only -moz-outline-radius properly, but that won't work on IE/Chrome/Safari/Opera/etc. So, it looks like the most cross-browser-compatible way* to get a curved line around a border is to use a wrapper div:

_x000D_
_x000D_
div.inner {
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: 1px solid black;
  background-color: #CCC;
  height: 100px;
  width: 160px;
}

div.outer {
  display: inline-block;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: 1px solid red;
}
_x000D_
<div class="outer">
  <div class="inner"></div>
</div>
_x000D_
_x000D_
_x000D_


*aside from using images


We may see our wishes soonish by setting outline-style: auto It's on WebKits radar: http://trac.webkit.org/changeset/198062/webkit

See ya in 2030.


Try using padding and a background color for the border, then a border for the outline:

.round_outline {
  padding: 8px;
  background-color: white;
  border-radius: 50%;
  border: 1px solid black;
}

Worked in my case.


As others have said, only firefox supports this. Here is a work around that does the same thing, and even works with dashed outlines.

example

_x000D_
_x000D_
.has-outline {_x000D_
    display: inline-block;_x000D_
    background: #51ab9f;_x000D_
    border-radius: 10px;_x000D_
    padding: 5px;_x000D_
    position: relative;_x000D_
}_x000D_
.has-outline:after {_x000D_
  border-radius: 10px;_x000D_
  padding: 5px;_x000D_
  border: 2px dashed #9dd5cf;_x000D_
  position: absolute;_x000D_
  content: '';_x000D_
  top: -2px;_x000D_
  left: -2px;_x000D_
  bottom: -2px;_x000D_
  right: -2px;_x000D_
}
_x000D_
<div class="has-outline">_x000D_
  I can haz outline_x000D_
</div>
_x000D_
_x000D_
_x000D_


I like this way.

.circle:before {
   content: "";
   width: 14px;
   height: 14px;
   border: 3px solid #fff;
   background-color: #ced4da;
   border-radius: 7px;
   display: inline-block;
   margin-bottom: -2px;
   margin-right: 7px;
   box-shadow: 0px 0px 0px 1px #ced4da;
}

It will create gray circle with wit border around it and again 1px around border!


Similar to Lea Hayes above, but here's how I did it:

_x000D_
_x000D_
div {_x000D_
  background: #999;_x000D_
  height: 100px;_x000D_
  width: 200px;_x000D_
  border: #999 solid 1px;_x000D_
  border-radius: 10px;_x000D_
  margin: 15px;_x000D_
  box-shadow: 0px 0px 0px 1px #fff inset;_x000D_
}
_x000D_
<div></div>
_x000D_
_x000D_
_x000D_

No nesting of DIVs or jQuery necessary, Altho for brevity I have left out the -moz and -webkit variants of some of the CSS. You can see the result above