web-dev-qa-db-fra.com

CSS - Afficher uniquement les bordures d'angle

Je me demande s'il est possible en CSS ou Jquery de créer une bordure mais uniquement pour le coin. Quelque chose comme ça: 

****                         ****
*                               *
*                               *

             CONTENT

*                               *
*                               *
****                         ****
34
pierreaurelemartin

J'utiliserais des divs qui se chevauchent.

Un avec des coins carrés. Et l’Autre aux coins arrondis (pour ne pas masquer les coins du premier).

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

http://jsfiddle.net/y3EfP/

Résultat:

enter image description here


Une solution améliorée fournie par @ web-tiki:

http://jsfiddle.net/webtiki/y3EfP/147/

37
Majid Laissi

En supposant que <div id="content">CONTENT</div> et que CONTENT incluent au moins un nœud 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}

Voici un Fiddle

33
Niet the Dark Absol

SVG

Ceci est une autre excellente alternative si vous voulez maintenant commencer à utiliser des vecteurs pour permettre une grande réactivité.

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

SVG est un excellent outil à utiliser. Certains des avantages d'utiliser SVG dans ce cas sont les suivants:

  • Contrôle de la courbe
  • Contrôle de remplissage (opacité, couleur)
  • Contrôle du trait (largeur, opacité, couleur)
  • Quantité de code
  • Temps pour construire et maintenir la forme
  • Évolutif
  • Pas de requête HTTP (si utilisé en ligne comme dans l'exemple)

La prise en charge du navigateur pour les SVG en ligne retourne à Internet Explorer 9. Voir canIuse pour plus d’informations.

15
Stewartside

Voici quelques méthodes pour créer cet effet sans utiliser d’éléments pseudo/réels supplémentaires. Une chose à noter est que ces deux approches ne fonctionneraient que dans les navigateurs modernes, car elles utilisent les propriétés CSS3. 

Utilisation deborder-image: La propriété border-image facilite la création de tels effets. La démarche est la suivante:

  • Créez une image transparente qui a des bordures juste dans le coin comme ici .
  • Définissez cette image comme border-image-source et laissez le navigateur se charger du reste :) Comme la valeur par défaut de border-image-repeat est stretch, le navigateur dilaterait l'image d'origine pour l'adapter au conteneur, même si celui-ci devenait volumineux.
  • La valeur définie pour la propriété border-image-width détermine l'épaisseur des bordures.

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

Avantages:

  • Ne nécessite aucun élément supplémentaire (pseudo ou réel), ce qui signifie moins de balisage, les pseudo-éléments peuvent être utilisés pour d'autres besoins.
  • Est raisonnablement sensible. Ce navigateur adaptera les bordures même si les dimensions du conteneur changent.

Désavantages:

  • Support du navigateur relativement faible . Si IE10 est pris en charge, alors c'est impossible.
  • Étant donné que l'image de bordure est étirée, si le canevas de l'image d'origine est un carré et que le conteneur est un rectangle, les bordures semblent plus larges en haut et en bas qu'à gauche et à droite.

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


Utilisation debackground-image: La propriété background-image peut également être utilisée avec des images linear-gradient pour produire l'effet. La démarche est la suivante:

  • Créez quatre images linear-gradient (deux pour le haut, le bas et deux pour la gauche et la droite). Ces dégradés commenceraient par la couleur requise et resteraient cette couleur pour autant de pixels que la largeur/hauteur de l'image de bordure. Après cela, cela devrait être transparent. 
  • Pour les bordures supérieure et inférieure, la direction du dégradé doit être to right. Pour les bordures gauche et droite, il devrait s'agir de to bottom.
  • La valeur background-size détermine l'épaisseur de la bordure. Pour les bordures supérieure et inférieure, la taille de l'image en dégradé serait de 100% en abscisse et de 5 pixels (épaisseur) en ordonnée. Pour les bordures gauche et droite, la taille serait 5px (épaisseur) en abscisse et 100% en ordonnée.
  • background-repeat doit être défini sur repeat-x pour les bordures supérieure et inférieure et sur repeat-y pour les bordures gauche et droite.
  • Le background-position est défini sur (-1 * la moitié de la taille de la couleur en dégradé) sur l'axe des X ou des Y, selon le cas. Cela permet de faire apparaître la moitié de la zone colorée d'un côté de l'élément, tandis que l'autre moitié apparaît de l'autre côté (car le dégradé se répète).

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

Avantages:

  • Ne nécessite aucun élément supplémentaire (pseudo ou réel), ce qui signifie moins de balisage, les pseudo-éléments peuvent être utilisés pour d'autres besoins.
  • Est raisonnablement sensible car la largeur de la couleur en dégradé est fixée. Si la largeur des bordures doit changer en fonction des dimensions du conteneur, vous pouvez modifier la valeur des pixels en dégradé en pourcentage (avec quelques modifications mineures supplémentaires) comme dans l'extrait ci-dessous.

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

Désavantages:

  • Support du navigateur relativement meilleur . Si IE9- support est nécessaire, c'est une solution de rechange.
  • Si un gradient basé sur un pourcentage est utilisé, le même inconvénient avec les rectangles que celui mentionné pour border-image serait applicable ici également.
13
Harry

Vous pouvez absolument placer quatre <div>s, un dans chaque coin, chacun avec les deux bordures appropriées.

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

Vous pouvez y parvenir en utilisant plusieurs dégradés linéaires comme image d’arrière-plan.

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>

6
Robert Kirsz

clip-path

En utilisant deux div superposés.
Et en ajoutant un chemin de clip pour div, à l'arrière, vous pouvez créer un effet de bordure.

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

deux pseudo-éléments

En utilisant deux grands pseudo-éléments, vous pouvez créer l’effet de bordure.

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

5
Persijn

J'ai trouvé cette question, mais je n'étais pas satisfait de l'approche frontière-rayon: comme j'utilisais des bordures plus épaisses, l'effet n'était pas aussi bon que je le voulais. J'ai réussi à créer une autre solution, sans images et sans annotation supplémentaire:

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

Voici un exemple JSFiddle: https://jsfiddle.net/t6dbmq3e/ J'espère que cela vous aidera.

3
Raphael Aleixo

Ok, comme je suis nul en CSS, je pense que je ne pourrai pas le faire moi-même mais je le fais et cela semble fonctionner 

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

Et cela semble fonctionner ;-) Désolé de déranger et merci de votre aide.

1
pierreaurelemartin

Il n'y a pas de moyen propre pour donner une bordure aux coins, mais vous pouvez essayer de reproduire cet effet. Quelque chose comme ceci peut-être: 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;
}

en raison de la différence de rayon de bordure, la couleur d'arrière-plan de la division sous-jacente présente un creux qui donne l'effet d'une bordure sur les coins.

Personnellement, je pense que je travaillerais avec des images de fond pour y parvenir, afin de mieux contrôler le résultat.

1
Pevara

C'est ta photo: 

HTML:

<div class="Shell">

    <div class="top">

        <div class="clear">
            <div class="left">
              &#42;&#42;&#42;&#42;
            </div>
            <div class="right">
              &#42;&#42;&#42;&#42;
            </div>
        </div>

        <div class="clear"> 
            <div class="left">
              &#42;
            </div>
            <div class="right">
              &#42;
            </div>
        </div>

        <div class="clear">
            <div class="left">
              &#42;
            </div>
            <div class="right">
              &#42;
            </div>
        </div>

    </div>

    <div class="content">
        <p>CONTENT</p>
    </div>

    <div class="bottom">

        <div class="clear"> 
            <div class="left">
              &#42;
            </div>
            <div class="right">
              &#42;
            </div>
        </div>

        <div class="clear">
            <div class="left">
              &#42;
            </div>
            <div class="right">
              &#42;
            </div>
        </div>

      <div class="clear">
            <div class="left">
              &#42;&#42;&#42;&#42;
            </div>
            <div class="right">
              &#42;&#42;&#42;&#42;
            </div>
        </div>
    </div>

et CSS:

.Shell { width: 200px;}
.left{ float:left; }
.right{float:right; }
.clear { clear: both; line-height: 10px; }
.content { line-height: 10px; text-align: center; }

Voici quelque chose que j'ai fait récemment avec un contenu centré à la fois verticalement et horizontalement. 

Le 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">
        &copy; Copyright 2015 - Company name<br /><br />
        St Winifrids St,<br />
        The Saints, Harrogate HG1 5PZ, UK<br />
    </div>
  </div>
</div>

Le 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%); 
}

JSFiddle

1
amjgbr

Voici une version modifiée de la réponse ci-dessus, cette version a un parent relatif et un enfant absolus positionnés afin que nous puissions ajouter l'effet de survol. 

http://jsfiddle.net/3jo5btxd/

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;
}
1
zeros-and-ones

je pense que la meilleure solution est la méthode des pseudo-éléments. Nice et propre et ne pollue pas le code HTML avec (trop) d'éléments supplémentaires.

J'ai créé ce sass mixin en utilisant le code ci-dessus, pour une solution copier-coller:

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

Ensuite, vous pouvez l'utiliser comme ceci:

html:

<div class="border">
    <div class="content">
        Content
    </div>
</div>

SCSS

.border {
    @include corner-borders;
}

.content {
    position: relative;
    z-index: 1;
}

Vous avez besoin de l'index z et de la position relative pour que le contenu se trouve au-dessus des pseudo-éléments.

J'ai fait une démonstration de codepen ici: http://codepen.io/timrross/pen/XMwVbV

0
Tim