How to hack unsupported mix-blend-mode CSS property? - css

I'm programming gallery of images, with specific hover effect. When user comes over the image, I use ::before pseudoelement to create "curtain" over the div with image using mix-blend-mode CSS property:
div.img::after {
content: "";
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
mix-blend-mode: soft-light;
background-color: red;
}
Resulting effect is like this:
But unluckily, IE (and some others according to caniuse) does not support this property and displays full red rectangle over the image and therefore it is not visible.
Is it possible to hack this mix-blend-mode behaviour to act like in Firefox or Chrome?
If not, is it possible to hide covering div or set it semi-transparent if and only-if mix-blend-mode is not supported?
Thank you

I know this is an old question, but you can also use the #supports feature query to detect if a certain property is or isn't available.
#supports not (mix-blend-mode: multiply) {
.image {
...
}
}
If you're interested, you can read more about the feature query at: https://developer.mozilla.org/en-US/docs/Web/CSS/#supports

If you don't want to use plain opacity as a fallback:
Approaches to cross-browser support
Javascript polyfill
This will be slow, and will not allow you to easily animate. However, it will let you create an alternate image for each of your matching images, and you can then fade the opacity or do other CSS transition tricks between the two.
http://codepen.io/brav0/pen/bJDxt (not my pen - uses multiply, not soft light)
Server side processing
Wouldn't be my first choice, but if you control the server-side code, you can prepare alternate images using server side imaging libraries (GD, etc)
Only enabling the effect for supporting browsers
Css hacks for detecting IE
#media screen { #media (min-width: 0px) {
div.img::after{ ... }
} }
Using JavaScript
if (window.getComputedStyle(document.body).mixBlendMode !== undefined)
$("div.img").addClass("curtain");
...and the CSS...
img.curtain::after { ... }

Related

Does the media query operator "not" actually work?

I actually want to trigger :hover effect only on PC that have mouse, but not on hybrid ones (mouse + touch).
My query is :
#media not (any-pointer: coarse) {
tag:hover { some effect }
}
What I want to say is : apply hover to PC that have not at least one coarse pointer (touch).
But it doesn't work, neither on chrome nor on firefox or edge.
What I am missing ?
According to MDN
if you use the not or only operators, you must explicitly specify a media type.
This snippet adds screen to the media query in your question.
On a laptop without touch screen it appears to work, that is hovering over the div does change it to cyan. If you change the 'coarse' to 'fine' then the hover does not work because the laptop's mouse is considered a fine pointer.
div {
width: 20vmin;
height: 20vmin;
background: pink;
}
#media not screen and (any-pointer: coarse) {
div:hover {
background: cyan;
}
}
<div></div>

html audio tag color inverted on chrome [duplicate]

I haven't found any resources on how to do that. Something as simple as changing the color of the player would be nice to have :)
Yes: you can hide the built-in browser UI (by removing the controls attribute from audio) and instead build your own interface and control the playback using Javascript (source):
<audio id="player" src="vincent.mp3"></audio>
<div>
<button onclick="document.getElementById('player').play()">Play</button>
<button onclick="document.getElementById('player').pause()">Pause</button>
<button onclick="document.getElementById('player').volume += 0.1">Vol +</button>
<button onclick="document.getElementById('player').volume -= 0.1">Vol -</button>
</div>
You can then style the elements however you wish using CSS.
MDN HTMLAudioElement API reference
<audio>
audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
audio::-webkit-media-controls-timeline-container
audio::-webkit-media-controls-current-time-display
audio::-webkit-media-controls-time-remaining-display
audio::-webkit-media-controls-timeline
audio::-webkit-media-controls-volume-slider-container
audio::-webkit-media-controls-volume-slider
audio::-webkit-media-controls-seek-back-button
audio::-webkit-media-controls-seek-forward-button
audio::-webkit-media-controls-fullscreen-button
audio::-webkit-media-controls-rewind-button
audio::-webkit-media-controls-return-to-realtime-button
audio::-webkit-media-controls-toggle-closed-captions-button
REFERENCE: https://chromium.googlesource.com/chromium/blink/+/72fef91ac1ef679207f51def8133b336a6f6588f/Source/core/css/mediaControls.css?autodive=0%2F%2F%2F
Yes! The HTML5 audio tag with the "controls" attribute uses the browser's default player. You can customize it to your liking by not using the browser controls, but rolling your own controls and talking to the audio API via javascript.
Luckily, other people have already done this. My favorite player right now is jPlayer, it is very stylable and works great. Check it out.
some color tunings
audio {
filter: sepia(20%) saturate(70%) grayscale(1) contrast(99%) invert(12%);
width: 200px;
height: 25px;
}
The appearance of the tag is browser-dependent, but you can hide it, build your own interface and control the playback using Javascript.
Ken had it right as well.
a css tag:
audio {
}
will get you some results. seems it doesnt want the player any height above or below 25px but the width can be shortened or lengthened to an extent.
this was good enough for me; see this example (warning, audio plays automatically): www.thenewyorkerdeliinc.com
Missing the most important one IMO the container for the controls ::-webkit-media-controls-enclosure:
&::-webkit-media-controls-enclosure {
border-radius: 5px;
background-color: green;
}
To change just the colour of the player, simply address the audio tag in your css file, for instance on one of my sites the player became invisible (white on white) so I added:
audio {
background-color: #95B9C7;
}
This changed the player to light blue.
Yes, it's possible, from #Fábio Zangirolami answer
audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
background-color: red;
}
If you are using Chrome, turned on "Show user agent shadow DOM" in Chrome Dev Tool settings
Now you'll able to see all the pseudos
audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
...
and now you can style them
audio::-webkit-media-controls-mute-button {
display: none;
}
I did some customizations on the Audio component. Here is what i did.
audio {
/*border-radius: 90px;*/
width: 250px;
height: 45px;
margin-top: 5px;
margin-bottom: 5px;
}
audio::-webkit-media-controls-mute-button {
display: none !important;
}
audio::-webkit-media-controls-volume-slider {
display: none !important;
}
audio::-webkit-media-controls-volume-control-container.closed {
display: none !important;
}
audio::-webkit-media-controls-volume-control-container{
display: none !important;
}
I found that these customizations only works for Edge and Chrome. Not Firefox..
You can use HTMLMediaElement Api to create your own audioplayer with html/css. It is likely the only option. Because the default player can't be styled.
If you want to style the browsers standard music player in the CSS:
audio {
enter code here;
}

Is #supports available in LESS / Edge specific CSS rules written in LESS

Edge doesn't support styling above this section (no support for clip-path current) so to fix the styling I am trying to write Edge specific CSS.
I'm using LESS and I get an error when I try to to compile because it thinks that #supports is a LESS function. LESS will however recognise that #media is the CSS method.
My question is, how do I make the following code work with LESS or is there a better way to write Edge only CSS
#supports (-ms-ime-align:auto) {
.section {
padding-top: 0px !important;
}
}
UPDATE:
The issue appears to be with Visual Studios LESS compiler not recognising #supports
You are hopefully long-done with this project, but you can force LESS to not pre-process with the tilde and single quotes:
#supports ~'(-ms-ime-align:auto)' {
.section {
padding-top: 0px !important;
}
}
This renders to css as intended using the current Visual Studio 2019 - Web Compiler
I think less, at least for the version I am working on, cannot render #support tag inside a hierarchy.
So I struggled to make something like this work:
#header {
// some CSS...
#supports (-webkit-mask-image: url()) or (mask-image: url()) {
i {
-webkit-mask-size: cover;
mask-size: cover;
}
}
}
And finally, I make it by moving the whole hierarchy inside #support tag like this. A bit of repetition, yet it will do.
#header {
// some CSS...
}
#supports (-webkit-mask-image: url()) or (mask-image: url()) {
#header {
i {
-webkit-mask-size: cover;
mask-size: cover;
}
}
}

Preload images using css

Is this an acceptable way to preload images, compared to some js code inside of html / head
body:after{
display:none;
content:
url(img1.jpg)
url(img2.jpg)
...
}
js way
$.preload = function() {
for (var i = 0; i < arguments.length; i++) {
$("<img />").attr("src", arguments[i]);
}
}
$.preload("img1.jpg","img2.jpg");
The concept behind it is to place the background images on a pseudo-element that is loaded when the page loads but is not shown. This causes the browser to load the images so that when they are called later by another element they are ready to go.
This can be used to preload the images and swap them on hover. The "preload" div has no height/width since the images are set to background, so it doesn't show on the page, and the images are ready when you want to swap them on hover. (you will obviously have to set height/width on the anchors. I'm just showing minimal CSS here to get the point across)
HTML:
<div id="preload"></div>
<div id="icons">
</div>
CSS:
#preload {background: url('pic1b.png'), url('pic2b.png'), url('pic3b.png');}
.button-1 {background: url('pic1a.png');}
.button-2 {background: url('pic2a.png');}
.button-3 {background: url('pic3a.png');}
.button-1:hover {background: url('pic1b.png');}
.button-2:hover {background: url('pic2b.png');}
.button-3:hover {background: url('pic3b.png');}
Obviously, there are many other ways and the post above shared a link that include many others.
http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
I suppose that method would work, as long as the image isn't dynamically generated. The only issue with preloading using just CSS seems to be that the images download WITH the page, not after it. You can trigger the JavaScript event after the pageload is over.
Further reading: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
On firefox, at least, the images don't get cached with display: none. Instead you can set:
body:after {
width: 0; height: 0; overflow: hidden; display: block;
content: url('img1')
url('img2')
...;
}

Limit :hover to the parent element

Here come my example (found some pretty photos on the internet for you): http://jsfiddle.net/xGPys/ (works on chrome only, if anyone finds why Firefox doesn't like it)
So the part that causes me trouble is there:
.imagepreview:hover a {
top: -61px;
height: 150px;
z-index: 1000;
}
What I want to achieve is: You should be able to pass you mouse on the whole column, and each image should open and close one after the other, right now, the opened photo covers the other ones, and so the :hover state is note removed from the <td>.
I could use a bit of Javascript but I'd prefer keeping it pure CSS.
Thanks !
Just set the pointer-events to none:
.imagepreview a {
/* ... other styles ... */
pointer-events: none;
}
.imagepreview:hover a {
top: -61px;
height: 150px;
z-index: 1000;
}
Here's your fiddle: http://jsfiddle.net/xGPys/1/
Warning: pointer-events is experimental. Use at your own discretion.

Resources