One small enhancement in Notion that can have a huge visual impact is a nice-looking progress bar. Progress bars can help you quickly assess the status of a project or task at a glance.
Progress can be calculated in a number of different ways – one might calculate the percentage of tasks completed against the total tasks to be completed, or measure where the current date falls between a start and an end date. Regardless of the method, these formulas for displaying a progress bar assume that you have a property in your database called “Progress” where you do the actual progress calculation and output either a decimal value or a percentage. In our examples, our progress decimal value is 0.64 (64% complete).
Follow along, or skip to below where you can find example progress bars and the formulas to copy.
How it works
To display a progress bar we use the substring()
function in Notion. What is substring? Substring extracts a substring from a string using three arguments:
- The string
- The starting index (number)
- The ending index (number)
Example:
substring("Hello world", 1, 5) == "ello"
Here’s an explanation of how the first three examples work. We pre-load a string with the “filled” symbols that will make up the completed portion of our progress bar. Then we take the decimal value from our “progress” property and multiply it by 10 to get a whole number and use that as the ending index for our filled symbol string:
substring("●●●●●●●●●●", 0, round(prop("Progress") * 10))
In our example our progress is at 60%, so this displays six filled symbols:
●●●●●●
Then we pre-load a string with the “empty” symbols that will make up the incomplete portion of our progress bar. We subtract the decimal value for our “progress” property from 1 to get the incomplete difference and multiply by 10 to get a whole number. We use this number as the ending index for our empty symbol string:
substring("○○○○○○○○○○", 0, round((1 - prop("Progress")) * 10))
In our example there is 40% remaining incomplete, so this displays four empty symbols:
○○○○
Then we connect the two together with a “+” connector and add a text display of the progress percentage at the end. The full formula:
substring("●●●●●●●●●●", 0, round(prop("Progress") * 10)) + substring("○○○○○○○○○○", 0, round((1 - prop("Progress")) * 10)) + " " + format(round(prop("Progress") * 100)) + "%"
Which outputs the progress bar:
●●●●●●○○○○ 64%
Here are some different styles of filled symbol progress bars and the corresponding formulas.

substring("●●●●●●●●●●", 0, round(prop("Progress") * 10)) + substring("○○○○○○○○○○", 0, round((1 - prop("Progress")) * 10)) + " " + format(round(prop("Progress") * 100)) + "%"

substring("■■■■■■■■■■", 0, round(prop("Progress") * 10)) + substring("□□□□□□□□□□", 0, round((1 - prop("Progress")) * 10)) + " " + format(round(prop("Progress") * 100)) + "%"

substring("⬥⬥⬥⬥⬥⬥⬥⬥⬥⬥", 0, round(prop("Progress") * 10)) + substring("⬦⬦⬦⬦⬦⬦⬦⬦⬦⬦", 0, round((1 - prop("Progress")) * 10)) + " " + format(round(prop("Progress") * 100)) + "%"
For the rest of the examples, the method is similar but slightly modified. Instead of using filled symbols, we are using dashes or underscores, and by using “20” as our multiplier instead of “10” we are able to use a bit more real estate, which has a nice visual aesthetic. Again, we use slice to calculate the complete and incomplete portions of our progress bar, but insert a symbol in-between, marking the current position of progress within our project or task.
Here are some different style progress bars and the corresponding formulas.

substring("____________________", 0, 20 * prop("Progress")) + "⍜" + substring("____________________", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "□" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "●" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "○" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "◉" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "◎" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + "◐" + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("____________________", 0, 20 * prop("Progress")) + "◢" + substring("____________________", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("––––––––––––––––––––", 0, 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%" + " " + substring("––––––––––––––––––––", 0, 20 - 20 * prop("Progress"))
And some progress bars with a bit of fun flair:

substring("--------------------", 0, 20 * prop("Progress")) + "✖" + substring("--------------------", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("--------------------", 0, 20 * prop("Progress")) + "✂︎" + substring("--------------------", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"

substring("____________________", 0, 20 * prop("Progress")) + "🐌" + substring("____________________", 0, 20 - 20 * prop("Progress")) + " " + format(round(100 * prop("Progress"))) + "%"
DUPLICATE NOTION TEMPLATE