w3schools - ¿Es posible crear una esquina en ángulo en CSS?
label shape css (4)
Es posible hacer esto, pero es una solución CSS3 por lo que no funcionará en navegadores más antiguos, no creo.
Lo que he hecho es crear dos divisiones, una tiene un borde alrededor y la otra tiene un borde solo en la parte inferior. Usando translate
, he rotado ese div 45 grados para enmascarar la esquina del otro div, dando el efecto deseado.
HTML
<div class="holder">
<div class="main"></div>
<div class="corner"></div>
</div>
CSS
.holder {
position:relative;
width: 180px;
margin:30px
}
.main {
width: 160px;
height: 40px;
border: 1px solid grey;
position:absolute;
left:0;
z-index: 1;
}
.corner {
border-bottom: 1px solid grey;
width:30px;
height: 41px;
position:absolute;
top:-25px;
right:0;
z-index:2;
background:#fff;
/* Safari */
-webkit-transform: rotate(45deg);
/* Firefox */
-moz-transform: rotate(45deg);
/* IE */
-ms-transform: rotate(45deg);
/* Opera */
-o-transform: rotate(45deg);
}
Salida
Ver Fiddle
Me pregunto si hay alguna forma de crear esta forma con CSS puro. Para ampliar aún más este problema, esta forma necesita recortar la imagen en el interior (piénselo como una máscara, pero el borde gris debe estar visible).
¿O es mejor crear esto en canvas / svg?
Es un poco difícil mantener el borde, pero logré lograr un efecto cercano usando: antes y después de los elementos con un contenedor padre (: antes y después no funcionan en una etiqueta img)
Agregue un borde al contenedor
Agregue un antes para bloquear una esquina y compense por -1 para cubrir el borde
Agregue un punto después de eso ligeramente desviado del anterior para crear la línea dentro del corte
Como puede ver, el grosor de la línea de 45deg es un problema:
.cutCorner {
position:relative; background-color:blue;
border:1px solid silver; display: inline-block;
}
.cutCorner img {
display:block;
}
.cutCorner:before {
position:absolute; left:-1px; top:-1px; content:'''';
border-top: 70px solid silver;
border-right: 70px solid transparent;
}
.cutCorner:after {
position:absolute; left:-2px; top:-2px; content:'''';
border-top: 70px solid white;
border-right: 70px solid transparent;
}
<div class="cutCorner">
<img class="" src="https://www.google.co.uk/logos/doodles/2013/william-john-swainsons-224th-birthday-5655612935372800-hp.jpg" />
</div>
Puede hacer esto usando pseudo, junto con border-width
border-color
vea el siguiente código para ver cómo se puede hacer.
HTML
<div class="cut"></div>
CSS
.cut {
position:relative;
width:500px;
height: 200px;
padding:20px;
color:#000;
background:#ccc;
}
.cut:before {
content:"";
position:absolute;
top:0;
left:0;
border-width:30px 30px 0px 0px;
border-style:solid;
border-color:#fff transparent transparent #fff ;
}
Otra solución que utiliza esta secuencia de comandos jQuery para compatibilidad con navegadores cruzados. -> http://jquery.malsup.com/corner/
HTML
<div class="cut"></div>
CSS
.cut {
position:relative;
width:500px;
height: 200px;
padding:20px;
color:#000;
background:#ccc;
}
JS
$(".cut").corner("bevel tl 50px");
Usando CSS:
La forma exacta se puede lograr usando CSS. La idea es tener un elemento con un border-radius
de border-radius
para la esquina superior izquierda, inclinarlo a lo largo del eje Y y luego colocarlo justo antes del rectángulo. Hacer esto haría que parezca que el elemento rectangular tiene un corte triangular en la parte superior con un borde curvo.
Si la parte interior de la forma tiene solo un color (sólido o transparente), puede lograrse utilizando solo un elemento. Sin embargo, si se necesita agregar una imagen dentro de la forma (como se menciona en la pregunta), entonces necesitamos más de un elemento porque tenemos que revertir el efecto de skew
en la imagen y esto no se puede hacer sin un elemento secundario.
.shape,
.shape-image {
position: relative;
height: 150px;
width: 400px;
border-bottom: 2px solid crimson;
overflow: hidden;
}
.shape:before,
.shape:after,
.shape-image:after {
position: absolute;
content: '''';
top: 0px;
height: 100%;
z-index: -1;
}
.shape:before,
.shape-image .before {
left: 0px;
top: -2px;
width: 50px;
border: 2px solid crimson;
border-width: 3px 0px 0px 2px;
border-top-left-radius: 8px;
transform-origin: right bottom;
transform: skewY(-45deg);
}
.shape:after,
.shape-image:after {
left: 52px;
width: calc(100% - 54px);
border: 2px solid crimson;
border-left: none;
}
.shape:after,
.shape:before {
background: aliceblue;
}
.shape.semi-transparent:after,
.shape.semi-transparent:before {
background: rgba(150, 150, 150, 0.5);
}
.shape-image .before {
position: absolute;
top: 0px;
height: 100%;
overflow: hidden;
}
.shape-image .before .img {
height: 100%;
width: 100%;
border-top-left-radius: 8px;
background: url(http://lorempixel.com/400/150);
transform-origin: right bottom;
transform: skewY(45deg);
}
.shape-image:after {
background: url(http://lorempixel.com/400/150);
background-position: -50px 0px;
}
/* Just for demo */
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
.shape{
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
<div class="shape semi-transparent"></div>
<div class="shape-image">
<div class="before">
<div class="img"></div>
</div>
</div>
Usando SVG:
Alternativamente, lo mismo se puede lograr de una manera más libre de complicaciones con SVG como en el siguiente fragmento.
.vector {
height: 150px;
width: 410px;
padding-left
}
svg {
height: 100%;
width: 100%;
}
path {
stroke: crimson;
stroke-width: 2;
fill: none;
}
polygon {
fill: url(#bg);
}
/* Just for demo */
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class=''vector''>
<svg viewBox=''0 0 400 150'' preserveAspectRatio=''none''>
<defs>
<path d=''M50,2 h 342 v144 h-390 v-90 a6,12 0 0,1 3,-9 z'' id=''p'' />
<clipPath id=''clipper''>
<use xlink:href=''#p'' />
</clipPath>
<pattern id=''bg'' width=''400'' height=''150'' patternUnits=''userSpaceOnUse''>
<image xlink:href=''http://lorempixel.com/400/150'' height=''150'' width=''400'' />
</pattern>
</defs>
<polygon points=''2,2 392,2 392,148 2,148'' clip-path=''url(#clipper)'' />
<use xlink:href=''#p'' />
</svg>
</div>
<h3>Original Image</h3>
<img src=''http://lorempixel.com/400/150'' />
Captura de pantalla: