web-dev-qa-db-fra.com

Forme CSS 3: "Inverse Circle" ou "Cut Out Circle"

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

CSS Shape

L'image est en quelque sorte inexacte, car la ligne noire doit continuer le long de la bordure 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 même possible avec CSS sans images?

40
Alp

Mise à jour: option de dégradé d'arrière-plan radial CSS3

(Pour les navigateurs qui le prennent en charge - testé dans FF et Chrome - IE10, Safari devrait également fonctionner).

Un "problème" avec ma réponse originale est ces situations où l'on n'a pas une solide expérience contre laquelle ils travaillent. Cette mise à jour crée le même effet permettant un "espace" transparent entre le cercle et sa découpe 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

J'ai pris plus d'efforts que prévu pour que le z-indexage fonctionne ( cela semble ignorer le z-index négatif ), cependant, cela donne un joli look épuré (testé dans 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;
} 
53
ScottS

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

Si les points doivent être plus arrondis, vous devrez mettre des cercles aux extrémités pour qu'ils se mélangent avec le gros scoop.

8
Chris Fletcher

Approche différente: Box-shadows

Cette approche utilise des ombres de boîte CSS qui sont prises en charge par IE9 + ( canIuse )

DÉMO

Production :

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

C'est une question très intéressante. J'ai récemment publié un tutoriel sur la façon de faire Inverse Border Radius en CSS (ici) et je pense que cela pourrait facilement être adapté à votre cas.

L'astuce consiste à créer une plage qui génère la bordure inverse en utilisant un concept très simple - des bordures très épaisses. Et utilisez la section intérieure en les cachant. Ce que vous auriez à faire en plus de mon script fourni, c'est d'ajouter un autre rayon de bordure dans le coin supérieur gauche car je n'utilise que le coin supérieur droit. Rendez la travée alignée à gauche de l'élément que vous voulez par positionnement absolu, et augmentez la hauteur/largeur de la travée en conséquence et le tour est joué inverse border-radius .

1
Jon Mifsud

Introduisez un cercle blanc sans bordure absolument positionné qui se trouve derrière le cercle gris avec un décalage. Vous devrez définir le z-index du cercle sombre pour vous assurer qu'il se trouve au-dessus du cercle blanc:

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

Démo.

0
karim79

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

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

et la question: CSS3 Inverted Rounded Corner

J'espère que cela aide!

0
Rick Donohoe