¿Es posible crear una esquina en ángulo en CSS?


Me pregunto si hay alguna manera de crear esta forma con CSS puro. Para extender este problema aún más, esta forma necesita recortar la imagen dentro (piense en ella como una máscara, pero el borde gris tiene que ser visible).

introduzca la descripción de la imagen aquí

¿O estoy mejor creando esto en canvas/svg?

Author: web-tiki, 2013-10-08

4 answers

Es un poco difícil mantener el borde, pero logré lograr un efecto cercano usando elementos: before y: after con un contenedor padre (: before y: after no funcionan en una etiqueta img)

  1. Añadir un borde al contenedor

  2. Añadir un antes para bloquear una esquina y desplazar por -1 para cubrir el borde

  3. Agregue un después que está ligeramente desplazado del antes para crear la línea dentro del corte

Como se puede ver, el el grosor de la línea 45deg es un pequeño 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>

JSFiddle

 32
Author: Matt.C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-15 18:16:23

VER LA DEMO

Puede hacer esto usando pseudo, junto con border-width y 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 este script jQuery para el soporte de navegadores cruzados. --> http://jquery.malsup.com/corner /

VER LA DEMO AQUÍ

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");
 11
Author: Vikas Ghodke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-08 13:41:32

Usando CSS:

La forma exacta se puede lograr usando CSS. La idea es tener un elemento con un border-radius para la esquina superior izquierda, sesgarlo 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), entonces se puede lograr usando solo un elemento. Sin embargo, si una imagen necesita agregarse dentro de la forma (como se menciona en la pregunta), entonces necesitamos más de un elemento porque tenemos que invertir el efecto skew en la imagen y esto no se puede hacer sin un elemento hijo.

.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 problemas con SVG como en el fragmento de código a continuación.

.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:

introduzca la descripción de la imagen aquí

 10
Author: Harry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-11 13:59:40

Es posible hacer esto, pero es una solución de CSS3, por lo que no funcionará en navegadores más antiguos, no creo.

Lo que he hecho es, he creado dos divs, uno tiene un borde alrededor, y el otro tiene un borde solo en la parte inferior. Usando translate He girado 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

Esquina recortada

Véase Fiddle

 3
Author: ediblecode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-08 13:26:05