Reputation: 1847
How can I achieve such a thing in CSS?
I've tried so many ways but the dark background is still in the way and can't be clipped so the background image under it's invisible...
.item {
position: relative;
}
.item:before {
content: '';
size(100%);
top: 0;
left: 0;
z-index: 1;
background: rgba(0, 0, 0,0 0.1);
}
<div class="item">
<img>
<span class="rate">
<span class="amount">10</span> امتیاز
</span>
</div>
I'm looking for a way to be able to make parts of the dark background transparent, so the image can be seen.
Upvotes: 9
Views: 1312
Reputation: 1249
Infinite box-shadow
with overflow: hidden;
I don't know if it would work for you, I just tried-
<style>
.item img {
max-width: 100%;
vertical-align: top;
}
.item {
font-family: 'Amiri', serif;
width: 300px;
margin: 20px auto;
overflow: hidden; /* STEP-1 */
position: relative;
}
.rate {
position: absolute;
width: 100px;
height: 100px;
border-radius: 100%;
background: rgba(0,0,0,.7);
top: 80px;
left: 50%;
transform: translatex(-50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 22px;
color: #fff;
}
.rate::before {
position: absolute;
content: '';
width: calc(100% + 10px);
height: calc(100% + 10px);
top: -5px;
left: 50%;
transform: translatex(-50%);
border-radius: 100%;
box-shadow: 0 0 0 100vh rgba(0,0,0,.7); /* STEP-2 */
}
.amount {
font-size: 20px;
font-weight: 700;
display: block;
}
</style>
<link href="https://fonts.googleapis.com/css2?family=Amiri:wght@400;700&display=swap" rel="stylesheet">
<div class="item">
<img src="https://images.pexels.com/photos/4888690/pexels-photo-4888690.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Card title">
<span class="rate">
<span class="amount">١٠</span> امتیاز
</span>
</div>
Upvotes: 5
Reputation: 9984
This can be achieved using a radial gradient, (Example split onto separate lines to make it easier to read)
background-image: radial-gradient(
/* Position the circle at the center, 40px from the top */
circle at center 40px,
/* The center of the radius should be dark */
rgba(0,0,0,0.4) 0%,
/* This is the inner edge of the circle, we transition from dark-transparent between pixels 30 and 31 */
rgba(0,0,0,0.4) 30px, rgba(0,0,0,0) 31px,
/* This is the outer edge of the circle, we transition back from transprent-dark between pixels 34 and 35*/
rgba(0,0,0,0) 34px, rgba(0,0,0,0.4) 35px,
/* Everything outside of the circle should be dark */
rgba(0,0,0,0.4) 100%
);
Where circle at center 40px
defines the position of the circle relative to the parent element (Horizontally centred, an 40px down from the top) bare in mind this is the position for the centre of the circle so you do need to account for it's radius.
And we use very small steps between the gradient to make it look like a solid line rather than a blurred gradient (I find that a 1px
difference helps prevent aliasing on the line and makes everything look much smoother)
You can adjust the size of the circle or the thickness of the line by changing the 30px
, 31px
, 34px
and 35px
values in the gradient.
Working example:
.item {
position: relative;
width: 200px;
height: 200px;
background: url(https://picsum.photos/seed/picsum/200/200);
}
.item:before {
position: absolute;
content: '';
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
/* This is the ring itself, you can adjust it's size using the pixel values, leaving 1px differnce usually leaves the best result for smooth edges */
background-image: radial-gradient(circle at center 40px, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0.4) 30px, rgba(0, 0, 0, 0) 31px, rgba(0, 0, 0, 0) 34px, rgba(0, 0, 0, 0.4) 35px, rgba(0, 0, 0, 0.4) 100%);
}
<div class="item"></div>
(This method is browser compatible with pretty much every browser released since 2010)
Upvotes: 9
Reputation: 5281
As an alternative, I made .item
and its child elements Flexbox containers for easy positioning.
The circle is simply a circular element with a border.
All you have to do now is fiddle with sizes, colors and tranparency.
For the fun of it I added some :hover
effects...
snippet with comments
/* All are FBL containers, for easy positioning */
.item, .item>*, .rate {
display: flex;
justify-content: center; align-items: center;
}
.rate { flex-direction: column }
/* item content */
.item {
position: relative; /* position child elements to this parent */
width: 400px;
height: 600px;
/* set image to background of item */
background-image: url("https://i.ytimg.com/vi/fqumdSlyLxg/maxresdefault.jpg");
background-repeat: no-repeat;
background-size: cover; /* clip/stretch when too large/small */
background-color: rgba(0,0,0,0.3); /* some tranparent black */
background-blend-mode: overlay; /* mix bg-color with image */
/* eye-candy */
margin: 5rem auto; /* center */
font-size: 1.5em;
font-weight: bold;
color: rgba(255,255,255,.6);
border-radius: 12px;
}
.item>* {
position: absolute; /* position child inside parent */
width : 100px; height: 100px;
opacity: 0.7;
}
.rate { text-shadow: 0px 0px 7px rgba(255,255,255,.8) }
.circle {
border: 5px solid rgba(255,255,255,.3);
border-radius: 50%;
filter: blur(1px);
}
/******************************/
/* HOVER eye-candy, demo only */
/******************************/
.item:hover {
background-blend-mode: normal;
color: rgba(255,255,255,1);
}
.item:hover>* {
opacity: 1;
}
.item:hover .circle {
border-color: rgba(255,255,255,.8);
}
/* demo eye-candy */
.item {
/* GMC elevation 1dp */
box-shadow: 0px 2px 1px -1px rgba(0,0,0,.20),
0px 1px 1px 0px rgba(0,0,0,.14),
0px 1px 3px 0px rgba(0,0,0,.12);
}
.item:hover {
transform: scale(1.01);
/* GMC elevation 3dp */
box-shadow: 0px 3px 3px -2px rgba(0,0,0,.20),
0px 3px 4px 0px rgba(0,0,0,.14),
0px 1px 8px 0px rgba(0,0,0,.12);
}
/*.item:active:not(:focus) { transform: scale(1) }/* enable for some animation */
<div class="item">
<div class="circle"></div>
<div class="rate">
<span class="amount">10</span>
<span>text</span>
</div>
</div>
Upvotes: 0
Reputation: 8368
You could use a few divs with position: absolute
:
body {
margin: 0;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
.bg {
height: 100vh;
width: 100%;
background-image: url('https://i.ytimg.com/vi/fqumdSlyLxg/maxresdefault.jpg');
filter: brightness(0.4);
}
.circle {
position: absolute;
height: 150px;
width: 150px;
border-radius: 50%;
backdrop-filter: brightness(5);
-webkit-backdrop-filter: brightness(5);
z-index: 0;
}
.inner-circle {
position: absolute;
height: 142px;
width: 142px;
border-radius: 50%;
backdrop-filter: brightness(0.2);
-webkit-backdrop-filter: brightness(0.2);
z-index: 1;
}
.rate {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
position: absolute;
height: 142px;
color: white;
z-index: 2;
}
.amount {
font-size: 30px;
border-radius: 50%;
text-shadow: 0px 0px 5px #fff;
}
<div class="container">
<div class="bg"></div>
<div class="circle"></div>
<div class="inner-circle"></div>
<div class="rate">
<span class="amount">10</span>
<span class="amount">امتیاز</span>
</div>
</div>
Use the backdrop-filter
property to set the brightness and display: flex
on the container to center everything, then for the text use text-shadow
to make it luminous.
Upvotes: 2