web-dev-qa-db-fra.com

Est-il possible de créer un coin angulaire en CSS?

Je me demande s'il existe un moyen de créer cette forme avec du CSS pur. Pour étendre davantage ce problème, cette forme doit couper l'image à l'intérieur (pensez-y comme un masque - mais la bordure grise doit être visible).

enter image description here

Ou suis-je mieux de créer ceci dans canvas/svg?

33
user2307706

C'est un peu difficile de garder la bordure, mais j'ai réussi à obtenir un effet proche en utilisant: les éléments avant et: après avec un conteneur parent (: avant et: après ne fonctionnent pas sur une balise img)

  1. Ajouter une bordure au conteneur

  2. Ajoutez un avant pour bloquer un coin et décalez de -1 pour couvrir la bordure

  3. Ajoutez un après légèrement décalé par rapport à l'avant pour créer la ligne à l'intérieur de la coupure

Comme vous pouvez le voir, l'épaisseur de la ligne 45 degrés est un peu un problème:

.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

33
Matt.C

VOIR LA DÉMO

Vous pouvez le faire en utilisant un pseudo, avec border-width et border-color voir le code ci-dessous pour voir comment cela peut être fait.

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

Une autre solution utilisant ce script jQuery pour la prise en charge de plusieurs navigateurs. -> http://jquery.malsup.com/corner/

VOIR LA DÉMO ICI

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");
12
Vikas Ghodke

en utilisant CSS:

La forme exacte peut être obtenue en utilisant CSS. L'idée est d'avoir un élément avec un border-radius pour le coin supérieur gauche, l'incliner le long de l'axe Y, puis le positionner juste avant le rectangle. Faire cela donnerait l'impression que l'élément rectangulaire a une coupe triangulaire en haut avec un bord incurvé.

Si la partie intérieure de la forme n'a qu'une couleur (solide ou transparente), elle peut être réalisée en utilisant un seul élément. Cependant, si une image doit être ajoutée à l'intérieur de la forme (comme mentionné en question), alors nous avons besoin de plus d'un élément car nous devons inverser l'effet skew sur l'image et cela ne peut pas être fait sans enfant élément.

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

en utilisant SVG:

Alternativement, la même chose peut être obtenue d'une manière plus sans tracas avec SVG comme dans l'extrait ci-dessous.

.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' />

Capture d'écran:

enter image description here

10
Harry

Il est possible de le faire, mais c'est une solution CSS3, donc je ne pense pas que cela fonctionnera sur les navigateurs plus anciens.

Ce que j'ai fait, c'est que j'ai créé deux divisions, l'une a une bordure tout autour et l'autre n'a une bordure qu'en bas. En utilisant translate j'ai ensuite fait pivoter cette div de 45 degrés pour masquer le coin de l'autre div, donnant l'effet souhaité.

[~ # ~] 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);
}

Sortie

Clipped corner

Voir Violon

3
ediblecode