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
I am trying to animate image by filter: invert(1) going from right side to the left side.
filter: invert(1);
transform-origin: right;
Seems to not be working. Is there any easy way to do it?
That's because you aren't changing the image with a transform, you're changing it with a filter. The transform-origin property will not affect a filter in any way, only transforms. If I were you I would try something like my example below. Hover the image to see the effect.
.image-container {
position: relative;
overflow: hidden;
}
.image-container:before {
content: '';
background: white;
position: absolute;
height: 100%;
width: 100%;
mix-blend-mode: difference;
transform: translateX(100%);
transition: 1s ease;
}
.image-container:hover:before {
transform: translateX(0);
}
<div class="image-container">
<img src="https://picsum.photos/id/10/400/300" alt="" />
</div>
I have a moving box (a div changed into a tiny box) on a html page. The box is moving in a curve path that I am describing in animation frames of css.
Now I have to draw a line following this box move, just to mimic a pencil move, so it looks like the line has been drawn by the moving box. As the box moves, a line should start appearing behind it, e.g. just like we draw a line by pen or pencil.
Not sure, if it is possible only in css but if you have any suggestion, please feel free to advice me. Thank you.
here is code
test.html
<html>
<head>
<link rel="stylesheet" href="box.css">
</head>
<body style="background-color: white;">
<div id="box">
<div id="line"></div>
</div>
</body>
<script src = "logo.js"></script>
</html>
css file: box.css
body{
width:100%;
height:100vh;
background-color: black;
}
#box {
margin-top:300px;
margin-left:30px;
top:0;
left:0;
width:30px;
height:40px;
background-color: red;
animation:move-line;
animation-duration: 5s;
animation-iteration-count: infinite;
}
#keyframes move-line {
0%{
transform:translateX(0px)translateY(0px) ;
}
50%{
transform:translateX(280px)translateY(0px) ;
}
60%{
transform:translateX(300px)translateY(-100px) ;
}
70%{
transform:translateX(300px)translateY(100px) ;
}
80%{
transform:translateX(320px)translateY(0px) ;
}
90%{
transform:translateX(330)translateY(0px) ;
}
100%{
transform:translateX(400px) ;
}
}
javascript file: logo.js
currently it is empty but if you have a solution feel free to use it with javascript too however css is preferred.
Here is a snippet to demonstrate the idea.
An after pseudo element attached to the red box has a solid white background.
As the box moves, the pseudo element 'goes before it' revealing what is already underneath.
In this demo just the first part of the line has been drawn. You'll need to add the other lines with additional linear-gradients, 3 being at angles and positioned suitably and the last one horizontal again.
Alternatively you could put an image there instead of using linear gradients but I note your question says no SVG so I assume that maybe it isn't allowed a jpg either.
<style>
body {
width: 100%;
height: 100vh;
background-color: black;
}
.container {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
padding: 0;
background-image: linear-gradient(transparent 0 calc(300px + 20px), black calc(300px + 20px) calc(301px + 20px), transparent calc(301px + 20px) 100%);
background-size: 280px 100vh;
background-repeat: no-repeat;
background-position: 0 0;
}
#box {
margin-left: 30px;
top: 300px;
left: 0;
width: 30px;
height: 40px;
background-color: red;
animation: move-line;
animation-duration: 5s;
animation-iteration-count: infinite;
position: relative;
}
#box::after {
content: '';
position: absolute;
top: -300px;
left: 100%;
height: 100vh;
width: 100vw;
background-color: white;
display: inline-block;
}
#keyframes move-line {
0% {
transform: translateX(0px)translateY(0px);
}
50% {
transform: translateX(280px)translateY(0px);
}
60% {
transform: translateX(300px)translateY(-100px);
}
70% {
transform: translateX(300px)translateY(100px);
}
80% {
transform: translateX(320px)translateY(0px);
}
90% {
transform: translateX(330)translateY(0px);
}
100% {
transform: translateX(400px);
}
}
</style>
<html>
<head>
<link rel="stylesheet" href="box.css">
</head>
<body style="background-color: white;">
<div class="container">
<div id="box">
</div>
</div>
</body>
<script src="logo.js"></script>
</html>
This is the example: https://jsfiddle.net/0w4bcy93/
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: red;
transform: rotateX(40deg) rotateY(0deg) rotateZ(0deg);
}
.circle--1 {
filter: blur(10px) opacity(1);
}
<div class="circle circle--1"></div>
<div class="circle circle--2"></div>
Both has the same styling except .circle--1 has filter blur. Is this a browser issue?
edit: You can also try increasing the rotateX and the cropped area will be bigger
edit2: I logged a bug in Chromium https://bugs.chromium.org/p/chromium/issues/detail?id=1108298
In case of it's a chrome bug itself. There's a cheat way to work around. By using a parent
filter layer to blur.
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: red;
transform: rotateX(75deg) rotateY(0deg) rotateZ(0deg);
}
.blur-filter {
filter: blur(10px);
width: 100px;
height: 100px;
}
.circle--1 {
filter: opacity(1);
}
<div class="blur-filter">
<div class="circle circle--1"></div>
</div>
<div class="circle circle--2"></div>
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>