Raio do contorno?

473

Existe alguma maneira de obter cantos arredondados no contorno de um div element, semelhante a border-radius?

Marc Guerin
fonte
2
Bem, eu tenho uma caixa Div com uma 2px borda cinza com 20px border-radius, eu estava vagando se posso, então, uma 10px Outine em torno desse Border que segue o Border ao invés de ser quadrado
Marc Guerin
4
Essa é uma boa pergunta. Um elemento com border: 5px rede outline: 5px bluee border-radius: 5px, a borda é arredondada, mas o contorno é quadrado.
Matthew Rudy
4
Até agora, só podemos usá-lo no Firefox:-moz-outline-radius
Wojciech Bednarski
Deve ser parte de CSS3 ... Se eu pensar sobre isso - Eu odeio W3C: D
m93a
17
todos vocês precisam de um box-shadowna sua vida ..
Muhammad Umer

Respostas:

538

Pergunta antiga agora, mas isso pode ser relevante para alguém com um problema semelhante. Eu tinha um campo de entrada arredondado bordere queria mudar a cor do contorno do foco. Eu não poderia domesticar o quadrado horrível outlineao controle de entrada.

Então, em vez disso, usei box-shadow. Na verdade, eu preferia a aparência suave da sombra, mas a sombra pode ser reforçada para simular um contorno arredondado:

 /* Smooth outline with box-shadow: */
    .text1:focus {
        box-shadow: 0 0 3pt 2pt red;
    }

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

Lea Hayes
fonte
24
IMO, esta é a resposta que você está procurando. Eu fiz este método mas não se esqueçam transformando seu esboço a 0.
John Morton
2
Era exatamente isso que eu procurava e se encaixa ainda melhor do que um raio de contorno.
Zenexer
2
O exemplo de estrutura de tópicos não funciona. É apenas um retângulo sem raio de canto.
Erik Aigner
1
outline: 0quebra a acessibilidade da web; leia outlinenone.com
ianstarz
4
@ianstarz, quebra a acessibilidade quando você não fornece um estilo alternativo. box-shadowé o estilo alternativo (que, como apresentado aqui, é realmente muito parecido com a aparência outline).
ACJ
84

Eu costumo fazer isso usando o pseudo-elemento: after:

é claro que depende do uso, esse método permite o controle sobre bordas individuais, em vez de usar o método de sombra forte.

você também pode definir deslocamentos -1px e usar um gradiente linear de plano de fundo (sem borda) para obter um efeito diferente mais uma vez.

body {
  margin: 20px;
}

a {
  background: #999;
  padding: 10px 20px;
  border-radius: 5px;
  text-decoration: none;
  color: #fff;
  position: relative;
  border: 2px solid #000;
}

a:after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  border-radius: 5px;
  border: 2px solid #ccc;
}
<a href="#">Button</a>

monônimo
fonte
3
Uma versão modificada e um pouco mais espetacular: jsfiddle.net/rh6j3cdm .
Dávid Horváth
2
Não é possível fazer uma :: after pseudo para um campo de entrada
Simon Franzen
obrigado, isso funcionou MUITO bem com os contornos das consultas de pesquisa da react-sortable-tree!
Monarch Wadia
Eu gosto dessa solução porque é muito mais flexível que a box-shadowversão. Por exemplo, se você deseja que o "contorno" fique afastado do elemento (isto é, simulando outline-offset), isso se torna possível com esta técnica.
Kirk Woll
34

Semelhante a Lea Hayes acima, mas aqui está como eu fiz isso:

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

Nenhum aninhamento de DIVs ou jQuery é necessário, mas por uma questão de brevidade, deixei de fora as variantes -moz e -webkit de alguns dos CSS. Você pode ver o resultado acima

Heraldmonkey
fonte
6
Ele está falando sobre o ESBOÇO, não a fronteira ... "raio" do contorno
android.nick
5
correto, mas como o raio do contorno não está disponível, meu método fornece a aparência de uma borda e de um contorno. Esse é um efeito visual, portanto, a menos que o design de Marc seja especificado abaixo do pixel, o fato de ele realmente não usar a propriedade outline não faz diferença. E como é uma solução prática, eu gostaria de
receber
2
Isso funcionou muito bem. Eu não usei insete consegui o que queria.
Paul Schreiber
18

Eu queria uma boa acessibilidade de foco para menus suspensos em uma barra de navegação do Bootstrap e fiquei muito feliz com isso:

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

StackOverflowUser
fonte
16

Você está procurando algo assim , eu acho.

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

Editar

Existe apenas um Firefox -moz-outline-radiuscorretamente, mas isso não funciona no IE / Chrome / Safari / Opera / etc. Portanto, parece que a maneira mais compatível com vários navegadores * para obter uma linha curva em torno de uma borda é usar uma div wrapper:

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;
}
<div class="outer">
  <div class="inner"></div>
</div>


* além de usar imagens

Matt Ball
fonte
20
Não, eu sei como obter o Border Radius Eu estava vagando se você pudesse ter um esboço-Raio
Marc Guerin
Significado o que exatamente? Um contorno mais grosso, assim? jsfiddle.net/mattball/NXZFv/1
Matt Bola
10
@ Matt: um contorno curvo em vez de uma borda , obviamente. Veja w3.org/TR/CSS21/ui.html#dynamic-outlines
Joey
Bem, eu tenho uma caixa Div com uma borda cinza de 2px com raio de borda de 20px, eu estava vagando se posso então ter um Outp 10px em torno dessa borda que segue a borda em vez de ser quadrado.
Marc Guerin
1
Apenas um complemento para o seu mate código, se você deixar cair o raio fronteira alguns px sobre a caixa interna do canto, em seguida, torna-se muito mais apertado, obrigado pela sua ajuda
Marc Guerin
7

Acabei de encontrar uma ótima solução para isso e, depois de analisar todas as respostas até agora, ainda não a vi postada. Então, aqui está o que eu fiz:

Criei uma regra de CSS para a classe e usei uma pseudo-classe de: focus para essa regra. Eu decidi outline: noneme livrar desse 'contorno' padrão em azul claro e sem borda que o Chrome usa por padrão. Então, na mesma :focuspseudo-classe, onde esse contorno não existe mais, adicionei minhas propriedades de raio e borda. Levando ao seguinte

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

ter um contorno de cor marrom com um raio da borda que agora aparece quando o elemento é selecionado por tabulação pelo usuário.

Branden Pinney
fonte
Usar "estrutura de tópicos: 0" ou "estrutura de tópicos: nenhuma" é considerado uma prática ruim e prejudica a acessibilidade do usuário. Neste ponto, não tenho uma correção, mas aqui está um artigo sobre por que você não deve remover o esboço, se possível, e o que fazer se for absolutamente necessário. Nunca remova contornos CSS
AndrewBrntt
5

Se você deseja obter uma aparência em relevo, pode fazer algo como o seguinte:

.embossed {
  background: #e5e5e5;
  height: 100px;
  width: 200px;
  border: #FFFFFF solid 1px;
  outline: #d0d0d0 solid 1px;
  margin: 15px;
}

.border-radius {
  border-radius: 20px 20px 20px 20px;
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  -khtml-border-radius: 20px;
}

.outline-radius {
  -moz-outline-radius: 21px;
}
<div class="embossed"></div>
<div class="embossed border-radius"></div>
<div class="embossed border-radius outline-radius">-MOZ ONLY</div>

Não encontrei uma solução alternativa para ter esse trabalho em outros navegadores.

EDIT: A única outra maneira de fazer isso é usar box-shadow, mas isso não funcionará se você já tiver uma sombra de caixa nesse elemento.

James Kyle
fonte
1
Você pode usar várias sombras no mesmo elemento, separando-as por vírgulas.
Bangash
2

Existe a solução se você precisar apenas delinear sem borda. Não é meu. Eu tenho se a partir do arquivo CSS Bootstrap. Se você especificar outline: 1px auto certain_color, obterá uma linha externa fina em torno de div de determinada cor. Nesse caso, a largura especificada não importa, mesmo se você especificar 10 px de largura, de qualquer forma, será uma linha fina. A palavra-chave na regra mencionada é "auto".
Se você precisar de um contorno com cantos arredondados e certa largura, adicione a regra css na borda com a largura necessária e a mesma cor. Torna o contorno mais grosso.

Aleks Sid
fonte
2

Até onde eu sei, o Outline radiusFirefox só é suportado pelo Firefox e Firefox para Android.

-moz-outline-radius: 1em;

insira a descrição da imagem aqui

ucMedia
fonte
1

Não. As bordas ficam do lado de fora do elemento e do lado de dentro da área de margem do modelo de caixa. Os contornos ficam no interior do elemento e a área de preenchimento do modelo de caixa o ignora. Não se destina à estética. É apenas para mostrar ao designer os contornos dos elementos. Nos estágios iniciais do desenvolvimento de um documento html, por exemplo, um desenvolvedor pode precisar discernir rapidamente se colocou todos os divs esqueléticos no lugar correto. Mais tarde, eles podem precisar verificar se vários botões e formulários estão com o número correto de pixels separados um do outro.

As fronteiras são de natureza estética. Diferentemente dos contornos, eles são realmente separados do modelo da caixa, o que significa que eles não se sobrepõem ao texto definido como margem: 0; e cada lado da borda pode ser estilizado individualmente.

Se você está tentando aplicar um raio de canto para delinear, presumo que você o esteja usando da maneira que a maioria das pessoas usa borda. Então, se você não se importa de me perguntar, que propriedade do contorno o torna desejável além do limite?

Musixauce3000
fonte
10
O objetivo do contorno é para a navegação por teclado / acessibilidade, para não mostrar aos desenvolvedores onde os elementos são
danwellman
Bem, é para isso que os navegadores os usam, por padrão. Mas eu sempre os usei para ver onde estão meus divs, com grande efeito.
Musixauce3000
+1 por mencionar que "As bordas ficam do lado de fora do elemento e dentro da área de margem do modelo de caixa. Os contornos ficam do lado de dentro do elemento e a área de preenchimento do modelo de caixa o ignora".
21718 Jacques
1

SOMBRA E ESBOÇO DA CAIXA DE COMBINAÇÃO.

Uma ligeira torção na resposta de Lea Hayes que encontrei

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

obtém um acabamento limpo muito bom. Nenhum salto no tamanho que você obtém ao usar o raio da borda

fidev
fonte
1

Como outros já disseram, apenas o firefox suporta isso. Aqui está uma solução alternativa que faz a mesma coisa e até funciona com contornos tracejados.

exemplo

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

RobKohr
fonte
0

Tente usar preenchimento e uma cor de fundo para a borda, depois uma borda para o contorno:

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

Trabalhou no meu caso.

Eric
fonte
0

Acabei de definir o contorno transparente.

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

input[type=text]:focus {    
  border-color: #0079ff;
}
Ireneml.fr
fonte
0

Eu gosto desse jeito.

.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;
}

Ele criará um círculo cinza com borda de inteligência em torno dele e novamente 1px em torno da borda!

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

Na verdade, isso tornará apenas um círculo clicável, enquanto o raio da borda ainda forma um quadrado, mas parece um círculo.

Martin Zvarík
fonte
0

A resposta simples para a pergunta básica é não. A única opção entre navegadores é criar um hack que realiza o que você deseja. Essa abordagem carrega consigo alguns problemas em potencial quando se trata de estilizar conteúdo pré-existente , mas fornece mais personalização do contorno (deslocamento, largura, estilo de linha) do que muitas das outras soluções.

Em um nível básico, considere o seguinte exemplo estático (execute o snippent para demo):

.outline {
    border: 2px dotted transparent;
    border-radius: 5px;
    display: inline-block;
    padding: 2px;
    margin: -4px;
}

/* :focus-within does not work in Edge or IE */
.outline:focus-within, .outline.edge {
    border-color: blue;
}

br {
    margin-bottom: 0.75rem;
}
<h3>Javascript-Free Demo</h3>
<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" />
<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>

Agora, em um nível mais avançado, seria possível usar o JavaScript para inicializar elementos de um determinado tipo ou classe para que eles sejam agrupados dentro de uma div que simule uma estrutura de tópicos no carregamento da página. Além disso, ligações de eventos podem ser estabelecidas para mostrar ou ocultar o resumo das interações do usuário como esta (execute o trecho abaixo ou abra no JSFiddle ):

h3 {
  margin: 0;
}

div {
  box-sizing: border-box;
}

.flex {
  display: flex;
}

.clickable {
  cursor: pointer;
}

.box {
  background: red;
  border: 1px solid black;
  border-radius: 10px;
  height: 5rem;
  display: flex;
  align-items: center;
  text-align: center;
  color: white;
  font-weight: bold;
  padding: 0.5rem;
  margin: 1rem;
}
<h3>Javascript-Enabled Demo</h3>
<div class="flex">
  <div class="box outline-me">I'm outlined because I contain<br>the "outline-me" class</div>
  <div class="box clickable">Click me to toggle outline</div>
</div>
<hr>
<input type="text" placeholder="I'm outlined when focused" />

<script>
// Called on an element to wrap with an outline and passed a styleObject
// the styleObject can contain the following outline properties:
// 		style, width, color, offset, radius, bottomLeftRadius,
//		bottomRightRadius, topLeftRadius, topRightRadius
// It then creates a new div with the properties specified and 
// moves the calling element into the div
// The newly created wrapper div receives the class "simulated-outline"
Element.prototype.addOutline = function (styleObject, hideOutline = true) {
    var element = this;

    // create a div for simulating an outline
    var outline = document.createElement('div');

    // initialize css formatting
    var css = 'display:inline-block;';

    // transfer any element margin to the outline div
    var margins = ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'];
    var marginPropertyNames = { 
        marginTop: 'margin-top',
        marginBottom: 'margin-bottom',
        marginLeft: 'margin-left',
        marginRight: 'margin-right'
    }
    var outlineWidth = Number.parseInt(styleObject.width);
    var outlineOffset = Number.parseInt(styleObject.offset);
    for (var i = 0; i < margins.length; ++i) {
        var computedMargin = Number.parseInt(getComputedStyle(element)[margins[i]]);
        var margin = computedMargin - outlineWidth - outlineOffset;
        css += marginPropertyNames[margins[i]] + ":" + margin + "px;";
    }
    element.style.cssText += 'margin:0px !important;';
    
    // compute css border style for the outline div
    var keys = Object.keys(styleObject);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        var value = styleObject[key];
        switch (key) {
            case 'style':
                var property = 'border-style';
                break;
            case 'width':
                var property = 'border-width';
                break;
            case 'color':
                var property = 'border-color';
                break;
            case 'offset':
                var property = 'padding';
                break;
            case 'radius':
                var property = 'border-radius';
                break;
            case 'bottomLeftRadius':
                var property = 'border-bottom-left-radius';
                break;
            case 'bottomRightRadius':
                var property = 'border-bottom-right-radius';
                break;
            case 'topLeftRadius':
                var property = 'border-top-left-radius-style';
                break;
            case 'topRightRadius':
                var property = 'border-top-right-radius';
                break;
        }
        css += property + ":" + value + ';';
    }
    
    // apply the computed css to the outline div
    outline.style.cssText = css;
    
    // add a class in case we want to do something with elements
    // receiving a simulated outline
    outline.classList.add('simulated-outline');
    
    // place the element inside the outline div
    var parent = element.parentElement;
    parent.insertBefore(outline, element);
    outline.appendChild(element);

    // determine whether outline should be hidden by default or not
    if (hideOutline) element.hideOutline();
}

Element.prototype.showOutline = function () {
    var element = this;
    // get a reference to the outline element that wraps this element
    var outline = element.getOutline();
    // show the outline if one exists
    if (outline) outline.classList.remove('hide-outline');
}


Element.prototype.hideOutline = function () {
    var element = this;
    // get a reference to the outline element that wraps this element
    var outline = element.getOutline();
    // hide the outline if one exists
    if (outline) outline.classList.add('hide-outline');
}

// Determines if this element has an outline. If it does, it returns the outline
// element. If it doesn't have one, return null.
Element.prototype.getOutline = function() {
    var element = this;
    var parent = element.parentElement;
    return (parent.classList.contains('simulated-outline')) ? parent : null;
}

// Determines the visiblity status of the outline, returning true if the outline is
// visible and false if it is not. If the element has no outline, null is returned.
Element.prototype.outlineStatus = function() {
    var element = this;
    var outline = element.getOutline();
    if (outline === null) {
        return null;
    } else {
        return !outline.classList.contains('hide-outline');
    }
}

// this embeds a style element in the document head for handling outline visibility
var embeddedStyle = document.querySelector('#outline-styles');
if (!embeddedStyle) {
    var style = document.createElement('style');
    style.innerText = `
        .simulated-outline.hide-outline {
            border-color: transparent !important;
        }
    `;
    document.head.append(style);
}


/*########################## example usage ##########################*/

// add outline to all elements with "outline-me" class
var outlineMeStyle = {
    style: 'dashed',
    width: '3px',
    color: 'blue',
    offset: '2px',
    radius: '5px'
};
document.querySelectorAll('.outline-me').forEach((element)=>{
  element.addOutline(outlineMeStyle, false);
});


// make clickable divs get outlines
var outlineStyle = {
    style: 'double',
    width: '4px',
    offset: '3px',
    color: 'red',
    radius: '10px'
};
document.querySelectorAll('.clickable').forEach((element)=>{
    element.addOutline(outlineStyle);
    element.addEventListener('click', (evt)=>{
        var element = evt.target;
        (element.outlineStatus()) ? element.hideOutline() : element.showOutline();
    });
});


// configure inputs to only have outline on focus
document.querySelectorAll('input').forEach((input)=>{
    var outlineStyle = {
        width: '2px',
        offset: '2px',
        color: 'black',
        style: 'dotted',
        radius: '10px'
    }
    input.addOutline(outlineStyle);
    input.addEventListener('focus', (evt)=>{
        var input = evt.target;
        input.showOutline();
    });
    input.addEventListener('blur', (evt)=>{
        var input = evt.target;
        input.hideOutline();
    });
});
</script>

Para concluir, permita-me reiterar que a implementação dessa abordagem pode exigir mais estilo do que o que eu incluí em minhas demos, especialmente se você já tiver estilizado o elemento que deseja descrever.

b_laoshi
fonte