Scroll-Tag for Google Tag Manager

Understand your viewers reading behaviour

25.07.2016  |  Markus Kehrer  |  Tag1, Tag2, Tag 3

What is it about

In this very first article of my blog i want to help you understand users reading behavior a little better. In fact we want to find out how far the users are reading through your pages. Are they reading your articles till the end, or are your users primarily scrolling down not more than half of the page? It can give you a very good insight of how attractive your content is in the eye of the user. What we need to get this running is beside your website an installed Google Tag Manager instance and the linked Google Analytics to analyze the data centrally. You also may need a little of JavaScript or programming knowledge. If not, don’t worry. I promise you to get this easily running even as a total beginner. So lets dive right in.

Scroll-Tag for Google Tag Manager

The Theory

The goal for this Tutorial is to create a tracking-setup that gives us insight how far the users are scrolling down the page. For that we will create a script tag, which we implement in Google Tag Manager, that stores the users scrolling height every time a user passes a new maximum scroll height (steps of ten should be enough) while scrolling down the page. After the user is leaving the page, the script is sending the information as an event to Google Analytics, where we can analyze the data further. In the last section we go a little deeper in how we can do that and how to understand that little piece of data.

The script itself works in a very uncomplicated way. All it does is as soon as the users starts scrolling to check the position of the users viewport in relation to the height of the page. It calculates a percentage out of that information and stores it in a variable. On the example Page below you can have a look at the mechanics.

The Scroll Tag

Now let´s get serious and do some coding. In the following i will show you the code and right after i will explain it to you. But first we have to create a so called "Custom HTML" Tag in Google Tag Manager, which will contain our JavaScript. Sure, we could insert that code right onto the page itself, but for non-IT workers it´s far more easy this way, because you don´t have to work on the page itself, which often requires IT help in companies. So we stay the easy way, as it works the same.

In Tag Manager we navigate to the container of our site and click on "Tags" and "New". No we can choose a name and the tag-type. Insert a name and click on "Custom HTML Tag" at the bottom. In the box copy the following lines of code. Don´t be afraid of the length. We will go through every line in the next paragraph. At the end of the section you can copy the code as once, but first lets irritate to the single lines.

Initialising the function

Javascript

1
2
var boolLoad = true;
var scrollHeight = 0;

So what happens in the first lines here? It´s quit easy. We create a Boolean variable (Boolean can only have the values 'true' or 'false') which controls if the whole function is running or not. Like we see later, the function stops, when the scroll-height reaches 100%. In this case, the variable turns to false and the function is not allowed to work anymore. Logically, because the user cant scroll further then the full page.

The next variable we create is called „scrollHeight“. It keeps the percentage of how far the user scrolled down as a number. In the beginning it has the value zero, which will change as soon as the user starts scrolling.

Find the browser height

Javascript

1
2
3
4
5
6
7
8
9
var browserHeight = 0;

if ( typeof (window.innerHeight ) == 'number') {;
browserHeight = window.innerHeight;
} else if (document.documentElement && document.documentElement.clientWidth) {;
browserHeight = document.documentElement.clientHeight;
} else if (document.body && document.body.clientHeight) {
browserHeight = document.body.clientHeight;
}

In the next section of the code, we want to find out how big the users viewport, or in other words the browser-window, is. Especially the height is important for us, so that we can calculate the scroll height later. But finding that out, is quit the most tricky part in the whole script. The problem is, that every browser calculates the height a little bit different and because of that, there can be huge differences in the values, or even worse, no value at all. Most of the browsers support the innerHeight parameter of the window-object, which represents the browser window itself. After creating the variable browserHeight that will contain the value later, we will check for the window object first. If the script can find a valid value in that object (which will likely happen in all never browser, except for Internet Explorer) it stores that very value in our variable.

If there is no valid value, the script carries on to the next 'if' loop and checks if there is a documentElement object that holds the parameter clientHight. You can find that parameter in the newer Internet Explorer versions. It can be frustrating to see, that IE is really the only not pairing shoe in the rendering of webpages and browsers. But because of the wide distribution of this browser, it is a must to get this running.

And it does not stop there. The older IE versions have another object that holds the browser height information. So we need another if loop, that checks for the body object and the same clientHight parameter. This object, which holds the HTML elements in your body tag, is a child of the document object. This object is in fact your whole page and all of their child elements.

With these three if loops we should be safe. Every browser i checked can find at least one valid browser height value we can use here. Leave me a comment if you find an unsupported browser which makes sense to support.

Find the Page height

Javascript

1
var height = (document.body.offsetHeight - 100);

What comes next? Yeah right, now we need the height of the whole page. Luckily this is by far more easy, and we don’t need a separate check for Internet-Explorer. We just check for the body object. This is the object where all your content is saved. And because any website is in fact a body object with many child’s, there is no difference in all the browsers.

So in the first line we create a variable that contains the height of the body object (offsetHeight) minus 100 pixel. This pixel are meant for the footer of your page. If you like to have the footer within your calculations, don´t subtract that number from the height value. For me it turns out, that it´s much more important if the users came to the end of the content, and not the whole page. So it makes totally sense to subtract the footers height. If now the user reaches the end of the content, before the footer, calculation will give me a 100% scroll height.

But please be always sure, to check the real height of your footer and type it in instead of the 100. In the example page the footer is exactly 100 pixels high. If you have a footer that changes the height depending on browser size, you should give your footer an id and type that one in, instead of the exact pixel number. This should then look like this:

Javascript

1
var height = (document.body.offsetHeight – document.getElementsById('footer');

And the HTML part:

HTML

1
2
3
<div id='footer'></div>
Content...
</div>

Send event after user is leaving the page

Javascript

1
2
3
4
window.onbeforeunload = function(){
ga('create', 'your_Tracking_Code', 'auto');
ga('send', {hitType: 'event', eventCategory: 'Scroll Height', eventAction: document.location, eventLabel: scrollHeight + "%"});
};

To make sure the event, which will later hold the scroll height information, is getting fired after the user left the page we need once again the window object. The parameter onbeforeunload starts a function, if the user is leaving the page. If this is happening we will then create a Google Analytics event, like you see in lines 2 and 3. We can choose an event description so that we can separate the events later. The Category is just the overall description for these event types. In the action field we type in the actual URL of the page, so that we can separate between different pages. And in the label field we type in the scroll height and add a percentage letter to the number. You can choose your own description names if you like. But for analyzing the data correctly, you should always send the URL and the scroll height within the event.

Calling the function

Javascript

1
2
window.onscroll = function() {
if (boolLoad) {

In the following sections I describe the function, that calculates the scroll height, pushes the value to the Datalayer and fires the scroll event. All of the following code snippets are part of this function. And because the function should start working while the user is scrolling, we can initialize the function with the window object. This object (representing the browser window as mentioned before) is having a parameter called onscroll. This indicates if the window is getting scrolled by the user at the moment. If it does, it creates the function and runs it right after.

Like I said before we want the function only to run when the maximum scroll height is not yet reached. If the user does reach the full 100% scroll height, then there is no more need to call the function. We can do that with a simple if loop like you can see in line 2. The Boolean we created in an earlier stage, indicates if the rest of the function will be executed or not.

Let's calulate

Maybe you already noticed: To calculate the scroll height, there is one more important value we need. I´m talking about the actual scrolling position. We do this within the scrolling function we created right before, because every time the user is scrolling this value is changing. So if the scrolling function is getting executed, the first thing it does is getting the scrolling position at that very moment. And because there is only a value scrollTop (which is the scrolling position measured at the top of the viewport) we need to add the height of the window to get the bottom scroll height. Let say we scrolled down 200 pixels at the top of the window. We add the browser height, for example 800 pixels. So the bottom scroll height must be 1000 pixels.

Javascript

1
var scrollBottom = document.body.scrollTop + browserHeight;

No we have everything together that we need, for calculating the scroll height as a percentage. This happens in the following line:

Javascript

1
var percent = Math.floor((10 / height) * scrollBottom);

First we take the height of the website (height) and divide it by ten, because we are doing steps by ten and the output should be a number between zero and ten. To that value we multiply the height of the bottom of the window, which we calculated just before. Now the output is a number with many digits after the point, something like this '2.795848'. We don´t need it that exactly, so we round that number with the Math.floor function. All this function does, is cutting all the digits after the point and just keep the first ones. So for example the '2.795848' would become a '2'.

Be sure not to use the Math.round function. This often used function would get you some false outputs here. Because what this function does, is rounding up the values, like you do it in school. Our example number '2.795848' would be rounded up to a 3. This would mean, that the user have scrolled down 30%, but in fact he is just something around a little more then 20%.

Storing the value

Now that we have the percentage value of our scroll height, we need to save that value in our variable scrollHeigt. We can do this very easily. But first we need to check out when to do this.

Javascript

1
2
3
4
5
6
7
switch (percent) {
case 1:
if ((percent * 10) > scrollHeight) {
scrollHeight = 10;
}
break;
}

Our percentage output is a number from the range of 0 to 10. Now, if the user scrolled down for example 10% of the page, the output should be the value 1. We then just check within a simple switch statement, if the value is 1. If this is the case we then check if the actual scroll height is more than the value saved before. For example, we start loading the page and the first value is 0 (must be a very long site though). Now the user is scrolling and the if loop recognizes that the new actual value is higher then the one before. So it stores the new value in the scrollHeight variable, in this case 1. For a better understanding (and a bit more easier data analysis) we store the value multiplied by ten, which represents the real percentage value (1 becomes 10%). Now that we have a new value assigned, we store it into the variable scrollHeight.

We irritate the above code snippet every time the user is scrolling. And of course we have 9 additional cases like that, to check for every single step (1 to 10). The next one (20%) looks like this.

Javascript

1
2
3
4
5
case 2
if ((percent * 10) > scrollHeight) {
scrollHeight = 20;
}
break;

Now there is just one thing missing and the script is finished. In the very last loop we are checking if the user scrolled down the full 100%. If it´s the case, the function can stop do it´s work. So we set the boolLoad Boolean to false. Now the whole function will stop working.

Javascript

1
2
3
4
5
case 10
if ((percent * 10) > scrollHeight) {
scrollHeight = 100;
boolLoad = false; }
break;

As you may recognized we don´t have to check if the scroll height value is higher than the one before. That´s so, because it can happen only one time to reach the full 100% scroll height.

The Custom HTML Tag we just created should now look like this:

GTM Scroll Tag

You can copy the whole code out of the following section:

Javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<script>
var boolLoad = true;
var scrollHeight = 0;
var browserHeight = 0;

if (typeof (window.innerHeight ) == 'number') {
browserHeight = window.innerHeight;
} else if (document.documentElement && document.documentElement.clientWidth) {
browserHeight = document.documentElement.clientHeight;
} else if (document.body && document.body.clientHeight) {
browserHeight = document.body.clientHeight;
}

var body = document.body;
var html = document.documentElement;
var Fensterhöhe = Math.min(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight, window.outerHeight);
var height = (document.body.offsetHeight - 100);

window.onbeforeunload = function () {
ga('create', 'UA-80990546-1', 'auto');
ga('send', {
hitType: 'event',
eventCategory: 'Scroll Height',
eventAction: document.location,
eventLabel: scrollHeight + "%"
});
};
window.onscroll = function () {
if (boolLoad) {
var scrollBottom = document.body.scrollTop + browserHeight;
var percentRare = (10 / height) * scrollBottom;
var percent = Math.floor((10 / height) * scrollBottom);

switch (percent) {
case 1:
if ((percent * 10) > scrollHeight) {
scrollHeight = 10;
}
break;

case 2:
if ((percent * 10) > scrollHeight) {
scrollHeight = 20;
}
break;

case 3:
if ((percent * 10) > scrollHeight) {
scrollHeight = 30;
}
break;

case 4:
if ((percent * 10) > scrollHeight) {
scrollHeight = 40;
}
break;

case 5:
if ((percent * 10) > scrollHeight) {
scrollHeight = 50;
}
break;

case 6:
if ((percent * 10) > scrollHeight) {
scrollHeight = 60;
}
break;

case 7:
if ((percent * 10) > scrollHeight) {
scrollHeight = 70;
}
break;

case 8:
if ((percent * 10) > scrollHeight) {
scrollHeight = 80;
}
break;

case 9:
if ((percent * 10) > scrollHeight) {
scrollHeight = 90;
}
break;

case 10:
if ((percent * 10) > scrollHeight) {
scrollHeight = 100;
boolLoad = false;
}
break;

}
}
}
</script>

The Trigger

Now one more thing is missing to complete the scroll tag. The Trigger. This little piece of information tells the scroll tag when to fire. You can do that by defining rules. Maybe you want the script only to work on a specific article page. So you could setup the rule “Page URL” - “equals” - “/article/article01”.

There are even some predefined triggers, like “All Pages”. You can tell that this trigger would fire your tag on any page where the tag manager container is installed. Another way to feed your trigger is by events. You can setup the triggers up in a way, that allows them to fire when a specific event is occurring, like the scrolling event, which we will see later.

If you need help on how to setup the triggers, take a deeper look in the Google documentation:

Now we finished the technical part of this whole scrolling setup. Further we just have to make some adjustments in Google Tag Manager and Google Analytics, which follows in the next sections.

Google Analytics – Analyzing the data

In the last chapters we were taking care, that the information about the scroll height is getting send to Google Analytics. After a while (and after some traffic over your page) there should be some events visible. Just have a look in the “Behavior” and “Top Events” report. There you should see all the events sorted after their category name. Click on one to get further to the action and to the label definition. After clicking on the label the value will be displayed, where we saved our scroll height data in.

If you have done the description of the events the same as in the demo, your are now able to tell how many users scrolled down which site and how far. The percentage of every event (representing a single user session) tells you the maximum scroll height and under “Total Events” how many times this event occurred. For further analyzing you could export that data to excel and calculate the percentage of every event type. This could look for example like this:

Analyzing the Data

Of course it is better to have more users that are reading the full page at higher scroll height percentages. A diagram like the one above shows you that very clearly. If you see more users in the lower percentage area, you should really do something about it. Maybe control the quality of your content or watch out for technical issues, that won´t allow a good reading experience. Like a slow speed for example. If the page is loading to slow, the user will jump off and does not read trough the whole page.

I hope this article gave you a better understanding in your users reading behavior, without being to complicated after all. So please leave a comment if this solution worked for you or not. I´m trying to keep this article updated.