So I'm working on a project that requires me to make an animated flag purely with HTML5 and CSS3—looking something like this, and with this kind of movement.
I know there exist some solutions with HTML canvas, but my client specifically requested this be done with CSS3 (and as little javascript as possible). For the waving effect, the only solution I found was to create several div elements and have each with an animation delay on the translateY to create the flag effect all together (JSFiddle here) and do the exact same thing for the text.
I can also make the text overlap the flag by making the text have an absolute position, but my problem is I'm not sure how I can coordinate the wave movement of the text with the flag's so it can be exactly the same. Or, alternatively, if there's another way to do this animation (not sure yet how I'm going to work around the triangles at the edges)? I know an image can be used to animate over it; what would be more efficient in this case?
We can do the animation in CSS3 using Keyframes.
You have to have the transparent image which will have the set of frames(all frames in single image) and animate using keyframes.
Here is one Example like that - https://codepen.io/Guilh/pen/yldGp
HTML
<div class="monster"></div>
CSS
body {
background: #24aecd;
}
.monster {
width: 190px;
height: 240px;
margin: 2% auto;
background: url('https://treehouse-code-samples.s3.amazonaws.com/CSS-DD/codepen/blog/monster.png') left center;
animation: play .8s steps(10) infinite;
}
#keyframes play {
100% { background-position: -1900px; }
}
I hope this will help you
Related
I am trying to add a pulsing ring that rapidly and repeatedly shrinks around a target element to draw a user's attention to that location. Not subtle, but it'll do the job. I have several places on my site I want to place it, so I want to be able to attach it to any element without significantly altering the element that I attach it to.
My current attempt uses a div with absolute positioning with a wide border and border radius of 50%:
HTML Declaration:
<a href="mysite/readme">
<div class="attention-ring"></div>
Click Me
<a>
CSS
.attention-ring {
border-radius: 50%;
border: 10px solid red;
position: absolute;
z-index: 100;
}
The animation is achieved with jQuery. It gives it a width of 100% and quickly shrinks it using setInterval(), resetting when width reaches 0:
function animateRing() {
if ($('.attention-ring') != null) {
var ringDiameter = 100;
setInterval(function () {
if (ringDiameter > 0) {
$('.attention-ring').css({ "padding":`${ringDiameter}%`, "margin":`${-1 * ringDiameter}%`})
ringDiameter -= 1
} else {
ringDiameter = 100;
}
}, 10)
}
}
What I have does work. But there are a few problems:
The ring element at maximum diameter extends past the edge of the page. This is particularly bad for elements already close to the edge of the page. It causes intermittent blank space to appear past the edge of the page and makes the scroll-bars go haywire. Ideally I want the page to ignore that this element is going out of bound.
I currently need to place the div with the ring class directly inside elements. This means for elements, the user will have difficulty clicking on other elements on pages where this feature is active. Not ideal because I eventually want to add a way to turn this off using a different button.
How would I solve the above problems?
This is a perfect use-case for pseudo-elements and CSS animations. In fact, you don't need any Javascript at all.
Problem #1 happens because the script resizes the actual .attention-ring div itself. With position: absolute this doesn't affect the size of its container, but it will still trigger overflow if it gets beyond the container's bounds. Hence the dancing scrollbars. (You'd have to set any container to position:relative; overflow:hidden to prevent that... which could get hairy if you want to apply this in a lot of locations. Fortunately that's not necessary!)
Instead of resizing the div as an element, you can use transform: scale(<some number>) to scale the rendered element visually. (See CSS transform property.) This takes place after the "boxes" for each element are laid out in the browser, so it doesn't cause anything to overflow.
You can then animate the transform property in CSS with a named #keyframes rule, which gets attached to the animated element with the animation property.
Problem #2 can be solved with two steps. First, set pointer-events: none on the ring element. This makes clicks go "through" it, as if it's not part of the a tag it belongs to. Then you can avoid adding a separate div by turning the ring into a ::before pseudoelement. This way you can turn it on or off simply by adding or removing a class from the element you want to highlight.
Here's a demo of the whole thing in action:
.attention-ring::before {
display: block;
content: "";
pointer-events: none;
border-radius: 50%;
border: 10px solid red;
position: absolute;
animation: attention 1s cubic-bezier(0,0,.2,1) infinite;
}
#keyframes attention {
50%,to {
transform: scale(5); /* multiple of the initial size */
opacity: 0;
}
}
<p><a href="mysite/readme" class="attention-ring">
Click Me
</a></p>
<p><a href="#">
Also Click Me
</a></p>
<p
Note: the display:block; content:"" on the before:: makes the ring display, otherwise the browser treats it as an empty node and won't render it.
Credit: this is partly inspired by the ping animation in Tailwind CSS, but my solution above is a bit more flexible.
Hello guys,
You can check out my preloader here: http://apesdesk.apespark.com/ (Press ESC as soon as you open the page in order to stop loading the rest of the website and see the loader as much time as you need)
When you do so, you'll see the problem with the quality of the background linear gradient quality. The GIFs quality is way better than the CSS's gradient quality. I have no idea why this is caused and how I should fix it. Normally CSS shouldn't have those issues as it's actually computing the gradient, it's not an image, etc. to have lossless quality.
Regards,
Denis Saidov
ApesPark
P.S. I've temporary commented everything else and made the loader to loop infinitely.
I tried to tag your name but it won't work. As mentioned in my comment -
I'm getting the same issue. For a workaround solution I would suggest using a pseudo element to cover either the top or bottom of the page instead.
E.g.
#preloader {
background-color: #fff;
}
#preloader::before {
position: absolute;
top: 0;
left: 0:
height: 50%;
right: 0;
background-color: #477FE7;
z-index: 0;
}
Cheers,
Conor
As an example, lets say I have a wash that I want to go across a container when a user does something and reverse when they do it again, something like:
#keyframes wash{
0%{clip-path: circle(0% at bottom left);}
100%{clip-path: circle(150% at bottom left);}
}
#keyframes wash-reverse{
0%{clip-path: circle(150% at bottom left);}
1000%{clip-path: circle(0% at bottom left);}
}
.container.opening{
animation : wash;
}
.container.closing{
animation : wash-reverse;
}
If I want the container to start unaffected by the wash then I want to apply the "wash" to the container (using the opening css class) and then remove it (with the closing css class) is it possible to define a single animation and have a separate CSS rule that says "play the animation backwards"?
I've tried the animation-direction : reverse but I can't get it to work.
A JS fiddle of a working (Chrome only) example where you click on the 'toggle' button to add and remove the wash, completed by defining both animations distinctly, is here:
http://jsfiddle.net/errumm/c7ojz7r6/1/
Try to change the solution by using translation instead of key-frames.
Config a translation on 'clip-path'. Change the logic of toggle button to add/remove 'in' class.
.adl-modal{
-webkit-clip-path: circle(0 at bottom left);
}
.adl-modal.in{
-webkit-clip-path: circle(150% at bottom left);
}
I am using the following css to make all items in the main DIV of my page to be transparented:
#wrapper
{
filter:alpha(opacity=90);
-moz-opacity: 0.9;
opacity: 0.9;
}
This works and everything gets transparented. But for example I DO NOT want the texts, images and buttons to be transparented. How can I do this?
You can do this like so:
#wrapper{
color:rgba(255,255,255,0.9);
}
You will have to use rgba() to achieve this. Take a look at this website:
http://www.css3.info/introduction-opacity-rgba/
I did also come over this problematic and solving it with rgba() is really the best way to get around this. Using transparent images as background, in my opinion is not as flexible as it should be and I'm really against using images when you can achieve the effects you want in other simpler ways.
You need to use a transparent background (in png) for your wrapper and do not use opacity
The child-elements inherit the opacity and you can not directly change it back. But there is a workaround http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/
http://www.apple.com/why-mac/
has a cool little thing where you hover your cursor over the image and it scrolls upward to show hidden text.
I'm wanting to create a mockup with that same effect, where I have the mockup as one flat background image and then place the scrolling images on top of it.
Any ideas as to how I can do this?
You can do this with jQuery scrollable: http://flowplayer.org/tools/scrollable/
Looking into the source for the page (with Firefox/Firebug, by the way, which is awesome for this kind of reverse-engineering) I see that the javascript framework Scriptaculous is in use. Specifically, the BlindUp animation appears to be the one in use on that page.
Apple uses Scritaculous for that effect.
CSS Transitions?
(From the link above):
Transitions are specified using the following properties:
transition-property – What property should animate, e.g., opacity.
transition-duration – How long the transition should last.
transition-timing-function – The timing function for the transition
(e.g., linear vs. ease-in vs. a custom cubic bezier function).
transition – A shorthand for all three properties.
Here is a simple example:
div {
opacity: 1;
-webkit-transition: opacity 1s linear;
}
div:hover {
opacity: 0;
}