web-dev-qa-db-fra.com

Couper les coins en utilisant CSS

Je cherche à "couper" le coin supérieur gauche d'une div, comme si vous aviez plié le coin d'une page.

J'aimerais le faire en CSS pur, y a-t-il des méthodes?

49
Rixius

Si l'élément parent a un arrière-plan de couleur unie, vous pouvez utiliser des pseudo-éléments pour créer l'effet:

div {
    height: 300px;
    background: red;
    position: relative;
}

div:before {
    content: '';
    position: absolute;
    top: 0; right: 0;
    border-top: 80px solid white;
    border-left: 80px solid red;
    width: 0;
}

http://jsfiddle.net/2bZAW/


P.S.Le prochain border-corner-shape correspond exactement à ce que vous recherchez. Dommage qu'il puisse être exclu des spécifications et ne jamais en faire un navigateur à l'état sauvage :(

88
Joseph Silber

Si vous avez besoin d'un bord découpé transparent, vous pouvez utiliser un pseudo-élément pivoté comme arrière-plan pour la variable div et le positionner pour découper le coin souhaité:

Transprent cut out Edge on a div

body {
  background: url(http://i.imgur.com/k8BtMvj.jpg);
  background-size: cover;
}
div {
  position: relative;
  width: 50%;
  margin: 0 auto;
  overflow: hidden;
  padding: 20px;
  text-align: center;
}
div:after {
  content: '';
  position: absolute;
  width: 1100%; height: 1100%;
  top: 20px; right: -500%;
  background: rgba(255,255,255,.8);
  transform-Origin: 54% 0;
  transform: rotate(45deg);
  z-index: -1;
}
<div>
  ... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>
</div>

Notez que cette solution utilise des transformations et que vous devez ajouter les préfixes de fournisseur requis. Pour plus d'informations, voir canIuse .

Pour couper le bord inférieur droit, vous pouvez modifier les propriétés top, transforme et transform-Origin du pseudo-élément en:

body {
  background: url(http://i.imgur.com/k8BtMvj.jpg);
  background-size: cover;
}
div {
  position: relative;
  width: 50%;
  margin: 0 auto;
  overflow: hidden;
  padding: 20px;
  text-align: center;
}
div:after {
  content: '';
  position: absolute;
  width: 1100%; height: 1100%;
  bottom: 20px; right: -500%;
  background: rgba(255,255,255,.8);
  transform-Origin: 54% 100%;
  transform: rotate(-45deg);
  z-index: -1;
}
<div>
  ... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>
</div>

41
web-tiki

CSS Clip-Path

Utiliser un clip-path est une nouvelle alternative. Il commence à être de plus en plus supporté et est maintenant bien documenté. Puisqu'il utilise SVG pour créer la forme, il est réactif dès sa sortie de la boîte.

div {
  width: 200px;
  min-height: 200px;
  -webkit-clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 25%, 75% 0);
  clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 25%, 75% 0);
  background: lightblue;
}
<div>
  <p>Some Text</p>
</div>

Transformation CSS

J'ai une alternative à la réponse de transformation de web-tiki.

body {
  background: lightgreen;
}
div {
  width: 200px;
  height: 200px;
  background: transparent;
  position: relative;
  overflow: hidden;
}
div.bg {
  width: 200%;
  height: 200%;
  background: lightblue;
  position: absolute;
  top: 0;
  left: -75%;
  transform-Origin: 50% 50%;
  transform: rotate(45deg);
  z-index: -1;
}
<div>
  <div class="bg"></div>
  <p>Some Text</p>
</div>

24
Stewartside

Vous pouvez utiliser linear-gradient. Supposons que le parent div ait une image d’arrière-plan et que vous ayez besoin d’une div avec un fond gris et un coin gauche coudé. Vous pouvez faire quelque chose comme ça:

.parent-div { background: url('/image.jpg'); }
.child-div { 
   background: #333;
   background: linear-gradient(135deg, transparent 30px, #333 0);
}

Voir sur CodePen

Lectures complémentaires:

13
Nate

Voici une autre approche utilisant CSS transform: skew(45deg) pour produire l'effet de coin coupé. La forme elle-même implique trois éléments (1 réel et 2 pseudo-éléments) comme suit:

  • L'élément conteneur div principal a overflow: hidden et génère la bordure gauche.
  • Le pseudo-élément :before qui correspond à 20% de la hauteur du conteneur parent et auquel une transformation oblique est appliquée. Cet élément produit la bordure en haut et la bordure coupée (inclinée) du côté droit.
  • Le pseudo-élément :after qui représente 80% de la hauteur du parent (en gros, la hauteur restante) et produit la bordure inférieure, la partie restante de la bordure droite.

La sortie produite est réactive, produit une découpe transparente en haut et prend en charge les arrière-plans transparents.

div {
  position: relative;
  height: 100px;
  width: 200px;
  border-left: 2px solid beige;
  overflow: hidden;
}
div:after,
div:before {
  position: absolute;
  content: '';
  width: calc(100% - 2px);
  left: 0px;
  z-index: -1;
}
div:before {
  height: 20%;
  top: 0px;
  border: 2px solid beige;
  border-width: 2px 3px 0px 0px;
  transform: skew(45deg);
  transform-Origin: right bottom;
}
div:after {
  height: calc(80% - 4px);
  bottom: 0px;
  border: 2px solid beige;
  border-width: 0px 2px 2px 0px;
}
.filled:before, .filled:after {
  background-color: beige;
}

/* Just for demo */

div {
  float: left;
  color: beige;
  padding: 10px;
  transition: all 1s;
  margin: 10px;
}
div:hover {
  height: 200px;
  width: 300px;
}
div.filled{
  color: black;
}
body{
 background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">Some content</div>
<div class="cut-corner filled">Some content</div>

 enter image description here


Vous trouverez ci-dessous une autre méthode pour produire l’effet de coin coupé en utilisant des images d’arrière-plan linear-gradient. Une combinaison de 3 images en dégradé (donnée ci-dessous) est utilisée:

  • Un dégradé linéaire (incliné vers le bas à gauche) pour produire l’effet de coin coupé. Ce dégradé a une taille fixe de 25 px x 25 px.
  • Un dégradé linéaire pour fournir une couleur unie à gauche du triangle à l'origine de l'effet de coupe. Un dégradé est utilisé même s'il produit une couleur unie car nous pouvons contrôler la taille, la position de l'arrière-plan uniquement lorsque des images ou des dégradés sont utilisés. Ce dégradé est positionné à -25 pixels sur l’axe X (ce qui signifie qu’il se terminerait avant l’endroit où la coupe est présente).
  • Un autre dégradé similaire à celui ci-dessus produit à nouveau une couleur unie mais est positionné à 25 pixels de l’axe des ordonnées vers le bas (encore une fois pour laisser de côté la zone de découpe).

La sortie produite est réactive, produit une coupe transparente et ne nécessite aucun élément supplémentaire (réel ou pseudo). L'inconvénient est que cette approche ne fonctionnerait que lorsque l'arrière-plan (remplissage) est de couleur unie et qu'il est très difficile de créer des bordures (mais reste possible comme le montre l'extrait de code).

.cut-corner {
  height: 100px;
  width: 200px;
  background-image: linear-gradient(to bottom left, transparent 50%, beige 50%), linear-gradient(beige, beige), linear-gradient(beige, beige);
  background-size: 25px 25px, 100% 100%, 100% 100%;
  background-position: 100% 0%, -25px 0%, 100% 25px;
  background-repeat: no-repeat;
}
.filled {
  background-image: linear-gradient(black, black), linear-gradient(black, black), linear-gradient(black, black), linear-gradient(black, black), linear-gradient(to bottom left, transparent calc(50% - 1px), black calc(50% - 1px), black calc(50% + 1px), beige calc(50% + 1px)), linear-gradient(beige, beige), linear-gradient(beige, beige);
  background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
  background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}

/* Just for demo */

*{
  box-sizing: border-box;
  }
div {
  float: left;
  color: black;
  padding: 10px;
  transition: all 1s;
  margin: 10px;
}
div:hover {
  height: 200px;
  width: 300px;
}
body{
 background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">Some content</div>
<div class="cut-corner filled">Some content</div>

 enter image description here

13
Harry

Si vous avez besoin d'une bordure diagonale au lieu d'un coin, vous pouvez empiler 2 divs avec chacun un pseudo-élément:

DEMO

http://codepen.io/remcokalf/pen/BNxLMJ

.container {
  padding: 100px 200px;
  overflow: hidden;
}

div.diagonal {
  background: #da1d00;
  color: #fff;
  font-family: Arial, Helvetica, sans-serif;
  width: 300px;
  height: 300px;
  padding: 70px;
  position: relative;
  margin: 30px;
  float: left;
}

div.diagonal2 {
  background: #da1d00;
  color: #fff;
  font-family: Arial, Helvetica, sans-serif;
  width: 300px;
  height: 300px;
  padding: 70px;
  position: relative;
  margin: 30px;
  background: #da1d00 url(http://www.remcokalf.nl/background.jpg) left top;
  background-size: cover;
  float: left;
}

div.diagonal3 {
  background: #da1d00;
  color: #da1d00;
  font-family: Arial, Helvetica, sans-serif;
  width: 432px;
  height: 432px;
  padding: 4px;
  position: relative;
  margin: 30px;
  float: left;
}

div.inside {
  background: #fff;
  color: #da1d00;
  font-family: Arial, Helvetica, sans-serif;
  width: 292px;
  height: 292px;
  padding: 70px;
  position: relative;
}

div.diagonal:before,
div.diagonal2:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border-top: 80px solid #fff;
  border-right: 80px solid transparent;
  width: 0;
}

div.diagonal3:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border-top: 80px solid #da1d00;
  border-right: 80px solid transparent;
  width: 0;
  z-index: 1;
}

div.inside:before {
  content: '';
  position: absolute;
  top: -4px;
  left: -4px;
  border-top: 74px solid #fff;
  border-right: 74px solid transparent;
  width: 0;
  z-index: 2;
}

h2 {
  font-size: 30px;
  line-height: 1.3em;
  margin-bottom: 1em;
  position: relative;
  z-index: 1000;
}

p {
  font-size: 16px;
  line-height: 1.6em;
  margin-bottom: 1.8em;
}

#grey {
  width: 100%;
  height: 400px;
  background: #ccc;
  position: relative;
  margin-top: 100px;
}

#grey:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border-top: 80px solid #fff;
  border-right: 80px solid #ccc;
  width: 400px;
}
<div id="grey"></div>
<div class="container">
  <div class="diagonal">
    <h2>Header title</h2>
    <p>Yes a CSS diagonal corner is possible</p>
  </div>
  <div class="diagonal2">
    <h2>Header title</h2>
    <p>Yes a CSS diagonal corner with background image is possible</p>
  </div>
  <div class="diagonal3">
    <div class="inside">
      <h2>Header title</h2>
      <p>Yes a CSS diagonal border is even possible with an extra div</p>
    </div>
  </div>
</div>

7
RemBem

Ce code vous permet de couper des coins de chaque côté du rectangle:

div {
  display:block;
  height: 300px;
  width: 200px;
  background: url('http://lorempixel.com/180/290/') no-repeat;
  background-size:cover;

  -webkit-clip-path: polygon(10px 0%, calc(100% - 10px) 0%, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0% calc(100% - 10px), 0% 10px);
  clip-path: polygon(10px 0%, calc(100% - 10px) 0%, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0% calc(100% - 10px), 0% 10px);
}

http://jsfiddle.net/2bZAW/5552/

 enter image description here

5
Sviat

Avec une petite modification du code de Joseph, l'élément ne nécessite pas un arrière-plan solide:

div {
    height: 300px;
    background: url('http://images2.layoutsparks.com/1/190037/serene-nature-scenery-blue.jpg');
    position: relative;
}

div:before {
    content: '';
    position: absolute;
    top: 0; right: 0;
    border-top: 80px solid white;
    border-left: 80px solid rgba(0,0,0,0);
    width: 0;
}

http://jsfiddle.net/2bZAW/1921/

Cette utilisation de 'rgba (0,0,0,0)' permet au "coin" intérieur d'être invisible.

Vous pouvez également éditer le 4ème paramètre 'a', où 0 <a <1, pour avoir une ombre pour davantage d'effet 'coin plié':

http://jsfiddle.net/2bZAW/1922/ (avec ombre)


NOTE: Les valeurs de couleur RGBA sont supportées dans IE9 +, Firefox 3+, Chrome, Safari et Opera 10+.

3
hakJav

Nous avons eu le problème des couleurs de fond différentes pour nos éléments coupés. Et nous voulions seulement le coin supérieur droit et inférieur gauche.

 enter image description here

body {
 background-color: rgba(0,0,0,0.3)
 
}

.box {
 position: relative;
 display: block;
 background: blue;
 text-align: center;
 color: white;
 padding: 15px;
 margin: 50px;
}

.box:before,
.box:after {
 content: "";
 position: absolute;
 left: 0; 
 right: 0;
 bottom: 100%;
 border-bottom: 15px solid blue;
 border-left: 15px solid transparent;
 border-right: 15px solid transparent;
}

.box:before{
	border-left: 15px solid blue;
}

.box:after{
	border-right: 15px solid blue;
}

.box:after {
 bottom: auto;
 top: 100%;
 border-bottom: none;
 border-top: 15px solid blue;
}


/* Active box */
.box.active{
	background: white;
	color: black;
}



.active:before,
.active:after {
 border-bottom: 15px solid white;
}

.active:before{
	border-left: 15px solid white;
}

.active:after{
	border-right: 15px solid white;
}

.active:after {
 border-bottom: none;
 border-top: 15px solid white;
}
<div class="box">
 Some text goes here. Some text goes here. Some text goes here. Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>
</div>
<div class="box">
 Some text goes here.
</div>
<div class="box active">
 Some text goes here.
 <span class="border-bottom"></span>
</div>
<div class="box">
 Some text goes here.
</div>

2
Simon Franzen

Selon la solution à gradient linéaire de Harry (répondu le 14 octobre '15 à 9h55), il est écrit que l'opacité du fond n'est pas possible, je l'ai essayée et oui, ça ne l'est pas. 

Mais! J'ai trouvé une solution de contournement. Non ce n'est pas super optimisé, mais ça a fonctionné. Alors voici ma solution. Puisque Harry n'utilise pas de pseudo-élément, nous pouvons y parvenir en en créant un. 

Définissez la position par rapport au conteneur et créez un pseudo-élément avec les mêmes propriétés de dégradé linéaire. En d'autres termes, il suffit de le cloner. Ensuite, mettez un fond transparent pour le conteneur et disons un fond noir pour le clone. Mettez une position absolue dessus, un z-index de -1 et une valeur d'opacité (ie. 50%). Cela fera le travail. Encore une fois c'est une solution de contournement et ce n'est pas parfait mais cela fonctionne très bien. 

.cut-corner {
    position: relative;
    color: white;
    background-repeat: no-repeat;
    background-image: linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(to bottom left, transparent calc(50% - 1px), white calc(50% - 1px), white calc(50% + 1px), transparent calc(50% + 1px)), linear-gradient(transparent, transparent), linear-gradient(transparent, transparent);
    background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
    background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}
.cut-corner:after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    top: 0;
    z-index: -1;
    opacity: 0.5;
    background-repeat: no-repeat;
    background-image: linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(to bottom left, transparent calc(50% - 1px), white calc(50% - 1px), white calc(50% + 1px), black calc(50% + 1px)), linear-gradient(black, black), linear-gradient(black, black);
    background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
    background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}

/* Just for demo */

div {
  padding: 10px;
}
body{
 background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">
  Some content<br>
  Some content<br>
  Some content<br>
  Some content  
</div>

1
Kiwad

Une autre solution: html:

<div class="background">
  <div class="container">Hello world!</div>
</div>

css:

.background {
  position: relative;
  width: 50px;
  height: 50px;
  border-right: 150px solid lightgreen;
  border-bottom: 150px solid lightgreen;
  border-radius: 10px;
}
.background::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border: 25px solid lightgreen;
  border-top-color: transparent;
  border-left-color: transparent;
}
.container {
  position: absolute;
  padding-left: 25px;
  padding-top: 25px;
  font-size: 38px;
  font-weight: bolder;
}

https://codepen.io/eggofevil/pen/KYaMjV

0
Alex Gurin

par petite modification du code de Joshep ... Vous pouvez utiliser ce code qui semble être plié à droite selon vos besoins.

div {
    height: 300px;
    background: red;
    position: relative;
}

div:before {
    content: '';
    position: absolute;
    top: 0; right: 0;
    border-top: 80px solid white;
    border-left: 80px solid blue;
    width: 0;
}
0
Gagan Gami

J'ai récemment coupé le coin en haut à droite et superposé les onglets comme des dossiers. Terminez le code noob, alors ignorez le code de merde, mais j’ai fait cela en combinant un carré, un triangle et un rectangle ... C’est peut-être une nouvelle approche, mais heureusement, cela sera utile.

https://i.stack.imgur.com/qFMRz.png

Voici le HTML:

<!DOCTYPE html>
<html lang ="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="style.css"> 
    </head>
    <body>
        <div class="folders">
            <div class="container">
                <div class="triangleOne">
                    <p class="folderNames">Home</p>
                </div>
                <div class="triangleOneCut">
                </div>
                <div class="triangleOneFill">
                </div>
            </div>

            <div class="container2">
                <div class="triangleOne blue">
                    <p class="folderNames">About</p>
                </div>
                <div class="triangleOneCut blueCut">
                </div>
                <div class="triangleOneFill blue">
                </div>
            </div>

            <div class="container3">
                <div class="triangleOne green">
                    <p class="folderNames">Contact</p>
                </div>
                <div class="triangleOneCut greenCut">
                </div>
                <div class="triangleOneFill green">
                </div>
            </div>
        </div>
    </body>
</html>

Voici le CSS:

.triangleOne {
    height: 50px;
    width: 40px;
    background: red;
    border-radius: 5px 0px 0px 5px;
    position: absolute;
}

.triangleOneCut {
    content: '';
    position: absolute;
    top: 0; left: 40px;
    border-top: 10px solid transparent;
    border-left: 10px solid red;
    width: 0;
}

.triangleOneFill {
    content: '';
    position: absolute;
    top: 10px; left: 40px;
    width: 10px;
    height: 40px;
    background-color: red;
    border-radius: 0px 0px 5px 0px;
}

.container {
    position: relative;
    height: 50px;
    width: 50px;
    display: inline-block;
    z-index: 3;
}

.container2 {
    position: relative;
    height: 50px;
    width: 50px;
    display: inline-block;
    left: -10px;
    z-index: 2;
}

.container3 {
    position: relative;
    height: 50px;
    width: 50px;
    display: inline-block;
    left: -20px;
    z-index: 1;
}

.blue {
    background-color: blue;
}

.green {
    background-color: green;
}

.blueCut {
    border-left: 10px solid blue;
}

.greenCut {
    border-left: 10px solid green;
}

.folders {
    width: 160px;
    height: 50px;
    /* border: 10px solid white; */
    margin: auto;
    padding-left: 25px;
    margin-top: 100px;
}

.folderNames {
    text-align: right;
    padding-left: 2px;
    color: white;
    margin-top: 1.5px;
    font-family: monospace;
    font-size: 6.5px;
    border-bottom: double 1.5px white;
}
0
Xenxen