Forme CSS 3: "Cercle inversé" ou "cercle découpé""

je veux créer une forme, que je décrirais comme "cercle inversé":

<a href=CSS Shape" src="/images/content/10501488/79982de1c1d542f384e720bf767c00dd.png">

l'image est en quelque sorte inexacte, parce que la ligne noire devrait continuer le long de la frontière extérieure de l'élément div.

Voici une démo de ce que j'ai en ce moment: http://jsfiddle.net/n9fTF /

est-ce possible avec CSS sans images?

40
demandé sur web-tiki 2012-05-08 19:17:05

6 réponses

mise à jour: CSS3 Radial Background Gradient Option

(pour les navigateurs qui le supportent--testé en FF et Chrome--IE10, Safari devrait fonctionner aussi).

Un "problème" avec ma réponse originale à cette question est des situations où on n'a pas un arrière-plan solide qu'ils travaillent contre. Cette mise à jour crée le même effet permettant un "gap" transparent entre le cercle et son découpage inverse.

voir exemple violon .

CSS

.inversePair {
    border: 1px solid black;
    display: inline-block;    
    position: relative;    
    height: 100px;
    text-align: center;
    line-height: 100px;
    vertical-align: middle;
}

#a {
    width: 100px;
    border-radius: 50px;
    background: grey;
    z-index: 1;
}

#b {
    width: 200px;
    /* need to play with margin/padding adjustment
       based on your desired "gap" */
    padding-left: 30px;
    margin-left: -30px;
    /* real borders */
    border-left: none;
    -webkit-border-top-right-radius: 20px;
    -webkit-border-bottom-right-radius: 20px;
    -moz-border-radius-topright: 20px;
    -moz-border-radius-bottomright: 20px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
    /* the inverse circle "cut" */
    background-image: -moz-radial-gradient(
        -23px 50%, /* the -23px left position varies by your "gap" */
        circle closest-corner, /* keep radius to half height */
        transparent 0, /* transparent at center */
        transparent 55px, /*transparent at edge of gap */
        black 56px, /* start circle "border" */
        grey 57px /* end circle border and begin color of rest of background */
    );
    background-image: -webkit-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: -ms-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: -o-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
}

Réponse Originale

a pris plus d'effort que je m'y attendais pour faire fonctionner l'indexation en z ( cela semble ignorer l'index en Z négatif ), cependant, cela donne un bel aspect propre (testé en IE9, FF, Chrome):

HTML

<div id="a" class="inversePair">A</div>
<div id="b" class="inversePair">B</div>

CSS

.inversePair {
    border: 1px solid black;
    background: grey;
    display: inline-block;    
    position: relative;    
    height: 100px;
    text-align: center;
    line-height: 100px;
    vertical-align: middle;
}

#a {
    width: 100px;
    border-radius: 50px;
}

#a:before {
    content:' ';
    left: -6px;
    top: -6px;
    position: absolute;
    z-index: -1;
    width: 112px; /* 5px gap */
    height: 112px;
    border-radius: 56px;
    background-color: white;
} 

#b {
    width: 200px;
    z-index: -2;
    padding-left: 50px;
    margin-left: -55px;
    overflow: hidden;
    -webkit-border-top-right-radius: 20px;
    -webkit-border-bottom-right-radius: 20px;
    -moz-border-radius-topright: 20px;
    -moz-border-radius-bottomright: 20px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
}

#b:before {
    content:' ';
    left: -58px;
    top: -7px;
    position: absolute;
    width: 114px; /* 5px gap, 1px border */
    height: 114px;
    border-radius: 57px;
    background-color: black;
} 
52
répondu ScottS 2012-05-25 01:04:19

Je ne peux pas vraiment dire à partir de votre dessin comment arrondi vous voulez les points, mais voici une possibilité: http://jsfiddle.net/n9fTF/6/

si les points doivent être plus arrondis, vous aurez besoin de mettre quelques cercles sur les extrémités afin qu'ils se fondent avec le grand scoop.

8
répondu Chris Fletcher 2012-05-08 15:27:38

approche Différente : Box-ombre

Cette approche utilise de boîte CSS ombres qui sont , soutenu par IE9+ ( canIuse )

DÉMO

sortie:

CSS shape with inset curve using box-shadows

HTML:

<div id="a">
    <div id="b"></div>
</div>

CSS :

#a{
    overflow:hidden;
    border-radius:20px;
    position:relative;
    display:inline-block;
}
#a:before, #a:after{
    content:'';
    width: 100px;
    border-radius: 50%;
}
#a:before {
    height: 100px;
    float:left;    
    border: 1px solid black;
    background: grey;
}
#a:after {
    position:absolute;
    left:14px; top:-6px;
    height:114px;
    box-shadow: 1px 0px 0px 0px #000, 110px 0px 0px 68px #808080;
    background:none;
    z-index:-1;
}
#b {
    width: 200px;
    height: 100px;
    background:none;
    margin-left:-15px;
    border: 1px solid black;
    border-left:none;
    float:left;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
}
5
répondu web-tiki 2014-07-15 19:33:30

C'est une question très intéressante. J'ai récemment posté un tutoriel sur la façon de faire rayon frontière Inverse dans CSS (ici) et je pense que cela pourrait facilement être adapté pour votre cas.

le truc est de créer une portée qui génère la bordure inverse en utilisant un concept très simple - des frontières très épaisses. Et utilisez la section intérieure en les cachant. Ce que vous auriez à faire en plus de mon script fourni est d'ajouter un autre border-radius au coin en haut à gauche car je n'utilise que le coin en haut à droite. Faites la portée alignée à gauche de l'article que vous voulez par positionnement absolu, et augmentez la hauteur/largeur de la portée en conséquence et voilà vous avez votre bord-rayon inverse .

1
répondu Jon Mifsud 2012-07-14 12:32:15

Quelqu'un d'autre l'a fait quelque part d'après ce que j'ai trouvé...

JSFiddle: http://jsfiddle.net/ajeN7 /

et la question: CSS3 coin arrondi inversé

espérons que ça aide!

0
répondu Rick Donohoe 2017-05-23 11:46:58

introduisent un cercle blanc absolument sans bordures qui se trouve derrière le cercle gris à un décalage. Vous devez définir le z-index du cercle noir pour s'assurer qu'elle est au-dessus du cercle blanc:

#c {
    position: absolute;
    border: 0;
    left: 30px;
    width: 100px;
    height: 100px;
    border-radius: 50px;
    background: white;
}

Démo.

0
répondu karim79 2012-05-08 15:27:43