i am trying to create a frosted glass (blurred) background with a circle shape section of it unblurred with no success
this is what i got so far in sandbox editor, but there is a problem with this implementation
the area of the circle is staying blurred
https://codesandbox.io/s/frosted-glass-background-with-spotlight-fwdhd
note: the sandbox has been created with vue 2 but it is a simple problem to reproduce in vanilla
i think that it can be done with canvas html tag but i am not sure on the way to implement it.
can some one please help?
You can do this in CSS by using mask-image and CSS filter.
The example below uses a transparent PNG with a circle as the mask, and the filter property to blur the image below.
img {
max-width: 100%;
display: block;
}
.container {
width: 400px;
height: 300px;
margin: 1em auto;
position: relative;
}
.container img {
height: 100%;
width: 100%;
object-fit: cover;
-webkit-mask-size: cover;
mask-size: cover;
position: absolute;
top: 0;
left: 0;
}
.container img.overlay {
filter: blur(10px);
}
.container img.underlay {
-webkit-mask-image: url(https://i.imgur.com/l4o4AkX.png);
mask-image: url(https://i.imgur.com/l4o4AkX.png);
z-index: 2;
}
<div class="container">
<img class="underlay" src="https://cdn.glitch.com/04eadd2b-7dd4-43fc-af3d-cff948811986%2Fballoons.jpg?v=1597755892826" alt="Balloons">
<img class="overlay" src="https://cdn.glitch.com/04eadd2b-7dd4-43fc-af3d-cff948811986%2Fballoons.jpg?v=1597755892826" alt="Balloons">
</div>
I have some css in place that uses both a border-radius and a grayscale filter. I want the border radius to be in place all the time but the grayscale to disappear on hover.
The border radius works fine until I add in the grayscale, then it stops working and just shows the images as a square. On hover (when the filter is removed) the border-radius kicks in again. Does anyone know what I am missing?
I have searched but can't find an answer.
.esg-entry-media {
width: 250px;
height: 250px;
margin: 0 auto;
-webkit-border-radius: 50% !important;
border-radius: 50% !important;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.esg-entry-media:hover {
border: solid 10px #fff !important;
-webkit-filter: grayscale(0%);
filter: grayscale(0%);
}
I have included an image of the hover and non-hover states for reference.
You could use a div to wrap around the image put an overflow: hidden; on it and give the div the same width and height. Then put border-radius: 50%; on the div. Only apply the grayscale on the image. At the end to change the img do,
div:hover .esg-entry-media{
filter: grayscale(0)
}
On the wrapping div do,
div:hover {
border: 10px solid *coloryouwant*
}
which browser? works fine for me (chrome, firefox, safari):
.esg-entry-media {
width: 250px;
height: 250px;
border: 10px solid transparent;
border-radius: 50%;
filter: grayscale(100%);
}
.esg-entry-media:hover {
border-color: #a00;
filter: grayscale(0%);
}
<img src="http://placekitten.com/200/300" class="esg-entry-media" />
In the photo above where the gray container is set I want to add a high contrast black and white photo filter.
Iv tried scaling the opacity and using the filter css3 property but have had no success.
The body is the background image and the child container is the gray box. I want to just have the child show the black and white.
body{
background: url('../images/wtc.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.profile-box{
background-color: grey;
width: 80%;
height: 60%;
margin-top: 180px;
margin-bottom: 100px;
}
Easiest solution, but least supported: backdrop-filter
The most straight-forward way, is to actually use the rather new backdrop-filter property. Unfortunately it is only supported in Safari (and Chrome Canary) so far.
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box{
width: 80%;
height: 60%;
/* Backdrop filter */
-webkit-backdrop-filter: grayscale(100%);
backdrop-filter: grayscale(100%);
/* Additional styles for positioning */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="profile-box"></div>
The code snippet above will render something similar to this on Safari:
Complicated solutions, but more cross-browser compatible
Using the deprecated clip:
An alternative solution that will see more support across browser is to use the clip: rect(...) property. This property has been, however, deprecated in favour of clip-path (see next section for the updated solution). Since you have specified on your code that you wanted a grayscale area that is 80% in width and 60% in height (relative to viewport, so that is equivalent to 80vw and 60vh), we can tune the arguments passed into clip: rect(...) as such:
clip: rect(30vh, 90vw, 70vh, 10vw);
The coordinates represent offset from the top/left corners of the page of the top, right, bottom, left edges of the clip rectangle. To center a 80vw horizontally, we need 10vw on left and right (adding up to 20vw). To center a 60vh vertically, we need 20vh on top and bottom (adding up to 40vh). This computes to:
20vh from the top (this is the TOP border measured from top)
90vw from the left (this is the RIGHT border measured from left)
80vh from the top (this is the BOTTOM border measured from top)
10vw from the left (this is the LEFT border measured from left)
The image below will help you explain the calculations more:
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box {
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
filter: grayscale(100%);
clip: rect(20vh, 90vw, 80vh, 10vw);
}
<div class="profile-box"></div>
Using the new property, clip-path:
Even though it is a more modern standard compared to clip, it still suffers from non-support in IE or Edge. The arguments of clip-path: inset(...) are not comma-separated, unlike that of clip: rect(...), and it is slightly more intuitive to use because each edge is measure relative to the corresponding edge of the browser. In that case, using the same calculation logic we have established above, the arguments will be:
20vh from the top
10vw from the right
20vh from the bottom
10vw from the left
In other words, something like this:
clip-path: inset(20vh 10vw 20vh 10vw);
body{
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
margin: 0;
padding: 0;
}
.profile-box {
background: url('https://i.imgur.com/uh5YLj5.jpg') no-repeat center center fixed;
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
filter: grayscale(100%);
clip-path: inset(20vh 10vw 20vh 10vw);
}
<div class="profile-box"></div>
What you are trying to do is usually a pretty hard thing to achieve with css but it is possible. I think this answer will help you:
TAKEN FROM https://stackoverflow.com/a/19382357/8312881
written by edensource
If it has to be dynamic, you should have some trouble, but you can
have somewhere to start with this :
HTML
<div class="background"></div>
<div class="mask">
<div class="bluredBackground"></div>
</div>
<div class="content"></div>
CSS
.content {
width: 70%;
height: 70%;
border:2px solid;
border-radius:20px;
position: fixed;
top: 15%;
left: 15%;
z-index:10;
background-color: rgba(168, 235, 255, 0.2);
}
.background {
width:100%;
height:100%;
background-image:url('http://www.travel.com.hk/region/time_95.jpg');
z-index:2;
position:fixed;
}
.bluredBackground {
width:100%;
height:100%;
display:block;
background-image:url('http://www.travel.com.hk/region/time_95.jpg');
z-index:1;
position:absolute;
top:-20%;
left:-20%;
padding-left:20%;
padding-top:20%;
-webkit-filter: blur(2px);
}
.mask {
width: 70%;
height: 70%;
border:2px solid;
border-radius:20px;
position: fixed;
top: 15%;
left: 15%;
z-index:10;
overflow:hidden;
}
FIDDLE
http://jsfiddle.net/sE4Fv/
FIDDLE with greyscale filter
http://jsfiddle.net/sE4Fv/926/
(you did not respond to my question in comments, so i still go with an average answer untill feedback shows ;) )
you can use an rgba() color if the matter is to darken your image.
A simple example with background or image to show the idea, a third example showing the use of the grayscale(X%) filter if the matter is turn blac & white the image:
.filter {
position: relative;
float: left;
width: 50%;
}
.filter:before {
content: '';
position: absolute;
top: 15%;
right: 5%;
bottom: 15%;
left: 5%;
background: rgba(0, 0, 0, 0.5);
}
.filter img {
display: block;
width: 100%;
}
.filter.bg {
box-sizing: border-box;
padding: 1.5% 2.5%;
background: url(http://lorempixel.com/1200/250/city/5) center / 100% auto;
}
.bg:before {
display: none;
}
.content {
min-height: 7.45vw;
height: 100%;
background: rgba(0, 0, 0, 0.5)
}
.grayscale .content {
background: url(http://lorempixel.com/1200/250/city/5) center / 50vw auto;
filter: grayscale(100%);
}
body {
margin: 0;
}
<div class="filter">
<img src="http://lorempixel.com/1200/250/city/5" alt="my nice City" /></div>
<div class="filter bg ">
<div class="content">Some content hover the bg </div>
</div>
<div class="filter bg grayscale ">
<div class="content">Some content hover the bg </div>
</div>
Your body is ok, just the .profile-box needs some fixes:
div.profile-box {
background: url('https://s3-us-west-1.amazonaws.com/powr/defaults/image-slider2.jpg') no-repeat center center fixed;
background-size: cover;
filter: grayscale(100%);
// width & height etc...
}
Attach your background in the box as well and add filter: grayscale(100%)
Demo
I need to put a set of b/w images with colored borders on the page. I don't want to edit the images in Photoshop, since there may be some dynamically added ones later on; hence, I've used the corresponding filter:grayscale(100%).
img.myImage {
display: block;
position: relative;
border: 6px solid #0090ff;
width: 85%;
margin: 0 auto;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
However, it affects the colored border, which also becomes grayish. Is there a "painless" workaround here?
Since img does not accept :after/:before, and since filter seems to apply on children elements, the only solution I can think of is the basic:
div {
display: inline-block;
background-color: #0090ff;
padding: 6px;
width: 200px;
}
img {
display: block;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
width: 100%;
}
<div>
<img src="https://pbs.twimg.com/profile_images/562466745340817408/_nIu8KHX.jpeg" alt="" />
</div>
I want the div to appear like it is blurring the background image of the page. Should work when div position is changed. Consider window resizing.
I was able to come up with a neat solution that requires no js. The technique was to use the same backgroud with specific common settings
JSFIDDLE
HTML:
<div class="mydiv">
<div class='bgblur'></div>
</div>
CSS:
body {
background: url('/etc/bg.jpg') no-repeat center center fixed;
background-size: cover;
}
.bgblur {
background: url('/etc/bg.jpg') no-repeat center center fixed;
background-size: cover;
-webkit-filter: blur(26px);
-moz-filter: blur(26px);
position: absolute;
height: 100%;
width: 100%;
z-index: -1;
}
.mydiv {
position: relative;
overflow: hidden;
// not necessary
border: 2px solid black;
height: 200px;
width: 200px;
}