Scrollytelling through a look at food prices around the world

May 2, 2022

You have gathered the needed data to support your research, check. You have made some hypotheses about what you hope to conclude, check. You have spent time cleaning the data and organizing it in a manner that permits further exploration, check. You have sliced and diced the data with your favorite data exploration software packages or techniques and created some data visualizations that you feel confident about, quadruple check! You are now armed with insights that you hope to showcase to the world, what’s next? In this article, I would like to share some tips for creating a single page scrollystory site with simple HTML, CSS and some easy to implement JavaScript fade-in effects. 

Let’s first define scrollytelling. I am certain that you have read a countless number of online articles from major news outlets that combine images, visual effects and text to turn an otherwise long-form article into an interactive and multimedia experience. This narrative visualization technique is called scrollytelling. It was first popularized by a 2013 Pulitzer Prize winning New York Times article, Snow Fall: The Avalanche at Tunnel Creek [1]. The technique has since been frequently applied in journalism, science, education, business and beyond to create engaging stories that delight readers. 

To illustrate my experience leveraging the scrollytelling technique, I traced back the steps that were taken recently to create a data story called: The cost of putting food on the table across the world and over the years [2]. I’m sharing the workflow with you all below. 

1-Have a topic

Earlier this year, my team and I engaged in a data story project that investigated how food prices differ by country and over time. The project was inspired by our past travels that prices of food items could vary drastically based on geography. 

2-Find a dataset that supports your topic

By using the food price index as well as the commodity price indices published by the Food and Agriculture Organization of the United Nations (FAO), we were able to draw some interesting insights on price differences and fluctuations. 

3-Review what’s in the dataset and break down your analysis into chunks

Given there are 5 commodities including cereal, meat, diary, vegetable oils and sugar, the data story was structured to reveal details on each as well as the respective sub-categories. Above all, there was also the macro level insights at the continent and country level that deserved some attention. 

4-Make some hypotheses and test them

Some examples of hypotheses that I made related to food price index included:

  • Developing areas in the world have a higher consumer food price index compared to developed areas

  • The consumer food price index is expected to be the highest in countries that are prone to natural disasters or political turmoil; lowest in countries that are free from the related events

To test the above hypotheses, initial data visualizations such as the below were created. 

Figure 1: Food price index by continent (Line chart)

The line chart above confirmed that South America and Africa are regions with food prices much higher than the rest of the world.

Figure 2: Food price index by country (Packed bubble chart)

The packed bubble chart above showed that Venezuela’s food price is significantly higher than the rest of the countries. South Sudan, Zimbabwe, Sudan and Lebanon are among the countries with the highest food prices after Venezuela.

5-Refine each visualization by creating a task list to design for usability

After a key insight is extracted from an initial data visualization, I developed a set of tasks with good coverage of what I would like users to be able to perform when interacting with the prototypes. Some example tasks for the country-level food price index data visualization included:

  • Identify the overall world food price index trend from 2009 to 2021

  • Identify the country that has the highest and the lowest food price index for a given year

  • Find the button that plays back animation of food price index changes over the years

  • Find the dropdown box that takes you to the map view of a particular year

I then created a few prototypes with different designs and conducted a usability study with test subjects. Feedback from subjects was used to iteratively improve the design. This is a crucial part of the design process that is often not allocated enough time for what it’s worth. You would be amazed how much you could learn from subjects who look at your design with a fresh pair of eyes, and would be able to provide valuable suggestions that you would have never thought of that could change your course. Treat your data viz like a product (well, it is a data product) and let the ultimate consumers be the critics. 

The below figure shows the design iterations that were undergone before arriving at the final design (on the far right). To sum up the changes made, the packed bubble chart was not effective in illustrating differences for countries that had similar food price indices. Putting the countries onto a map however allowed users to easily associate each shaded area with a country based on the geospatial location. In the first attempt of the map view, circle marks as well as colors were used to depict the magnitude of each country’s food price index. A major finding from the usability study was that users relied mainly on the color scheme to gauge the values. Due to the number of countries, the circle marks often overlap each other and were too distracting. Most also all had very similar sizes, so it defeated their purpose. With this input, the circle marks were dropped, and a choropleth was used instead. This design was further improved to increase the color contrast of the food price index values by adjusting the midpoint value of the color spectrum. Beyond that, the locations of menus, subtitles and legends were also tweaked. Usability study and design iterations like the above were performed for all data visualizations used in the data story.

Figure 3: Design iteration for the food price index by country data visualization

While building out the desired features of data visualizations and ultimately the site that houses them could take effort, this is where a prototyping tool like Figma would be useful to convey to your team the desired form, fit, function and process flow for each component, and each feature on the site that you are to build.

6-Weave insights into a coherent storyline

After completing all of the above, we arrived at 8 data visualizations that looked at food prices from different aspects (E.g. continent-level, country-level, commodity-level, sub-commodity level, affordability, seasonality, etc.) At this point, even though the data visualizations were somewhat finalized, a coherent storyline was still not fully formed yet. Not without some further effort. Simply throwing all finalized data visualizations and meshing them together onto a webpage would not work. Creating a storyline that flows is perhaps a task that requires the most thought in the development of a data story. 

One tip that I have is to write down a key message or takeaway for each data visualization in one or two sentences. After that, lay these messages out onto a page so that you could see them all. Review and order them in a logical sequence to create a pseudo storyline. These key messages are then used to “glue” the data visualizations that you have developed together. To make the data story more fruitful and behave more like a journalistic article, accompany each data visualization with a paragraph or two that details the insights drawn and what the readers should pay attention to when interacting with it. 

7-Putting it all together

At this point, you should have all building blocks required to implement scrollytelling. I have created a barebone site template to help get you started in your future data storytelling projects. While the sample data visualizations here are created using Tableau, you can use any method such as D3, Altair, etc. and replace the JavaScript in the respective section accordingly. 

Here is the structure of the barebone template.


I added a viewport definition so that the visible area of the webpage is responsive to the device that the user users to view it and would scale accordingly. This is also where the stylesheet called style.css is linked to. You could update this to any style sheet if you have a different one. You will need to adjust it to work with this HTML template if you choose to do so.

Figure 4: Head element of the HTML file


The body consists of the following components:

  1. The cover page, we call it the “showcase” here

  2. The data visualizations that you wish to highlight

  3. Key message sections that help glue the data visualizations together

  4. A closing section that provides an opportunity for you to elaborate the origin of the data story, gives credits to the creators and for you to provide references to the sources of data

This template has placeholders for 2 data visualizations, 2 key message sections and a closing section. If you have more than 2 data visualizations, all you need to do is copy and paste these sections and rename the section ids. 

Figure 5: An example of a key message section

Fade-in effect

A key feature of this template is a fade-in effect that is implemented to enable gradual transition from one section to the next. This also adds a bit of aesthetic appeal and the scrollytelling style that one wishes to achieve. For a simplistic option that maximizes the possibility to expand, I would say this does the job nicely. And of course, sky is the limit with any frontend experience design. The fade-in script is located near the bottom of the HTML page, see the screenshot that follows for details.

Figure 6: Fade-in script (on the HTML page) 

Figure 7: Fade-in definitions (on the stylesheet)

The fade-in script works by “observing” at what point the user is currently viewing the page. As the user begins to enter the section that has fade-in applied, it adjusts the opacity of the section from 0 to 1 within a set duration. The default duration used in the template is 3 seconds. To turn on fade-in effect for a section, two things need to happen: 

  1. Append an additional line below to the fade-in script. “#new-section-name” refers to the respective section id.

Figure 8: Append new fade-in code for each section to turn on fade-in effect

  1. Edit the respective section’s class name as “new-section-name fade-in” in the section tag. Example for section a is as follows:

Figure 9: Update class name for each section to turn on fade-in effect

The template described above could be downloaded from my Github repo [4]. I hope this gives your development a healthy kickstart. 

One last mention before I end the article is that there are slightly more advanced libraries that could help you achieve even more if you wish to explore further. Scrollama [3] is a light-weight JavaScript library that is frequently cited and used by developers to achieve more advanced scroll-driven interactives. Check it out if you would like to explore further. Happy scrollytelling!


[1] Branch, J. (2012, December 20). Snow Fall: The Avalanche at Tunnel Creek. [online] The New York Times. Available at:

[2] Ayrapetyan, A., Leung, F., Rains, A., Schlissel, A. (2022, April 13, 2022). The cost of putting food on the table across the world and over the years. [online] Berkeley School of Information. Available at:

[3] Goldenberg, R. (n.d.) Sccrollama [online] Available at:

[4] Leung, F. Scrollytelling (2022, May 2). Scrollytelling. Available at: