42 votes

Est-il possible de créer cette forme (deux cercles partiels réunis) avec CSS?

Je tente d'accomplir cette frontière pour deux divs avec les CSS:

Desired result

J'ai essayé tout à l'aide d' border-radius, mais les deux cercles partiels ne sont pas pressés ensemble: http://jsfiddle.net/uwz6L79w/

 .left {
   position: absolute;
   left: 0;
   top: 0;
   width: 100px;
   height: 100px;
   border-width: 4px;
   border-color: black white black black;
   border-style: solid;
   border-radius: 60px
 }
 .right {
   position: absolute;
   left: 104px;
   top: 0;
   width: 100px;
   height: 100px;
   border-width: 4px;
   border-color: black black black white;
   border-style: solid;
   border-radius: 60px;
 }
<div class="left"></div>
<div class="right"></div>

Je pourrais vous suffit d'appuyer sur eux, mais je dois avoir un div chevauchement de l'autre, comme ceci: http://jsfiddle.net/uwz6L79w/1/.

.left {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  border-width: 4px;
  border-color: black white black black;
  border-style: solid;
  border-radius: 60px
}
.right {
  position: absolute;
  left: 70px;
  top: 0;
  width: 100px;
  height: 100px;
  border-width: 4px;
  border-color: black black black white;
  border-style: solid;
  border-radius: 60px;
  background: #f2f2f2;
}
<div class="left"></div>
<div class="right"></div>

Personne ne sait comment je pourrait accomplir cela sans avoir les divs se chevauchent?

47voto

Stewartside Points 6787

SVG

Cela est également possible à l'aide de SVG.

La version SVG est très court comme il a principalement exige seulement un Arc de commande pour le contrôle de sa forme, de taille et de position.

<svg width="50%" viewbox="0 0 100 50">
  <path d="M50,35 
           a20,20 0 1,0 0,-20 
           a20,20 0 1,0 0,20z" 
        fill="white" 
        stroke="black">
  </path>
</svg>

SVG est synonyme de Scalable Vector Graphic. Le navigateur web vues comme une image, mais vous pouvez ajouter du texte et HTML normal éléments à l'intérieur d'un SVG.

Il est bien pris en charge dans tous les navigateurs comme visible ici: CanIUse

41voto

Harry Points 10265

L'Utilisation Des Bordures: Recommandée

Vous pourriez faire de la même façon que dans votre deuxième extrait de code et l'utilisation de positionnement comme dans l'extrait de code ci-dessous pour éviter les deux div éléments de chevauchement. Ici, les cercles sont produites par des pseudo-éléments et le chevauchement de la partie est découpée à l'aide de overflow: hidden sur leurs parents.

Une chose à noter ici est que toute hover effet devrait être ajouté sur les pseudo-éléments, et pas les éléments parents. C'est parce que si l' :hover est attaché à un parent alors il serait déclenchée, même lorsque vous vous déplacez à l'extérieur du cercle (parce que le parent est toujours un carré).

De tous les trois solutions proposées dans cette réponse, c'est celle qui a la meilleure prise en charge du navigateur et même dans IE8. Par conséquent, c'est celui qui est recommandé.

.left, .right {
  position: relative;
  float: left;
  height: 200px;
  width: 200px;
  /* border: 1px solid; uncomment to see that they aren't overlapped */
  overflow: hidden;
}
.left:after, .right:after {
  position: absolute;
  content: '';
  height: calc(100% - 12px); /* 12px because of 6px border on either side */
  width: calc(100% - 12px); /* 12px because of 6px border on either side */
  border-radius: 50%;
  border: 6px solid gray;
}
.left:after { right: -20px; }
.right:after { left: -20px; }
<div class='left'></div>
<div class='right'></div>

En Utilisant Les Dégradés Radiaux:

Si vous ne voulez pas utiliser de pseudo-éléments et un overflow: hidden sur le parent, alors vous pourriez également faire usage de radial-gradient images d'arrière-plan pour produire le cercle et la position de telle sorte qu'ils finissent par produire l'effet souhaité. Ci-dessous est un extrait d'exemple de cette approche.

L'inconvénient de cette méthode est la faible prise en charge du navigateur pour radial-gradient. Il ne serait pas travailler dans IE9 et inférieur. De Plus, les cercles produite par les dégradés radiaux sont généralement irréguliers (aspérités) et lorsque l'on modifie la couleur positions d'arrêt à la rendre plus lisse, elle donne une image légèrement floue apparence.

.left, .right {
  float: left;
  height: 200px;
  width: 200px;
  /*border: 1px solid;  uncomment to see that they aren't overlapped */
}

/* generally the below code should be enough to produce 6px thick circular border
.left {
  background: radial-gradient(circle at 70% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));
}
.right {
  background: radial-gradient(circle at 30% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));
}
*/

/* but it produces jagged edges and so we can change the color stops a bit like below
   this produces smoother circles but the disadvantage is that they'd look a bit blurred */
.left {
  background: radial-gradient(circle at 70% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));
}
.right {
  background: radial-gradient(circle at 30% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='left'></div>
<div class='right'></div>

À l'aide de Chemins d'accès du Clip (CSS/SVG):

Une autre approche consiste à utiliser clip-path. L'avantage de cette approche est que l' hover effets serait déclenché uniquement lorsque le curseur est à l'intérieur du cercle (comme on peut le voir dans l'extrait de code). C'est parce que l'inutile parties sont coupées.

La baisse est encore une fois la mauvaise prise en charge du navigateur. CSS version de clip-path est pris en charge uniquement dans Webkit, mais pas dans Firefox, IE alors que la version SVG (en ligne SVG) est pris en charge dans Webkit, Firefox mais pas IE.

.left, .right {
  float: left;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  border: 6px solid gray;
}

/* CSS Clip Path - not supported by FF and IE */
.left.css-clip {
  clip-path: polygon(0% 0%, 80% 0%, 80% 100%, 0% 100%);
}
.right.css-clip {
  margin-left: -86px;  /* 20% width * 2 (which is the clipped space) - border width */
  clip-path: polygon(20% 0%, 100% 0%, 100% 100%, 20% 100%);
}

/* SVG Clip Path - supported by Webkit, FF but not IE */
.left.svg-clip {
  clip-path: url(#clipper-left);
}
.right.svg-clip {
  margin-left: -86px;  /* 20% width * 2 (which is the clipped space) - border width */
  clip-path: url(#clipper-right);
}

/* Just for demo */

h3{ clear: both; }
.left:hover, .right:hover{ background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>

<h3>CSS Clip Path</h3>
<div class='left css-clip'></div>
<div class='right css-clip'></div>

<h3>SVG Clip Path</h3>
<div class='left svg-clip'></div>
<div class='right svg-clip'></div>

<!-- Inline SVG for SVG Clip Path -->
<svg width='0' height='0'>
  <defs>
    <clipPath id='clipper-left' clipPathUnits='objectBoundingBox'>
      <path d='M0,0 .8,0 .8,1 0,1z' />
      </clipPath>
    <clipPath id='clipper-right' clipPathUnits='objectBoundingBox'>
      <path d='M.2,0 1,0 1,1 .2,1z' />
      </clipPath>
    </defs>
  </svg>

12voto

Rounin Points 4260

Voici une solution à l'aide d'un seul <div>.

  1. .shape est un cercle transparent avec un 10px bordure rouge.
  2. .shape::before est opaque cercle blanc avec un 10px bordure rouge.
  3. .shape::after est un blanc opaque cercle (pas de bordure).

.shape {
margin: 6px auto;
}

.shape, .shape::before, .shape::after {
display: block;
position: relative;
width: 160px;
height: 160px;
border-radius: 160px;
}

.shape, .shape::before {
border: 10px solid #f00;
}

.shape::before, .shape::after {
content: "";
background-color: rgba(255, 255, 255, 1);
}

.shape::before {
top: -10px;
left: -150px;
}

.shape::after {
top: -180px;
}
<div class="shape">
</div>

8voto

Jeff Batterton Points 81

Voici un exemple rapide, je suis venu avec. Je ne l'ai pas testé sur différents navigateurs, mais il devrait être assez bien pris en charge.

HTML:

<div class="one"></div>
<div class="two"></div>

CSS:

div {
  background: #fff;
  border-radius: 50%;
  float: left;
  height: 100px;
  position: relative;
  width: 100px;
}

.one:after,
.two:after{
  /* adjust this to set the border color */
  background: #666;
  border-radius: 50%;
  content: "";
  position: absolute;
  z-index: -1;
  /* adjust these to set the border width */
  top: -5px;
  right: -5px;
  bottom: -5px;
  left: -5px;
}

.two {
  /* adjust this to set the overlap of the circles */
  margin-left: -20px;
}

Démonstration En Direct

2voto

Rounin Points 4260

Je reviens à cette question (après 6 semaines), simplement parce que le haut-voté réponse a piqué ma curiosité scientifique en svg, que j'ai rarement rencontré et jamais pris le temps d'apprendre.

Depuis que je suis en train d'apprendre svg, cette question (qui m'a envoyé sur mon quête de l'apprendre en premier lieu) semblait être le défi idéal contre pour essayer de nouvelles compétences.

Voici donc une alternative svg de la solution, l'équivalent de mon single <div> css solution ci-dessus:

svg {
width: 310px;
height: 180px;
}

svg circle {
stroke: rgb(255,0,0);
stroke-width: 10;
fill: rgb(255,255,255);
}

svg circle:nth-of-type(3) {
stroke: rgb(255,255,255);
}
<svg viewbox="0 0 310 180">
<circle cx="90" cy="90" r="80" />
<circle cx="220" cy="90" r="80" />
<circle cx="90" cy="90" r="70" />
</svg>

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