I want to blur the whole "body" section of my website until the page has been fully rendered.
I have a preloader set up, it consists of 2 parts ":before" which acts as a background and ":after" which acts as a foreground.
Can I achieve this with just html & css or will I need to modify the JavaScript?
*Here's a perfect "permanent" example of what I want to achieve.
But I only want it to be temporary (until the page loads).
body {
-webkit-filter: blur(20px);
filter: blur(20px);
}
My current website css:
body {
background-color: #fff;
}
.site-preloader:before {
background-color: transparent;
//I want to blur the body here somehow
}
.site-preloader:after {
background: url("/preloader-image.png") 0 0 no-repeat;
z-index: 9999;
}
Whilst it is technically possible to achieve by doing the following
Give your body a class .i.e. .loading apply a filter:blur(200px); and add a javascript snippet that removes the class on page load
document.addEventListener('DOMContentLoaded',function(){
document.body.classlist.remove('loading');
})
This isn't advised - mainly because your css,javascript and html will load at different times so you will likely get different results based on the time it takes to load in your assets.
unless of course you wrap the removal of the class in a settimeout function, but again the problem with this is you are adding unnecessary 'fake' page loading making the page seem even slower
Given the requirement. I would suggest progressive rendering of the above the fold content AKA critical with a CSS in the head section and with a link rel="stylesheet" in the body below the fold. This technique is supported by browsers, (displaying the above the fold content before all assets below the fold are redered), but will trigger html checker errors.
You can also defer the CSS of the below the fold to the bottom of the page. If you need some authority to back you on this turn to Google ...
https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery ...
Also note I'm strongly suggesting opacity since it uses the GPU freeing up the CPU to continue to load the rest of the page. If you blur the page will need to repeat a layout process over and over again and make the load time worse if it is animated, However Louay Madrid solution would not make it worse.
At least give the users a header with the company name and phone number and access to site navigation why these poor souls are waiting for the rest of the page so they don't think there connection died.
<head>
<style>
// above the fold css - desired in html
body {
background-color: #fff;
}
#main {
background: url( ... your image ... );
animation-name: beginPage;
animation-duration: 4s;
-webkit-animation: beginPage 5s; /* Safari 4+ */
-moz-animation: beginPage 5s; /* Fx 5+ */
-o-animation: beginPage 5s; /* Opera 12+ */
animation: beginPage 5s; /* IE 10+, Fx 29+ */
}
#-webkit-keyframes beginPage {
0% { opacity: 0; }
100% { opacity: 1; }
}
#-moz-keyframes beginPage {
0% { opacity: 0; }
100% { opacity: 1; }
}
#-o-keyframes NbeginPage {
0% { opacity: 0; }
100% { opacity: 1; }
}
#keyframes beginPage {
0% { opacity: 0; }
100% { opacity: 1; }
}
</style>
</head>
<body>
<div id="main">
Above the fold content
<link rel="stylesheet" href="below the fold.css">
Below the fold content
</div>
</body>
Your css:
body {
-webkit-filter: blur(20px);
filter: blur(20px);
}
Then add this js/jq code to your script body:
window.addEventListener('load', (event) => { $('body').css('webkit-filter', 'blur(0px)');});
Related
I'm currently trying to implement or test a new feature on my locally hosted page which plays video with subtitles on. The subtitle format being VTT.
I've been trying to find how to actually be able to edit the VTT itself as I am trying to give a fading out effect for the subtitle.
This probably won't be helpful but I just tried implementing it via the style.css part of my project but sadly it only affects the texts of the page and I am not sure how to make it work for the texts from the VTT file itself.
Down below is the part I've tried to work out on the style.css
.fade-in {
animation: fadeIn 2s;
}
.fade-out {
animation: fadeOut 3s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
There is a ::cue selector to modify the subtitle text on a video.
But not all css properties are allowed.
You can change the color or opacity but you can not set the animation property.
Anyway, what you could do is to use css variable to set the opacity and the css variable could change with an animation
:root {
--opacity-value: 1
}
::cue {
opacity: var(--opacity-value);
}
#keyframes flickerAnimation {
0% { --opacity-value: 1; }
50% { --opacity-value: 0; }
100% { --opacity-value: 1; }
}
video{
animation: flickerAnimation 1s infinite;
}
An working example could be found here.
By cobbling together bits and pieces of various other answers from SO and elsewhere I have something that almost does what I want, but not quite:
I have to reload the page to get a new image.
Each new image fades in, but the previous image cuts out instantly rather fading across
Clicking on the image skips to the next one the same way.
The url I'm using returns a different image each time the server receives a request. I can change the URL to something else and it will still work. Is there a way to fade smoothly between images served in this way without refreshing the page? The other solutions I've found for this involve specifying a list of images somewhere in the page and rotating through them, which doesn't seem to work when every image has the same url.
I am trying to do this using only html + css + js.
<html>
<head>
<script type = "text/JavaScript">
<!--
function AutoRefresh( t ) {
setTimeout("location.reload(true);", t);
}
//-->
</script>
<style>
* {
margin: 0;
padding: 0;
}
.fade-in{
-webkit-animation: fade-in 2s ease;
-moz-animation: fade-in ease-in-out 2s both;
-ms-animation: fade-in ease-in-out 2s both;
-o-animation: fade-in ease-in-out 2s both;
animation: fade-in 2s ease;
visibility: visible;
-webkit-backface-visibility: hidden;
max-width: 100%;
max-height: 100vh;
margin: auto;
}
.imgbox {
display: grid;
height: 100%;
}
#-webkit-keyframes fade-in{0%{opacity:0;} 100%{opacity:1;}}
#-moz-keyframes fade-in{0%{opacity:0} 100%{opacity:1}}
#-o-keyframes fade-in{0%{opacity:0} 100%{opacity:1}}
#keyframes fade-in{0%{opacity:0} 100%{opacity:1}}
</style>
</head>
<body onload = "JavaScript:AutoRefresh(10000);">
<div class="imgbox">
<a href="javascript:location.reload(true)">
<img class = "fade-in" src="http://192.168.1.151:6600" style="object-fit:contain;display:block;margin-left:auto;margin-right: auto;" />
</a>
</div>
</body>
</html>
It is quite possible to use just JS/CSS/HTML to fade in and out between images without needing to reload the page.
To fade in and out between two images you'll need to have them both loaded. But in this case we cannot have two img elements with the same URL as the browser would assume the images were the same and therefore not ask the server for another one.
We get round this by adding a random query string to the end of the URL each time to persuade the browser to get another img. I'm using picsum and using their way of doing this, the method may differ for your service, though normally adding a random query to a URL doesn't upset the server, and it's only the browser we need to convince to send another request.
We load a new img with opacity: 0 so there isn't a sudden jump, and then we gradually fade it in while fading the other one out using your animation.
I have put the inline img styling into the head to tidy things up as we now have two images. I've removed the system-dependent prefixes just to make things easier to read, but of course put them back if you need them.
UPDATE: there was an additional requirement to not send requests to the image server too often. A pause flag has been added to indicate we cannot respond to the user's click which is unset after 2 seconds.
const imgs = [document.getElementById('img1'),document.getElementById('img2')];
let back=0; //0 or 1 depending on which img is faded out
let pause = false; //a flag to say it's too soon to get another image
let randomiser = 1;//we add this to the end of the img src to persuade the browser it really does need to get another image from the image server
function imgLoaded() {
imgs[back].style.animationDirection = 'normal';// will now fade in
back = (back + 1)%2;//make the other img the back
imgs[back].style.animationDirection = 'reverse'; // will now fade out
imgs[0].style.animationName = 'fade-in';
imgs[1].style.animationName = 'fade-in';
}
function next() {
if (pause) { return; }
imgs[0].style.animationName ='nothing';
imgs[1].style.animationName = 'nothing';
imgs[back].style.opacity = 0;// these should already be there, but just in case animation still on the go
imgs[(back+1)%2].style.opacity = 1;
randomiser++;
imgs[back].src = 'https://picsum.photos/1024/768.jpg?random='+ randomiser;
pause = true;
setTimeout(function () { pause = false; },2000);//dont ask for another image until 2 seconds is up
}
* {
margin: 0;
padding: 0;
}
body {
width:100vw;
height: 100vh;
}
.imgbox {
display: grid;
height: 100%;
}
#keyframes fade-in{0%{opacity:0} 100%{opacity:1}}
#keyframes nothing {}
.imgbox img {
object-fit:contain;
display:block;
animation-fill-mode: forwards;
animation-duration: 2s;
animation-iteration-count: 1;
position: absolute;
opacity:0;
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
<div class="imgbox" onclick="next();">
<img id="img1" onload="imgLoaded();" src="https://picsum.photos/1024/768.jpg?random=0"/>
<img id="img2" onload="imgLoaded();" src="https://picsum.photos/1024/768.jpg?random=0"/>
</div>
Ok, I have a situation where I have basically built a little notification dropdown box that happens when the user does something, at the end it transitions to a opacity: 0; state.
However, because the user may click something else that will trigger this notification box again I am trying to come up with a way to reset it back to normal without affecting any in-progress transitions and attempting to keep the animation done by CSS rather than JavaScript.
CodePen:http://codepen.io/gutterboy/pen/WoEydg
HTML:
Open Notify Window
<div id="top_notify" class="top-notify">
<div class="container-fluid">
<div class="row">
<div class="content col-xs-12">
<div class="alert" role="alert"></div>
</div>
</div>
</div>
</div>
SCSS:
body {
text-align: center;
padding-top: 150px;
}
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
transform: translateY(0%);
transition: 0.8s 0s, opacity 1s 3.8s;
opacity: 0;
}
}
}
JS:
$('a').on('click', function(e){
e.preventDefault();
myFunc();
});
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
var alert_el = $('#top_notify').find('.alert');
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
I know I can reset it back to normal by doing this in JS:
$('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary
...however doing this removes the classes before the transition is finished fading out the opacity and it just vanishes straight away.
I know I can do a delay in JS to counteract the CSS delay but doing it that way just doesn't seem a very good way to do it since you have the timings in 2 different places.
Is there any way I can accomplish this whilst keeping the animation done by CSS or will I have to move to using jQuery's animate so I can run the reset procedure once the animation is complete?
Ok, I came up with a simple solution after coming up with a convoluted one ha.
Simple solution I should have come up with in the first place was removing any additional added classes before the ajax call; I got too focused on doing it within the ajax block and of course that didn't work, but until I started playing around with the other solution I never tried it.
Any way, the simple solution is simply moving this code:
var alert_el = $('#top_notify').find('.alert');
...above the ajax call, rather than being inside of it.
Then adding this directly under it:
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
With the full function code being:
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
var alert_el = $('#top_notify').find('.alert');
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
CodePen: http://codepen.io/gutterboy/pen/xRXbXy
The other solution I came up with, whilst not really needed now, I thought I would post it anyway in-case it comes in handy for me (or someone) else in the future.
It doesn't remove the visible class after the animation is finished (as there is no way that I know of to alert JS when it's done) but the visible class - which I would change the name of if you use this method - doesn't add any new styles, it just runs the animation.
Here is how I did it:
The JavaScript remains the same as the solution above, it's all in the CSS.
TLDR;
Basically uses multiple CSS animations to control different states during the effect runtime; CodePen at bottom.
The changes being in the .visible class and the addition of some #keyframes.
.visible class:
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
As you can see we have gotten rid of any additional styling here - this means when the animation is done, it essentially resets back to normal, which is what we want.
Now, let's break down this code:
We are running 3 different animations here and it's important to note they don't run one after the other - meaning they don't wait until one is finished until it starts the next one, hence why we needed to include delay settings.
So first up we start with the slideDown animation:
slideDown 0.8s 0s
If you are new to animations in CSS then basically what this does is sets a delay of 0s before it starts running and the animation runs for 0.8s, and this is the animation:
#keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
So, pretty simple, just slides it down with transform from -100% to 0% and this animation takes 0.8s as we set in our call to this animation.
Now, I wanted this to stay visible for 3 seconds before it started to fade away, but we have a problem; once the animation ends then it goes back to it's standard styling, which in our case means it vanishes as it goes back to transform: translateY(-100%) since we have no extra styles in the .visible class, and we can't put any extra styles in there as then we won't be able to reset it back to it's original state (style wise).
But what do we do? The fadeAway animation doesn't start for another 3 seconds and at the moment it doesn't have anything to fade away (well it does, but you can't see it as it's hidden).
The solution to that was adding another animation - which technically doesn't really animate anything, it just keeps it visible until the fadeAway animation starts.
That's where we get to:
keepThere 3s 0.8s
Now, remembering the settings of our fadeAway animation are: fadeAway 1s 3.8s this means that we have 3 seconds before this animation is going to start and hence before we can control any of the styling with it.
So that's where these parameter values comes in - we set the delay to 0.8s so the keepThere animation doesn't start until the slideDown one has finished; then we set the duration for 3s to counter for the wait time until the fadeAway animation starts, and this is the keepThere animation:
#keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
Since it has the same start and end styling we combine it into one selector of 0%, 100% and as you can see, this does just what it says it does, keeps the element visible for the set duration of 3s until we can control the styling with the fadeAway animation.
I guess technically you could combine this functionality into the fadeAway animation if you wanted to do the math at what % equals 3 seconds and hence know when to start fading the element away.
Lastly we have the fadeAway animation:
fadeAway 1s 3.8s
Now as we have discussed above, we already know why we have set the delay to 3.8s, the 0.8s offset to allow the slideDown animation to run and an additional 3s delay as that's how long we want the element to be visible for until it starts fading away and then of course the fade takes 1s to complete.
The animation for this is:
#keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Now, since the keepThere animation has completed, we have to make sure to keep the element visible so the fade has something visible to actually fade away, that's why we make sure to include the style transform: translateY(0%); as a value from start to finish; after that it's quite obvious what it's doing I think.
Put it all together and you get:
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
}
}
#keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
#keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
#keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
CodePen: http://codepen.io/gutterboy/pen/QGqwBg
Then of course to be able to run it again the class has to be re-added and hence that was the purpose of removing the .visible class at the start of each run (before the ajax call) and then when it gets re-added during the ajax call it runs again.
Thanks to #Nathaniel Flick for sharing the link that led me down this path to begin with :)
Well, hopefully that comes in handy for someone seeing as I am no longer going to use that option ha!
I have an element
<form class="fade-in-form">...</form>
with an animation
.fade-in-login-form{
opacity: 0;
-webkit-animation: fadein 2s; !important;
-webkit-animation-delay: 3s; !important;
}
#-webkit-keyframes fadein {
from {
opacity:0;
}
to {
opacity:1; !important;
}
}
and I want the element to be invisible at first, but then fading in.
The problem is that the form is invisible at first (opacity: 0;), then fades in, but after the animation flashes to be invisible again! Why doesn't the animation overwrite the initial value of opacity: 0; with opacity: 1;? And how can I achieve what I want?
If the solution requires Javascript: I prefer AngularJS over jQuery.
An animation by default only applies as long as it is running. When it ends running, it no longer applies
If you want to change this behaviour, you need to use the animation-fill-mode property
In your case, the value is forwards
animation-fill-mode: forwards;
(With prefixes if needed)
First, syntax-wise, I think you should not have a semi-colon between your values and !important (not a good one to use, by the way) :
-webkit-animation: fadein 2s !important;
Second, I guess the styles are not applied because your elements are not loaded ; if you set display to block on the form and set it back to block after page content is loaded with javascript (see code below), does it work better ?
document.addEventListener("DOMContentLoaded", function(event)
{
document.getElementById("form").style.display = "block";
});
codepen example
Just leave off the opacity: 0; in your first selector:
.fade-in-form {
-webkit-animation: fadein 2s 3s; /* Chrome, Opera 15+, Safari 5+ */
animation: fadein 2s 3s; /* Chrome, Firefox 16+, IE 10+, Opera */
}
#-webkit-keyframes fadein {
0% { opacity: 0.0; }
100% { opacity: 1.0; }
}
#keyframes fadein {
0% { opacity: 0.0; }
100% { opacity: 1.0; }
}
As #sodawillow mentioned try never ever to use !important but if you really have to use it like this: property-name: property-value !important;
I am making a popup message that when it is set to style.display = "block"; (by pressing a button), it will fade to invisible. I have a button on the popup that hides the popup by setting the style.display = "none"; how can I make it fade out?
here is the css
#note {
position: absolute;
z-index: 101;
top: 0;
left: 0;
right: 0;
background: #fde073;
text-align: center;
line-height: 2.5;
overflow: hidden;
-webkit-box-shadow: 0 0 5px black;
-moz-box-shadow: 0 0 5px black;
box-shadow: 0 0 5px black;
}
#-webkit-keyframes slideDown {
0%, 100% { -webkit-transform: translateY(-50px); }
10%, 90% { -webkit-transform: translateY(0px); }
}
#-moz-keyframes slideDown {
0%, 100% { -moz-transform: translateY(-50px); }
10%, 90% { -moz-transform: translateY(0px); }
}
.cssanimations.csstransforms #note {
-webkit-transform: translateY(-50px);
-webkit-animation: slideDown 2.5s 1.0s 1 ease forwards;
-moz-transform: translateY(-50px);
-moz-animation: slideDown 2.5s 1.0s 1 ease forwards;
}
.cssanimations.csstransforms #close {
display: none;
}
here is the javascript
<script>
close = document.getElementById("close");
close.addEventListener('click', function() {
note = document.getElementById("note");
note.style.display = 'none';
}, false);
</script>
and here is the html
<div id="note" style="display: none;">
Form has been sent. If you would like to fill out another suggestion, feel free but remember that there is an Anti-spam system running. <a id="close">[close]</a>
</div>
Use jQuery, cause it is much simpler, download is from here Click Here.
Include jquery.js & write your code in <script> tags.
To show popup use,
$("#btn_id").click(function(e){
$('#note').fadeIn();
});
To hide popup use,
$("#close").click(function(e){
$('#note').fadeOut();
});
CSS display property doesn't have a 'hidden' value (you probably made a mistype). You should set it to 'none'. Then you should specify transition for display property for #note in css, e.g.
#note {
display: block;
-webkit-transition: display 2s; /* For Safari 3.1 to 6.0 and don't forget other browsers */
transition: display 2s;
}
then, in JS all have to do is just set display property to 'none':
document.getElementById("close").onclick(function () {
document.getElementById('note').style.display = 'none';
});
If you use CSS transitions, you should check browser compatibility list. As possible workaround, you can try CSS visibility property ('visible' to 'hidden').
But this is wrong path, because display and hidden will not give you a smooth vanishing. Try opacity property and then hide the popup by setting display to none, when transition finished.
You can use jQuery or pure JS, but it is much slower than CSS transitions. I would strictly recommmend using CSS. On the other hand, CSS transitions have worse browser compatibility, so you should use it if it fits your browser compatibility requirements.