CSS-mostrar apenas o contorno do canto
**** ****
* *
* *
CONTENT
* *
* *
**** ****
15 answers
<div id="div1" />
<div id="div2" />
#div1 {
position:absolute;
top:9px;
left:9px;
height:100px;
width:100px;
background-color:white;
border:1px solid black;
}
#div2 {
position:relative;
top:-1px;
left:-1px;
height:102px;
width:102px;
background-color:white;
border-radius: 15px;
}
Resultado:
Uma solução melhorada fornecida por @web-tiki:
Assumindo <div id="content">CONTENT</div>
e que CONTENT
inclui pelo menos um nó HTML.
#content {position:relative}
#content:before, #content:after, #content>:first-child:before, #content>:first-child:after {
position:absolute; content:' ';
width:80px; height: 80px;
border-color:red; /* or whatever colour */
border-style:solid; /* or whatever style */
}
#content:before {top:0;left:0;border-width: 1px 0 0 1px}
#content:after {top:0;right:0;border-width: 1px 1px 0 0}
#content>:first-child:before {bottom:0;right:0;border-width: 0 1px 1px 0}
#content>:first-child:after {bottom:0;left:0;border-width: 0 0 1px 1px}
Aqui está um violino.
SVG
Esta é outra grande alternativa se você agora quiser começar a usar vetores para permitir uma grande capacidade de resposta.
<svg viewBox="0 0 100 100" width="50px">
<path d="M25,2 L2,2 L2,25" fill="none" stroke="black" stroke-width="3" />
<path d="M2,75 L2,98 L25,98" fill="none" stroke="black" stroke-width="3" />
<path d="M75,98 L98,98 L98,75" fill="none" stroke="black" stroke-width="3" />
<path d="M98,25 L98,2 L75,2" fill="none" stroke="black" stroke-width="3" />
</svg>
O SVG é uma grande ferramenta para usar. Algumas das vantagens de usar SVG neste caso são:
- Controlo da curva
- controlo de enchimento (opacidade, cor)
- controlo do traço (largura, opacidade, cor)
- quantidade de código Tempo para construir e manter o forma
- escalável
- nenhum pedido de HTTP (se usado em linha como no exemplo)
O Suporte do navegador para o SVG incorporado volta para o Internet Explorer 9. Ver canIuse para mais informações.
Aqui estão alguns métodos para criar este efeito sem usar nenhum elemento pseudo / real extra . Uma coisa a notar é que ambas as abordagens só funcionariam em navegadores modernos porque eles usam propriedades CSS3.
Utilização border-image
: a propriedade border-image
torna muito fácil criar tais efeitos. A abordagem é a seguinte:
- crie uma imagem transparente que tenha contornos no canto comoaqui .
- ajusta isto imagem como o
border-image-source
e deixar o navegador cuidar do resto:) uma vez que o valor padrão paraborder-image-repeat
éstretch
, o navegador iria esticar a imagem original para caber no recipiente, mesmo que o recipiente se torne grande. - o valor definido para a propriedade
border-image-width
determina a espessura das fronteiras.
.bordered {
background-color: beige;
border-image-source: url("http://i.stack.imgur.com/s2CAw.png");
border-image-slice: 1;
border-image-width: 5px;
}
.square {
height: 150px;
width: 150px;
}
.large-square {
height: 350px;
width: 350px;
}
/* Just for demo */
div {
margin-bottom: 10px;
}
<div class='bordered square'></div>
<div class='bordered large-square'></div>
Vantagens:
- não necessita de elementos adicionais (pseudo Ou reais) o que significa menos desordenados markup, pseudo elementos podem ser usados para outras necessidades.
- é razoavelmente sensível. Ou seja, o navegador irá adaptar as fronteiras, mesmo que as dimensões do container mudem.
Desvantagens:
- suporte de navegador relativamente mais baixo. Se o apoio IE10 for necessário, então isto não vai acontecer.
-
Uma vez que a imagem de contorno está a ser esticada, se a área de desenho da imagem original for um quadrado e o contentor for um rectângulo, então os contornos parecerão mais largo em cima e em baixo do que à esquerda e à direita.
.bordered { background-color: beige; border-image-source: url("http://i.stack.imgur.com/s2CAw.png"); border-image-slice: 2; border-image-width: 5px; } .small-square { height: 75px; width: 75px; } .square { height: 150px; width: 150px; } .large-square { height: 350px; width: 350px; } .rectangle { height: 150px; width: 250px; } .large-rectangle { height: 150px; width: 350px; } /* Just for demo */ div { margin-bottom: 10px; }
<div class='bordered small-square'></div> <div class='bordered square'></div> <div class='bordered large-square'></div> <div class='bordered rectangle'></div> <div class='bordered large-rectangle'></div>
Utilização background-image
: a propriedade background-image
também pode ser usada com imagens linear-gradient
para produzir o efeito. A abordagem é a seguinte:
- criar quatro imagens
linear-gradient
(duas para cima, baixo e duas para esquerda, direita). Estes gradientes começariam com a cor necessária e continuariam a ser essa cor para tantos pixels como a largura/altura do contorno imagem. Depois disso, deverá ser transparente. - para as fronteiras superior e inferior, a direcção do gradiente deve ser
to right
. Para as fronteiras esquerda e direita, deve serto bottom
. - o valor
background-size
determina a espessura da fronteira. Para as bordas superior e inferior, o tamanho da imagem do gradiente seria de 100% no eixo X e 5px (espessura) no eixo Y. Para as bordas esquerda e direita, o tamanho seria 5px (espessura) no eixo X e 100% no eixo Y. - O
background-repeat
deve ser ajustado pararepeat-x
para as fronteiras superior, inferior e para as fronteiras esquerda e direita. - o
background-position
é definido como (-1 * metade do tamanho da cor em gradiente) no eixo X ou Y, conforme apropriado. Isto é para fazer metade da área colorida aparecer em um lado do elemento, enquanto a outra metade aparece no outro lado (porque gradiente está repetindo).
.bordered.square {
height: 150px;
width: 150px;
}
.bordered.rectangle {
height: 150px;
width: 250px;
}
.bordered {
background-color: beige;
background-image: linear-gradient(to right, black 30px, transparent 30px), linear-gradient(to right, black 30px, transparent 30px), linear-gradient(to bottom, black 30px, transparent 30px), linear-gradient(to bottom, black 30px, transparent 30px);
background-size: 100% 5px, 100% 5px, 5px 100%, 5px 100%;
background-position: -15px 0%, -15px 100%, 0% -15px, 100% -15px;
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
}
/* Just for demo */
div {
margin-bottom: 10px;
}
<div class='bordered square'></div>
<div class='bordered rectangle'></div>
Vantagens:
- não necessita de elementos adicionais (pseudo Ou real) o que significa menos confusão de marcação, pseudo elementos podem ser usados para outras necessidades.
-
É razoavelmente sensível à medida que a largura da cor em gradiente é fixa. Se a largura dos contornos precisar de mudar de acordo com as dimensões do contentor, então podemos mudar o valor dos pixels em gradiente para porcentagem (com algumas alterações menores), como em baixo trecho.
.bordered.square { height: 150px; width: 150px; } .bordered.large-square { height: 250px; width: 250px; } .bordered { background-color: beige; background-image: linear-gradient(to right, black 10%, transparent 10%), linear-gradient(to right, black 10%, transparent 10%), linear-gradient(to bottom, black 10%, transparent 10%), linear-gradient(to bottom, black 10%, transparent 10%); background-size: 90% 5px, 90% 5px, 5px 90%, 5px 90%; background-position: 0% 0%, 0% 100%, 0% 0%, 100% 0%; background-repeat: repeat-x, repeat-x, repeat-y, repeat-y; } /* Just for demo */ div { margin-bottom: 10px; }
<div class='bordered square'></div> <div class='bordered large-square'></div>
Desvantagens:
- Suporte de navegador relativamente melhor . Se o apoio IE9 for necessário, então isto não vai acontecer.
- Se for utilizado um gradiente com base em percentagem, aplicar-se-á também aqui a mesma desvantagem com rectângulos como mencionado para
border-image
.
Você poderia absolutamente posicionar quatro <div>
s, um em cada canto, cada um com as duas fronteiras apropriadas.
HTML
<div class="corners">
<div class="top left"></div>
<div class="top right"></div>
<div class="bottom right"></div>
<div class="bottom left"></div>
content goes here
</div>
CSS
.corners {
position: relative;
width: 100px; /* for demo purposes */
padding: 10px;
}
.top, .bottom {
position: absolute;
width: 10px;
height: 10px;
}
.top {
top: 0;
border-top: 1px solid;
}
.bottom {
bottom: 0;
border-bottom: 1px solid;
}
.left {
left: 0;
border-left: 1px solid;
}
.right {
right: 0;
border-right: 1px solid;
}
Clip-path
Usando dois div's em cima um do outro.E adicionando um clip-path para div que na parte de trás você pode criar uma borda como efeito.
.wrapper {
display: inline-block;
background-color: black;
line-height: 0px;
-webkit-clip-path: polygon(0% 100%, 30% 100%, 30% 70%, 70% 70%, 70% 100%, 100% 100%, 100% 70%, 70% 70%, 70% 30%, 100% 30%, 100% 0%, 70% 0%, 70% 30%, 30% 30%, 30% 0%, 0% 0%, 0% 30%, 30% 30%, 30% 70%, 0% 70%);
clip-path: polygon(0% 100%,
30% 100%,
30% 70%,
70% 70%,
70% 100%,
100% 100%,
100% 70%,
70% 70%,
70% 30%,
100% 30%,
100% 0%,
70% 0%,
70% 30%,
30% 30%,
30% 0%,
0% 0%,
0% 30%,
30% 30%,
30% 70%,
0% 70%);
}
.wrapper {} .wrapper div {
display: inline-block;
height: 150px;
width: 150px;
margin: 10px;
background-color: white;
}
<div class="wrapper">
<div></div>
</div>
Dois pseudo-elementos
Usando dois grandes pseudo-elementos, pode criar o efeito border.
.cut-border {
position: relative;
display: inline-block;
border: 5px solid black;
width: 150px;
height: 150px;
}
.cut-border::before {
content: "";
position: absolute;
height: calc(100% + 10px);
width: 50%;
background-color: white;
top: -5px;
left: 25%;
}
.cut-border::after {
content: "";
position: absolute;
height: 50%;
width: calc(100% + 10px);
background-color: white;
top: 25%;
left: -5px;
}
<div class="cut-border"></div>
.box {
/* fake border */
position: relative;
overflow: hidden;
box-shadow: inset 0px 0px 0px 10px green;
padding: 1em;
}
.box:before {
/* this element will hide the fake border on the top and bottom */
content:'';
display: block;
position: absolute;
border-top:10px solid white;
border-bottom:10px solid white;
/* height = border-width x2 */
height:calc(100% - 20px);
top:0;
/* width = size of fake-border x2 */
width: calc(100% - 36px);
/* left = size of fake-border */
left:18px;
}
.box:after {
/* this element will hide the fake border on the left and right */
/* the rules for width, heigth, top and left will be the opposite of the former element */
display: block;
position: absolute;
content:'';
border-right:10px solid white;
border-left:10px solid white;
height:calc(100% - 36px);
width: calc(100% - 20px);
top:18px;
left: 0;
}
Aqui está um JSFiddle com este exemplo: https://jsfiddle.net/t6dbmq3e/ Espero que ajude.
Pode conseguir isso usando vários gradientes lineares como imagem de fundo.
div {
width: 100px;
height: 100px;
margin: 20px;
background:
linear-gradient(to right, black 4px, transparent 4px) 0 0,
linear-gradient(to right, black 4px, transparent 4px) 0 100%,
linear-gradient(to left, black 4px, transparent 4px) 100% 0,
linear-gradient(to left, black 4px, transparent 4px) 100% 100%,
linear-gradient(to bottom, black 4px, transparent 4px) 0 0,
linear-gradient(to bottom, black 4px, transparent 4px) 100% 0,
linear-gradient(to top, black 4px, transparent 4px) 0 100%,
linear-gradient(to top, black 4px, transparent 4px) 100% 100%;
background-repeat: no-repeat;
background-size: 20px 20px;
}
<div></div>
<div id="half" style="position:absolute; top:0; left:0; width:30px; height:30px; overflow:visible; border-top:3px solid #F00; border-left:3px solid #06F;"></div>
<div id="half" style="position:absolute; bottom:0; right:0; width:30px; height:30px; overflow:visible; border-bottom:3px solid #F00; border-right:3px solid #06F;"></div>
E parece estar a funcionar; -) Desculpe incomodar e obrigado pela sua ajuda.
Não há uma forma limpa de css apenas dar aos cantos uma fronteira, mas você poderia tentar imitar o efeito. Algo assim, talvez. http://jsfiddle.net/RLG4z/
<div id="corners">
<div id="content">
content
</div>
</div>
#corners {
width: 200px;
height: 50px;
border-radius: 10px;
background-color: red;
margin: 10px;
}
#content {
background-color: white;
border-radius: 15px;
height: 30px;
padding: 10px;
}
Devido à diferença no raio de contorno, a cor de fundo do div mostra o Vale, dando o efeito de um contorno nos cantos.
Pessoalmente, acho que trabalharia com imagens de fundo para conseguir isso, para melhor controlar o resultado.Esta é a tua foto:
HTML:
<div class="shell">
<div class="top">
<div class="clear">
<div class="left">
****
</div>
<div class="right">
****
</div>
</div>
<div class="clear">
<div class="left">
*
</div>
<div class="right">
*
</div>
</div>
<div class="clear">
<div class="left">
*
</div>
<div class="right">
*
</div>
</div>
</div>
<div class="content">
<p>CONTENT</p>
</div>
<div class="bottom">
<div class="clear">
<div class="left">
*
</div>
<div class="right">
*
</div>
</div>
<div class="clear">
<div class="left">
*
</div>
<div class="right">
*
</div>
</div>
<div class="clear">
<div class="left">
****
</div>
<div class="right">
****
</div>
</div>
</div>
E CSS:
.shell { width: 200px;}
.left{ float:left; }
.right{float:right; }
.clear { clear: both; line-height: 10px; }
.content { line-height: 10px; text-align: center; }
Aqui está uma versão modificada da resposta acima, esta versão tem pai posicionado relativo e filho posicionado absoluto para que possamos adicionar o efeito de hover on.
HTML:
<div id="div1"><div id="div2"><img src="http://placekitten.com/g/82/82"></div></div>
CSS:
#div1 {
position: relative;
height: 100px;
width: 100px;
background-color: white;
border: 1px solid transparent;
}
#div2 {
position: absolute;
top: -2px;
left: -2px;
height: 84px;
width: 84px;
background-color: #FFF;
border-radius: 15px;
padding: 10px;
}
#div1:hover {
border: 1px solid red;
}
O HTML
<div class="column">
<div class="c-frame-wrapper">
<div class="c-frame-tl"></div>
<div class="c-frame-tr"></div>
<div class="c-frame-br"></div>
<div class="c-frame-bl"></div>
<div class="c-frame-content">
© Copyright 2015 - Company name<br /><br />
St Winifrids St,<br />
The Saints, Harrogate HG1 5PZ, UK<br />
</div>
</div>
</div>
O CSS
.c-frame-wrapper {
width: 250px;
height: 100px;
font-size:11px;
color: $dark-grey-lighten-70;
/* center align x axis */
right: auto;
left: 50%;
transform: translateX(-50%);
}
.c-frame-tl {
top: 0;
left: 0;
position: absolute;
width:10px;
height:10px;
border-width: 3px;
border-style: solid none none solid;
border-color: #eb0000;
}
.c-frame-tr {
top: 0;
right: 0;
position: absolute;
width:10px;
height:10px;
border-width: 3px;
border-style: solid solid none none;
border-color: #eb0000;
}
.c-frame-br {
bottom: 0;
right: 0;
position: absolute;
width:10px;
height:10px;
border-width: 3px;
border-style: none solid solid none;
border-color: #eb0000;
}
.c-frame-bl {
bottom: 0;
left: 0;
position: absolute;
width:10px;
height:10px;
border-width: 3px;
border-style: none none solid solid;
border-color: #eb0000;
}
.c-frame-content {
width:100%;
text-align: center;
/*center alignment x and y*/
position: absolute;
top: 50%;
left: 50%;
bottom: auto;
right: auto;
transform: translate(-50%,-50%);
}
Criei esta mistura sass usando o código acima, para uma solução de copiar e colar:
@mixin corner-borders($corner-width: 1px, $corner-size: 5px, $color-border: grey, $color-background: white) {
position: relative;
border: $corner-width solid $color-border;
background-color: $color-background;
&::before {
content: "";
z-index: 0;
position: absolute;
top: -$corner-width;
bottom: -$corner-width;
left: $corner-size;
right: $corner-size;
background-color: $color-background;
}
&::after {
content: "";
z-index: 0;
position: absolute;
top: $corner-size;
bottom: $corner-size;
left: -$corner-width;
right: -$corner-width;
background-color: $color-background;
}
}
Então você pode usá-lo assim:
Html:
<div class="border">
<div class="content">
Content
</div>
</div>
SCSS
.border {
@include corner-borders;
}
.content {
position: relative;
z-index: 1;
}
Você precisa da posição relativa do índice z para que o conteúdo fique em cima dos pseudo-elementos.
Fiz uma demonstração de codepen aqui.: http://codepen.io/timrross/pen/XMwVbV.box{
background-color: aquamarine;
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 300px;
height: 200px;
border: 30px solid black;
}
.box::before{
content:'';
position: absolute;
top:25px; left:-30px;
height: 150px;
width: 360px;
background: aquamarine;
}
.box::after{
content:'';
position: absolute;
top:-30px; left:30px;
height: 260px;
width: 240px;
background: aquamarine;
}
<div class="box">
</div>