Using a Jpeg to Mask another Image with pure CSS? - css

I need to use the black pixels of a Jpeg image as a "transparency layer" to mask another image.
When I use this PNG image as a mask, it works fine:
(it's a white square in an alpha background)
But I need to do the same with a Jpeg image, replacing the alphachannel with black ! (so without alpha channel).
Here's my CSS:
#selection-image {
width: 1000px;
height: 800px;
position: absolute;
-webkit-mask-image: urlhttps://image.noelshack.com/fichiers/2019/14/4/1554391365-output-onlinepngtools-2.png);
-webkit-mask-size: 1000px 800px;
mask-image: url(https://image.noelshack.com/fichiers/2019/14/4/1554391365-output-onlinepngtools-2.png);
mask-size: 1000px 800px;
mask-type: alpha;
background: red;
}
I cannot use canvas to delete the black pixel, as it takes too much time. I thought I could use the property mask-type: luminance, but it seems to work only with alpha channel too ..

Related

How to center an specific (x,y) point of a background image to a defined (x',y') coordinates of the CSS element that contains it?

I have read that in order to place a background image inside a container block in CSS you can use the background-position property. And you can give labels to it like, top-right-bottom-left-center or css units, mostly percents. And the way it acts is kind of like this:
background-position: 25% 25%, will place the (25%,25%) point of the background image from the top-right edge centered to the (25%,25%) point of the CSS element that contains that background.
So if I would like to center the (50% 50%) point of the background image to the (0,0) point of the container, how can I achieve it?
I know I can do it with pseudo elements (:before, :after) but is there a math calculation that can help me use the background property to make this work? Unfortunately I haven't found a property like a registry point that could allow me to place the point I would like use as my center for the background (background-origin despite the close meaning it is used for something completely different as I discovered).
This question is in regards to any situation but as an example I'm sharing a quick and simple snippet to make it more graphical.
By the way, I'm trying to find the most responsive solution I could. It will be much better if we can assume that I don't know the exact dimensions of the background image so that if I later change that image for another of different size, it stays centered to the same place. This means I prefer % over px.
.foo {
margin: 0 auto;
width: 400px;
height: 300px;
background: url('https://source.unsplash.com/random/200x200') no-repeat, blue
}
<! -- Let's supose I would like to center the (50%, 50%) of that image placeholder at the (0,0) of the container div. -- >
<div class='foo'></div>
Thanks in advance
Since you know the size of the background image (200x200), you can use half the amount of those pixel values as negative values for the background position in order to have the image's center exactly at the upper left corner of its div element. In your case, that would be background-position: -100px -100px;:
.foo {
margin: 0 auto;
width: 400px;
height: 300px;
background: url('https://source.unsplash.com/random/200x200') no-repeat, blue;
background-position: -100px -100px;
}
<! -- Let's supose I would like to center the (50%, 50%) of that image placeholder at the (0,0) of the container div. -- >
<div class='foo'></div>
Second version: If you use a regular image instead of a background-image, you can use transform: translate(-50%, -50%); on it, and overflow: hidden on the parent. So that way using percentage values works.
However, in this case it becomes more complex to add content to the main div if you also need the background color for the rest of the container - You'd have to add an absolutely positioned element for that.
.foo {
margin: 0 auto;
width: 400px;
height: 300px;
background: #bbf;
overflow: hidden;
position: relative;
}
.foo>img {
transform: translate(-50%, -50%);
}
.foocontent {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<div class='foo'>
<img src="https://source.unsplash.com/random/200x200" />
<div class="foocontent">
Here's some text and even some more text to demonstrate how text content could be placed above the image that serves as a background here.
</div>
</div>
The percentage unit cannot be used to offset the background image because it defines the entire image point relative to its container.
What you can do is define the size and position of the image, which uses pixel units.
Use background shorthand:
background: url(img) -100px -150px / 200px 300px;
body {
background: url(https://images.unsplash.com/photo-1519940640025-75fdf32010d7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1234&q=80) -100px -150px / 200px 300px no-repeat pink;
}

Curved border on one side still shows thin line on the other sides when background is transparent, ONLY in mobile - why does this happen?

Lately, I've gotten into making CSS art and I noticed something that I don't understand about CSS borders.
If I style an element to be rounded with a transparent background, and set a border on only one side, there's still a faint line on all the other sides that shows up only on mobile.
<div></div>
div {
width: 300px;
height: 150px;
background: transparent;
border-top: 5px solid purple;
border-radius: 50%;
}
Compare the following CodePen on a PC vs phone to see what I mean:
https://codepen.io/aradevich/pen/mdrLvqx
Screenshot:
ellipse with 5px top border
This effect is particularly bothersome when it skews facial features in CSS art, like with the eyes here on mobile: https://codepen.io/aradevich/pen/qBaxQye?editors=1100
Does anyone know why this happens, and how I can address it?
Thank you!
Here is a different idea to have the same result without the border issue:
div.box {
width: 300px;
height: 150px;
background:
/* 150 = width/2 70 = height/2 - 5px of border */
radial-gradient(151px 70px at bottom, transparent 98%,purple)
top/100% 50% no-repeat;
border-radius: 50% 50% 0 0;
}
<div class="box"></div>
As far I know, maybe it's caused by browser rendering. So, the solution is change the graphic image to SVG or PNG instead of css.

Applying mask to parent element in CSS, yet with no result

I am new to masks and can find very little help online... I've set a mask by making a grayscale JPG and applying it to the parent container. I want everything in that container to be masked according to my JPG's white/black pixels, but after applying the mask, I get no change at all.
Here is the CSS:
.site-branding {
position: absolute;
height: 100vh;
width: 100%;
-webkit-mask-image: url('media/masks/catchphrase-mask.jpg');
mask-image: url('media/masks/catchphrase-mask.jpg');
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-position: center;
mask-position: center;
}
Here is the page: https://satya-ame-art.com/index.php/qui-suis-je/
The idea is that the little character and the animated text should slide up from under the arc. So I need to mask them until they reach the upper half of the screen. Thank you!!!

CSS background-blend-mode multiply with opacity

I'm porting a UI-based game from Unity to Cordova. In Unity, I was tinting predominately white images with various colors to reuse assets. The rough CSS equivalent seems to be using the [mostly standard] background-blend-mode property set to multiply and have the image in the background with the desired tint color as the bg color.
.tinted {
background-image: url('theimg.png');
background-size: 100% 100%;
background-color: #0f0;
background-blend-mode: multiply;
}
The problem is that it doesn't preserve the opacity of the image, namely the transparent parts become the tint color. The spec says something about blending from the top down so I thought it might relate to blending with the bg color, but it doesn't work if I layer a solid color (as a gradient) on top of the image either.
.tinted2 {
background-image: url('theimg.png'), linear-gradient(to bottom, #0f0, #0f0);
background-size: 100% 100%;
background-blend-mode: multiply;
}
Reversing the order of the background images or changing the blend mode to normal, multiply or multiply, normal doesn't work either. Any suggestions on how to do this correctly using CSS?
EDIT: As the answer mentions, the alpha aspect can be achieved using the mask property. I used a combination of the two techniques to get what I needed:
.tintedMasked {
background-image: url('theimg.png');
background-size: 100% 100%;
mask-image: url('theimg.png');
mask-size: 100% 100%;
background-color: #0f0;
background-blend-mode: multiply;
}
If I understand correctly what you're trying to do, then background blending is not the way, but masking.
div {
height: 200px;
background-image:linear-gradient(SlateBlue, Tomato);
-webkit-mask: url(https://cdn.pixabay.com/photo/2016/12/28/19/37/denied-1936877_960_720.png) top left no-repeat / contain;
mask: url(https://cdn.pixabay.com/photo/2016/12/28/19/37/denied-1936877_960_720.png) top left no-repeat / contain;
}
}
<div></div>
<h1>No stairway??</h1>
That's assuming your mask images are alpha transparent PNGs. you could also use luminance mask by setting mask-mode: luminance;

What is the best way to crop an image with CSS?

I want to show a photo in my page, the DIV layer is 500 * 500px. I will replace the picture very often, the picture size is not sure, may be horizontal version may be vertical version, maybe 800*600px maybe 576*720px.
I don't want to get the photo deformation. How to set CSS or JS, make the photo show only the center 500 * 500 px, hide the around part.
Use a background image on a DIV with pre-defined dimensions, and set the image position to 50%, which essentially centers it. Whatever overflows the 500x500 will be cropped...
#yourImageDiv {
background: url(../img/image.jpg) no-repeat 50%;
height: 500px;
width: 500px;
}
One nice trick is to use a transparent PNG instead of a div and apply a background-image style to it. That way you get to use the image as you normally would (inline, etc.) but can crop at will.
#cropper {
width: 500px;
height: 500px;
background-image: url(myBackgroundImage.png);
background-repeat: no-repeat;
background-position: center center;
}
...
<img id="cropper" src="clear.png">

Resources