2

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;
}
Louay Madrid
  • 41
  • 1
  • 5
  • What is the page size you are dealing with? And are you loading the page into cache using a from another page to address the loading time. Each 100 millisecond of perceived unresponsive time costs visitors to leave. In this regard blur is expensive because it forces more CPU time from the browser which blocks interactivity and can make the transaction less than smooth ... opacity provides the least performance hit Reference https://csstriggers.com/ ... opacity only causes the final compositing operation in the most browser which takes advantage of the GPU. – Wayne Mar 23 '19 at 18:33
  • Thanks. I understand, but my client insists and I can't do anything about that unfortunately. The page size is 950kb. The current preloader hides the webpage completely until it is loaded, so I actually think blur would keep more visitors on the page than the current preloader. – Louay Madrid Mar 23 '19 at 19:02
  • 1
    I would let the client know that Amazon found every 100ms of latency cost them 1% in sales; It is well worth the cost to improve response times ... Do you have a clean above the fold area that in theory could be rendered while the below the fold area continues to load? – Wayne Mar 23 '19 at 20:12

3 Answers3

1

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

Aaron McGuire
  • 1,217
  • 10
  • 14
  • Thanks. I understand, but my client insists and I can't do anything about that unfortunately. If it doesn't load correctly I will try again to advise my client not to use a blur loader. Thank you for your solution, is there any chance I can give the body and id instead of a class (it's too much to explain but it would be a lot easier if I could use an id) what would I need to change in that javascript? – Louay Madrid Mar 23 '19 at 19:13
  • P.S. I'm using jQuery, what would the code snippet be for classes or ids in this case? Thank you in advance – Louay Madrid Mar 23 '19 at 19:26
  • 1
    Yes you can swap the above code out to use an id. If you need a jquery alternative you could use something like this `jQuery( document ).ready(function() { jQuery('body').removeAttr('id'); });` – Aaron McGuire Mar 23 '19 at 19:39
  • [You want `load`, not `DOMContentLoaded`.](https://stackoverflow.com/questions/2414750/difference-between-domcontentloaded-and-load-events). This also fixes the reason you give for this not being advised. Also note that, depending on how the JS is run, it may happen after both `DOMContentLoaded` and `load`, so you should check `document.readyState` too. – twhb Mar 24 '19 at 01:04
1

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>
Wayne
  • 4,760
  • 1
  • 24
  • 24
1

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)');});
Vahid Rafael
  • 29
  • 1
  • 3