html - tag - ¿Es posible crear esta forma(dos círculos parciales unidos) con CSS?
title tag html (5)
Estaba tratando de lograr este borde para dos divs con CSS:
Intenté simplemente usar border-radius
, pero los dos círculos parciales no se presionaron juntos: 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>
Podría presionarlos aún más, pero tendría que tener un div superpuesto al otro, así: 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>
¿Alguien sabe cómo podría lograr esto sin tener la superposición de div?
SVG
Esto también es posible usando SVG.
La versión SVG es muy corta, ya que solo requiere un comando de arco para controlar su forma, tamaño y posición.
<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 significa Scalable Vector Graphic. El navegador web lo ve como una imagen, pero puede agregar texto y elementos HTML normales dentro de un SVG.
Está bien soportado en todos los navegadores como se puede ver aquí: CanIUse
Aquí hay un ejemplo rápido que se me ocurrió. No lo he probado en diferentes navegadores pero debería ser bastante compatible.
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;
}
Aquí hay una solución usando solo un <div>
.
-
.shape
es un círculo transparente con un10px
rojo de 1010px
. -
.shape::before
es un círculo blanco opaco con un10px
rojo de 1010px
. -
.shape::after
es un círculo blanco opaco (sin borde).
.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>
Estoy volviendo a esta pregunta (después de 6 semanas), simplemente porque la respuesta más votado despertó mi curiosidad académica en svg
, que rara vez me he encontrado y nunca me tomé el tiempo para aprender.
Como ahora estoy aprendiendo svg
, esta pregunta (que me envió en mi búsqueda para aprenderla en primer lugar) parecía ser el desafío ideal contra el cual probar algunas habilidades nuevas.
Así que aquí hay una solución svg
alternativa , el equivalente de mi única solución <div>
css anterior:
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>
Usar bordes: recomendado
Puede hacerlo de la misma manera que en su segundo fragmento y usar el posicionamiento como en el siguiente fragmento para evitar que los dos elementos div
solapen. Aquí los círculos son producidos por pseudoelementos y la parte superpuesta se corta usando overflow: hidden
en sus padres.
Una cosa a tener en cuenta aquí es que cualquier efecto de desplazamiento se debe agregar a los pseudo-elementos y no a los elementos principales. Esto se debe a que si :hover
está conectado al elemento primario, se activará incluso cuando se encuentre fuera del círculo (porque el elemento primario sigue siendo un cuadrado).
De todas las tres soluciones proporcionadas en esta respuesta, esta es la que tiene el mejor soporte de navegador y funcionaría incluso en IE8. Por lo tanto, este es el recomendado.
.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>
Usando degradados radiales:
Si no desea utilizar pseudoelementos y un overflow: hidden
en el elemento primario, también puede utilizar imágenes de fondo con radial-gradient
para generar el círculo y ubicarlos de manera que terminen produciendo el efecto requerido. A continuación se muestra un fragmento de muestra para este enfoque.
La desventaja de este enfoque es el bajo soporte del navegador para radial-gradient
. No funcionaría en IE9 y más bajo. Además, los círculos producidos por los gradientes radiales son generalmente irregulares (bordes ásperos) y cuando modificamos las posiciones de detención del color para hacerlo más suave, da una apariencia ligeramente borrosa.
.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>
Usar rutas de clip (CSS / SVG):
Otro enfoque que podría usarse es usar clip-path
. La ventaja de este enfoque es que los efectos de hover
se activan solo cuando el cursor está dentro del círculo (como se puede ver en un fragmento). Esto se debe a que las partes innecesarias están recortadas.
La desventaja es otra vez la mala compatibilidad con el navegador . La versión CSS de clip-path
solo se admite en Webkit pero no en Firefox, IE mientras que la versión SVG (usando SVG en línea) es compatible con Webkit, Firefox pero no con 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>