Le demi-cercle Transparent découpé du div
je voudrais faire une découpe transparente en forme de demi-cercle en utilisant seulement CSS3. La seule exigence est que tous les éléments qui forment la forme doit être noir ou transparent.
I ne peut pas utiliser un rectangle noir avec un cercle blanc en haut, parce que le demi-cercle doit être transparent et de laisser l'arrière-plan.
forme Désirée :
7 réponses
peut-être le faire avec CSS
:after
pseudo propriété comme ceci:
.rect
{
height: 100px;
width: 100px;
background:rgba(0,0,0,0.5);
position:relative;
margin-top:100px;
margin-left:100px;
}
.circle{
display:block;
width: 100px;
height: 50px;
top:-50px;
left:0;
overflow:hidden;
position:absolute;
}
.circle:after{
content:'';
width: 100px;
height: 100px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
background:rgba(0,0,0,0);
position:absolute;
top:-100px;
left:-40px;
border:40px solid rgba(0,0,0,0.5);
}
http://jsfiddle.net/FcaVX/2/
vous pouvez utiliser box-shadows pour faire le cercle transparent découpé:
body {
background: url(http://i.imgur.com/qi5FGET.jpg) no-repeat;
background-size: cover;
}
div {
display: inline-block;
width: 300px; height: 300px;
position: relative;
overflow: hidden;
}
div:before {
content: '';
position: absolute;
bottom: 50%;
width: 100%; height: 100%;
border-radius: 100%;
box-shadow: 0px 300px 0px 300px #000;
}
.transparent {
opacity: 0.5;
}
<div></div>
<div class="transparent"></div>
Cela peut être responsive avec un pourcentage longueurs:
body {
background: url(http://lorempixel.com/output/people-q-c-640-480-1.jpg) no-repeat;
background-size: cover;
}
div {
width: 40%; height: 300px;
position: relative;
overflow: hidden;
}
div:before {
content: '';
position: absolute;
bottom: 50%;
width: 100%; height: 100%;
border-radius: 100%;
box-shadow: 0px 300px 0px 300px #000;
}
.transparent {
opacity: 0.5;
}
<div class="transparent"></div>
utilisation de SVG:
Voici une solution alternative utilisant SVG (même si vous ne l'avez pas étiqueté). Les avantages de L'utilisation de SVG sont:
- il a une meilleure prise en charge du navigateur par rapport aux gradients radiaux.
- SVG peut supporter des images à l'intérieur de la forme contrairement à l'approche boîte-ombre.
alors que SVG n'est pas supporté par <= IE8 alors que box-shadow l'est, les retombées peuvent être fourni.
svg {
height: 150px;
width: 150px;
}
polygon {
fill: black;
}
/* Just for demo */
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<!-- Sample 1 - Using Clip Path -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<defs>
<clipPath id='clipper'>
<path d='M0,0 a50,50 0 1,0 100,0 l 0,100 -100,0' />
</clipPath>
</defs>
<polygon points='0,0 100,0 100,100 0,100' clip-path='url(#clipper)' />
</svg>
<!-- Sample 2 - Using Path -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<pattern id='bg' width='100' height='100' patternUnits='userSpaceOnUse'>
<image xlink:href='http://lorempixel.com/100/100/nature/1' height='100' width='100' />
</pattern>
<path d='M0,0 a50,50 0 1,0 100,0 l 0,100 -100,0 0,-100' fill='url(#bg)' />
</svg>
à l'Aide de CSS:
CSS a aussi clip-path
spécifications et nous pouvons essayer quelque chose comme dans le snippet ci-dessous.
.shape {
position: relative;
width: 100px;
height: 100px;
background-color: purple;
}
.shape:after {
position: absolute;
content: '';
top: 0px;
left: 0px;
height: 100%;
width: 100%;
background: white;
-webkit-clip-path: ellipse(50% 20% at 50% 0%);
clip-path: ellipse(50% 20% at 50% 5%);
}
.shape.image{
background: url(http://lorempixel.com/100/100);
}
#shape-2 {
width: 100px;
height: 100px;
background-color: purple;
-webkit-clip-path: ellipse(50% 20% at 50% 20%);
clip-path: ellipse(50% 20% at 50% 20%);
}
/* Just for demo */
.shape{
float: left;
margin: 20px;
}
#shape-2 {
margin: 150px 20px 0px;
}
<div class="shape"></div>
<div class="shape image"></div>
<br/>
<div id="shape-2"></div>
mais contrairement à SVG clip-path, la version CSS pure (c'est-à-dire sans utiliser de SVG interne ou externe) ne semble pas pouvoir supporter un path
. Il ne supporte que les formes et donc dans ce cas, si vous utilisez clip-path
sur le parent directement il produirait juste une ellipse (comme montré dans l'extrait). Pour surmonter cette difficulté, nous devrions mettre le clip-chemin sur un enfant (ou un pseudo-élément) et cela signifierait que l' la zone coupée ne serait pas transparente.
Utilisation De La Toile:
la même chose peut être faite en utilisant la toile aussi. Toile commandes sont assez similaires à SVG et leurs avantages sont également très similaires. Cependant, Toile sont basés sur des modèles matriciels et ne se dimensionnent donc pas aussi bien que SVG.
window.onload = function() {
/* Canvas example with path */
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'http://lorempixel.com/150/300';
ctx.beginPath();
ctx.moveTo(110, 0);
ctx.arc(60, 0, 50, 0, 3.14, false);
ctx.lineTo(10, 145);
ctx.lineTo(110, 145);
ctx.closePath();
ctx.fill();
/* Use below for using image as a fill */
/*img.onload = function(){
var ptrn = ctx.createPattern(img,'no-repeat');
ctx.fillStyle = ptrn;
ctx.fill();
}*/
}
/* Canvas example with clip path */
var canvasClip = document.getElementById('canvas-clip');
if (canvasClip.getContext) {
var ctxClip = canvasClip.getContext('2d');
ctxClip.beginPath();
ctxClip.moveTo(10, 145);
ctxClip.lineTo(10, 0);
ctxClip.arc(60, 0, 50, 0, Math.PI * 2, true);
ctxClip.lineTo(110, 145);
ctxClip.lineTo(10, 145);
ctxClip.clip();
ctxClip.fillStyle = 'tomato';
ctxClip.fill();
}
}
canvas {
height: 150px;
width: 300px;
}
/* Just for demo */
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<canvas id='canvas'></canvas>
<canvas id='canvas-clip'></canvas>
Utilisation De Masques:
cette forme peut aussi être créée en utilisant des masques CSS (ou) SVG. Les masques CSS ont un très mauvais support et ne fonctionnent actuellement que dans les navigateurs WebKit, mais les masques SVG ont un meilleur support et devraient fonctionner dans IE9+.
/* CSS Mask */
.shape {
width: 150px;
height: 150px;
background-color: black;
-webkit-mask-image: radial-gradient(circle closest-corner at 50% 0%, transparent 98%, white 99%);
mask-image: radial-gradient(circle closest-corner at 50% 0%, transparent 98%, white 99%);
}
/* End of CSS Mask */
svg {
height: 150px;
width: 150px;
}
polygon#shape {
fill: black;
mask: url(#masker);
}
/* Just for demo */
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<!-- CSS Mask -->
<div class='shape'></div>
<!-- SVG Mask -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<defs>
<mask id='masker' x='0' y='0' width='100' height='100'>
<polygon points='0,0 100,0 100,100 0,100' fill='#fff' />
<circle r='50' cx='50' cy='0' fill='#000' />
</mask>
</defs>
<polygon points='0,0 100,0 100,100 0,100' id='shape' />
</svg>
Vous pouvez le faire très facilement avec un dégradé radial.
DEMO
Résultat:
HTML:
<div class='shape'></div>
CSS:
.shape {
margin: 0 auto;
width: 10em; height: 16em;
/* WebKit browsers, old syntax */
background: -webkit-radial-gradient(50% 0, circle, transparent 30%, black 30%);
/* IE10, current versions of Firefox and Opera */
background: radial-gradient(circle at 50% 0, transparent 30%, black 30%);
}
http://caniuse.com/#feat=css-gradients pour des informations détaillées sur la compatibilité.
Kyle Sevenokas a fait du bon travail. Et j'ai construit à partir de ça. La caisse de l' http://jsfiddle.net/FcaVX/1/
j'ai en gros effondré la div blanche pour le cercle et lui ai donné des bordures blanches. La question de L'OP parlait des éléments de couleurs qui composent la forme; rien sur ses frontières n'est-ce pas?
j'avais besoin de coins arrondis seulement au bas d'une image réactive. Je suis parti de @ sandeep fiddle et l'ai amélioré pour mes besoins:
.rect
{
height: 85vh;
position: relative;
background-color: red;
width: 60vw;
}
.circle-helper{
display: block;
width: 100%;
padding-bottom: 50%;
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
background-color: transparent;
}
.circle{
display: block;
width: 100%;
padding-bottom: 100%;
// height: 500px;
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
background-color: transparent;
}
.circle:after{
box-sizing: content-box;
content: '';
width: 100%;
height: 100%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
background: rgba(0,0,0,0);
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
border: 300px solid blue;
}
top: 50%
left: 50%
border: 300px solid blue
pour l'instant, le seul moyen que je puisse imaginer serait d'utiliser beaucoup de divs noires de 1 pixel de large à côté de l'autre avec une hauteur variable. C'est techniquement possible, mais ça doit être très mal vu. De plus, vous n'aurez pas d'anti-aliasing à moins que vous ne vouliez passer par la difficulté d'ajouter 1x1 pixel divs et faire l'anti-aliasing manuellement.
Il pourrait être plus utile si vous avez donné un exemple de comment vous voulez utiliser cette. Pourquoi doit-il être noir/transparent seulement? Comme l'a déclaré par omarello, la meilleure solution sur la plupart des circonstances est probablement une simple image GIF ou PNG avec transparence.