I am creating a card that contains an image and text. When the card is hovered, the image scales to 1.5. When you hover, the image will scale but then it will have this flicker where the corners will be sharp and then round out again.
.box {
width: 100%;
max-width: 19.375em;
background-color: green;
border-radius: 1em;
overflow: hidden;
}
.box:hover .box__image img {
transform: scale(1.5);
}
.box__image {
overflow: hidden;
}
.box__image img {
display: block;
height: 12.5em;
width: 100%;
object-fit: cover;
transform: scale(1);
transition: transform 500ms ease;
}
<div class="box">
<div class="box__image"><img src="https://via.placeholder.com/576x200"/></div>
<div class="box__desc">
<p>hello</p>
</div>
</div>
Works perfectly fine on Chrome and Firefox
Related
I have two hover effects. One is a transparent overlay that brings up text over the image. The other one is a grayscale filter that affects the same image. I want the image to fade into grayscale and bring up a red colored font over the image. It works when my mouse first hovers over the image, but if I move my mouse after the image has been affected, the grayscale disappears and the red font stays.
CSS
.overlay {
position: absolute;
max-width: 400px;
width: 100%;
height: 300px;
margin: 3px;
background-color:
transparent;
top: 0;
left: 0;
transform: scale(0);
transition: 0.5s ease;
color: red;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 40px;
color: red;
}
.image-gallery li img:hover {
filter: grayscale(100%);
transition: 0.5s ease;
}
.image-gallery li:hover .overlay {
transform: scale(1);
}
HTML
<div id="tribute-info" class="container">
<ul class="image-gallery">
<li>
<img src="https://lp-cms-production.imgix.net/news/2019/06/Antartica.jpg?auto=format&w=1920&q=75">
<div class="overlay"><span>Antarctica</span></div>
</li>
.
.
.
</ul>
</div>
I tried adding grayscale to the overlay but it turns everything gray, including the font, which I want to keep red.
Displaying image with object-fit and object-position works in browsers that support them, but in Safari 12, animating the object-position property to create a moving effect doesn't appear to do anything (same with using CSS transitions).
Is this a bug? or am I missing something?
I made a simple box and image to demo: https://codepen.io/Taruckus/pen/zyoGNX
<html>
<head>
</head>
<body>
<div class="wrap"><img src="https://via.placeholder.com/500x2000" alt=""></div>
</body>
</html>
<style>
.wrap {
width: 400px;
height: 400px;
position: relative;
}
.wrap img {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
object-position: 50% 0%;
animation: move 5s ease 1 normal forwards;
animation-delay: 0.2s;
}
#keyframes move {
0% {
object-position: 50% 30%;
}
100% {
object-position: 50% 60%;
}
}
</style>
Consider animating transform property. It would be more performant and cross-browser.
Run the snippet below:
.wrap {
width: 400px;
height: 400px;
overflow: hidden;
}
.wrap img {
width: 100%;
transform: translateY(-20%);
animation: move 5s forwards .2s;
}
#keyframes move {
100% {
transform: translateY(-45%);
}
}
<div class="wrap">
<img src="https://via.placeholder.com/500x2000" alt="">
</div>
Long story short, I want my (any) image to change the color on hover, but I can't make it work well on PNG images. The problem is with transparency. I don't want to apply my color on transparent space. My CSS looks like this:
background-blend-mode: color-burn;
background-color: #edeb52;
Here is the full jsFiddle example. All I want is to get rid of that color around the icon, which should be transparent.
6 months late to the party but you could use the mask-image CSS property. Its experimental but fairly well supported:
.maskedimage {
display: inline-block;
width: 200px;
height: 200px;
background-image: url("https://gameartpartners.com/wp-content/uploads/edd/2015/06/goblin_featured.png");
background-size: cover;
-webkit-mask-image: url("https://gameartpartners.com/wp-content/uploads/edd/2015/06/goblin_featured.png");
-webkit-mask-mode: alpha;
-webkit-mask-size: cover;
mask-image: url("https://gameartpartners.com/wp-content/uploads/edd/2015/06/goblin_featured.png");
mask-mode: alpha;
mask-size: cover;
}
.maskedimage.blue {
background-blend-mode: luminosity;
background-color: blue;
}
.maskedimage.red {
background-blend-mode: luminosity;
background-color: red;
}
.maskedimage:hover {
background-blend-mode: multiply;
background-color: red;
}
<div class="maskedimage original"></div>
<div class="maskedimage blue"></div>
<div class="maskedimage red"></div>
Alternatively you can get a similar effect using css filters:
.filteredimage {
display: inline-block;
width: 200px;
height: 200px;
background-image: url("https://gameartpartners.com/wp-content/uploads/edd/2015/06/goblin_featured.png");
background-size: cover;
}
.filteredimage.blue {
filter: sepia(1) hue-rotate(170deg) brightness(45%) saturate(1000%);
}
.filteredimage.red {
filter: sepia(1) hue-rotate(313deg) brightness(45%) saturate(1000%);
}
.filteredimage:hover {
filter: sepia(1) hue-rotate(313deg) brightness(25%) saturate(1000%);
}
<div class="filteredimage original"></div>
<div class="filteredimage blue"></div>
<div class="filteredimage red"></div>
Your mileage may vary.
This can be done with css, but unfortunately browser support is very bad (may be webkit only).
https://jsfiddle.net/devefrontend/fowzemd2/2/
.image .img {-webkit-mask-box-image:'YOURIMAGEURL';}
and this may be the same question as you:
Is there any way to colorize a white PNG image with CSS only?
Its is a Example
you can more learn it
https://www.w3schools.com/howto/howto_css_image_overlay.asp
.container {
position: relative;
width: 50%;
}
.image {
opacity: 1;
display: block;
width: 100%;
height: auto;
transition: .5s ease;
backface-visibility: hidden;
}
.middle {
transition: .5s ease;
opacity: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%)
}
.container:hover .image {
opacity: 0.3;
}
.container:hover .middle {
opacity: 1;
}
.text {
color: white;
font-size: 16px;
width:400px; height:350px;
}
<div class="container">
<img src="http://www.kaptest.co.uk/sites/kaptest.co.uk/files/pictures/icon-lightbulb-grey.png" alt="Avatar" class="image" style="width:100%">
<div class="middle" ">
<div class="text">example</div>
</div>
</div>
Try like this. See if it is helpful. I have used filter property here.
.image {
display: inline-block;
}
.image .img {
width: 375px;
height: 360px;
background-image: url('http://www.kaptest.co.uk/sites/kaptest.co.uk/files/pictures/icon-lightbulb-grey.png');
background-size: cover;
-webkit-filter: opacity(.5) drop-shadow(0 0 0 yellow);
filter: opacity(.5) drop-shadow(0 0 0 yellow);
}
<div class="image">
<div class="img"></div>
</div>
Does it have to be PNG? Preferably you could use an inline svg. This way you can not only apply a fill color of your choice via css but you also get all the benefits of vector based graphics: Crispy on any size and smaller file (be sure to optimize with svgo)
I'm trying to implement a full-screen infinite scrolling background effect, which must extend on the entire height and width of the viewport.
Here's the demo.
The solution I've tried was to take a wrapper element that has 100vh and 100vw of the viewport, then place 2 divs inside it, 100% of its height, that have the same background-image and background-size: cover property. The size of the image I've used is: 1,920px × 808px.
Then I've applied the following animation on the wrapper element:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-100%);
}
}
But the problem is that on some viewport sizes, the images are not repeating correctly (because of background-size: cover property):
.
Here's the full code I've tried:
<div class="animated-scene">
<div class="animated-scene__frame animated-scene__frame-1"></div>
<div class="animated-scene__frame animated-scene__frame-2"></div>
</div>
And the css:
.animated-scene {
width: 100vw;
height: 100vh;
position: fixed;
min-height: 400px;
animation: infiniteScrollBg 50s linear infinite;
}
.animated-scene__frame {
width: 100%;
height: 100%;
background-size: cover;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg');
}
Do you have any idea on how could I implement this effect?
Thanks for your help.
For scrolling background, I used background-position instead of using additional element and animate it using transform css properties.
Why you might asked?
Pattern will be seamlessly stitched by the browsers
cleaner HTML code. We just need one element to do this.
The only const doing this method is you need to know the dimension of image you are using.
Example :
/*
specify the scroll x (or y) with the width (or height) of the images
In this case, the image dimension is :
width: 1920px;
height: 808px;
*/
#keyframes bgScroll {
0% {
background-position : 0px 0px
}
100% {
background-position : 0px -808px
}
}
.scrollingBG {
display:block;
width:100vw;
height:100vh;
background-image:url("https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg.jpg");
animation: bgScroll 20s linear infinite;
}
<div class='scrollingBG'></div>
I have used an image element just to use the auto height of it.
Then I use a backgroiund on a pseudo that gives the ability to repeat itself as many times as needed
I have set 2 different containers with different aspect ratios to more easily check the result on different screens
.container {
border: solid 1px black;
overflow: hidden;
position: absolute;
}
#ctn1 {
width: 300px;
height: 150px;
}
#ctn2 {
width: 200px;
height: 350px;
left: 320px;
}
.inner {
width: 100%;
position: relative;
animation: scroll 5s infinite linear;
}
.inner:after {
content: "";
height: 500%;
width: 100%;
position: absolute;
background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
background-size: 100% 20%;
}
.img {
width: 100%;
}
#keyframes scroll {
from {transform: translateY(-100%);}
to {transform: translateY(-200%);}
}
<div class="container" id="ctn1">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
<div class="container" id="ctn2">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
A better solution with media query used to change the way the image is used.
Notice that background-size: cover is needed when both the aspect ratio of the image and the window is unknown. Since you know the aspect ratio of your image, you can control the display with a media query based on it.
Now, when it's needed, the image will adapt not to the width of the container, but to the height of it
#media screen and (max-aspect-ratio: 4/3) {
.inner {
height: 100%;
width: auto !important;
}
.img {
height: 100%;
width: auto !important;
}
}
.container {
border: solid 1px black;
display: inline-block;
overflow: hidden;
}
#ctn1 {
width: 300px;
height: 150px;
}
#ctn2 {
width: 200px;
height: 350px;
}
.inner {
width: 100%;
position: relative;
animation: scroll 5s infinite linear;
display: inline-block;
}
.inner:after {
content: "";
height: 500%;
width: 100%;
left: 0px;
position: absolute;
background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
background-size: 100% 20%;
}
.img {
width: 100%;
}
#keyframes scroll {
from {transform: translateY(-100%);}
to {transform: translateY(-200%);}
}
<div class="container" id="ctn1">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
<div class="container" id="ctn2">
<div class="inner">
<img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
</div>
</div>
The issue is with aspect ratio. You're setting the aspect ratio to the view window, and not the image size. So your image ends up getting cut off at the view window aspect.
I worked around in your codepen by changing .animated-scene__frame to this:
.animated-scene__frame {
width: 100%;
height:200vh; //easy way - increase height in animated div to prevent image cutoff. Ideally should be done through javascript using like a 3x multiple of the height of the image. Then just rely on background-repeat during the animation :)
background-size:contain;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
}
I would recommend to just extend the picture 3 times, with:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-66.66%);
}
}
Use some image editor and create a large image with the same pattern, take a look of this site that I made site, there you will find some infinite background pattern
You must use background-position property.
Here's fixed example http://codepen.io/azamat7g/pen/BRwRVV
Full code:
#keyframes infiniteScrollBg {
0% {
transform: translateY(0%);
}
100%{
transform: translateY(-100%);
}
}
.animated-scene {
width: 100vw;
height: 100vh;
position: fixed;
min-height: 400px;
animation: infiniteScrollBg 50s linear infinite;
}
.animated-scene__frame {
width: 100%;
height: 100%;
background-size: cover;
background-position: bottom left;
background-color: #4277a3;
background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
}
.bottom{
background-position: top left;
}
<div class="animated-scene">
<div class="animated-scene__frame animated-scene__frame-1"></div>
<div class="animated-scene__frame animated-scene__frame-2 bottom"></div>
</div>
Here is a simple horizontal flip animation - http://jsfiddle.net/vntajmgh/2/
and I see 2 issues:
Open the url in chrome. Hover over the red div. The flip is ok, but the background color for the back div(blue) is not applied.
Open the url in firefox. The flip is like stuck. I can see the blue colored back div sometimes.
I guess it's 'stuck' here because the height is 100vh, which when reduced works fine, but should it not work with the full height too?
.flip-container {
width: 150px;
height: 100vh;
perspective: 800px;
color: #fff;
position: relative;
}
.flipper {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform linear 0.6s;
}
.flipper div {
margin: 0;
display: block;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flipper .front {
background: red;
}
.flipper div:after {
content:"";
display: block;
position: absolute;
top: 0;
left: 0;
background-image: url("http://www.transparenttextures.com/patterns/3px-tile.png");
width: 100%;
height: 100%;
opacity: 0.5;
z-index: 1;
}
.flipper .back {
background: blue;
transform: rotateY(180deg);
}
.flipper:hover {
transform: rotateY(180deg);
}
<div class="flip-container">
<div class="flipper">
<div id="1front" class="front">1-front</div>
<div id="1back" class="back">1-back</div>
</div>
</div>
UPDATE:
Here is the working fiddle - http://jsfiddle.net/gf3g8sz1/1/
Add an overflow hidden to the parent div(flip-container). When we are using 100vh(view port height) with rotate transform property, its actually taking more height than the view port has. so hide it by using overflow hidden.
css
.flip-container {
overflow:hidden;
}
To get the same hover effect in both browser you have to modify the hover CSS.
DEMO
removing:
backface-visibility: hidden;
will make the back color visible
The problem in Chrome is caused by the pseudo element. I have changed the way to get the image blended with red without an pseduo element, and now it works OK.
The problem in FF is caused by the reduced-disappeared size of the element that receives the hover. I have changed the hover so that it is triggered by the container, and now it works also ok.
It is always a good idea to avoid using hover on transformed elements, they usually give some kind of problems
.flip-container {
width: 150px;
height: 100vh;
perspective: 800px;
color: #fff;
position: relative;
}
.flipper {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform linear 0.6s;
}
.flipper div {
margin: 0;
display: block;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flipper .front {
background: red;
background-image: linear-gradient(rgba(255,0,0,0.5),rgba(255,0,0,0.5)), url("http://www.transparenttextures.com/patterns/3px-tile.png");
}
.flipper .back {
background: blue;
transform: rotateY(180deg);
}
.flip-container:hover .flipper {
transform: rotateY(180deg);
}
<div class="flip-container">
<div class="flipper">
<div id="1front" class="front">1-front</div>
<div id="1back" class="back">1-back</div>
</div>
</div>