40 votes

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

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

CSS Shape

L'image est en quelque sorte inexacte, car la ligne noire devrait se poursuivre le long du bord extérieur de l'élément div.

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

Est-ce que c'est même possible avec CSS sans images ?

53voto

ScottS Points 37738

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

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

L'un des "problèmes" de ma réponse initiale concerne les situations où l'on ne dispose pas d'un arrière-plan solide sur lequel travailler. Cette mise à jour crée le même effet en permettant un "espace" transparent entre le cercle et sa découpe inverse.

Voir l'exemple de 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

Il a fallu plus d'efforts que prévu pour que l'indexation en z fonctionne ( cela semble ignorer le z-index négatif ), cependant, cela donne un aspect propre et agréable (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;
}

8voto

Chris Fletcher Points 1728

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

Si les pointes doivent être plus arrondies, vous devrez mettre des cercles sur les extrémités pour qu'elles se fondent dans la grande pelle.

5voto

web-tiki Points 14660

Une approche différente : les ombres de la boîte

Cette approche utilise les ombres de boîte CSS qui sont supporté par IE9+ ( peut utiliser )

DEMO

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

1voto

Jon Mifsud Points 71

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

L'astuce consiste à créer un span qui génère la bordure inverse en utilisant un concept très simple : des bordures très épaisses. Et d'utiliser la section intérieure en les masquant. Ce que vous auriez à faire en plus de mon script fourni est d'ajouter un autre rayon de bordure au coin supérieur gauche car je n'utilise que celui du coin supérieur droit. Faites en sorte que le span soit aligné à gauche de l'élément que vous voulez par un positionnement absolu, et augmentez la hauteur/largeur du span en conséquence et voilà vous avez votre rayon de bordure inverse .

0voto

Rick Donohoe Points 1815

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é

J'espère que cela vous aidera !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X