The perils of ‘display: none’


Cascading Style Sheets (CSS) have an attribute called ‘display’ which can be used to determine how a given element on a web page is shown ( One of the possible values is ‘none’ which means to hide the given element completely. But this is only applied at the web browser. It is an easy thing to do with any custom CSS that you may add to a theme in order to customise it. However, just because it is easy does not mean that it is the best solution. If you don’t understand the full implications then you might be surprised to learn that you’re actually just papering over a crack that is still there.


Firefox® is a registered trademark of the Mozilla Foundation.

Ubuntu® is a registered trademark of Canonical Ltd –

Moodle™ is a registered trademark of ‘Martin Dougiamas’ –

Other names / logos can be trademarks of their respective owners. Please review their website for details.

I am independent from the organisations listed above and am in no way writing for or endorsed by them.

Client Server

Before we can understand why a value of ‘none’ for the ‘display’ attribute is bad, we need to understand how our Moodle page is created by our web browser. On the following diagram we see we have a ‘Client’ which has our web browser and a ‘Server’ that is running Moodle:

Diagram of client server technology in processing a Moodle page request.

Between the two is an ‘Internet / Intranet’. Think of it as the ‘network connection’ between your computer (the client) and the computer running Moodle (the server). Even if you’re running both Moodle and the Web browser on the same computer, there is still a ‘network connection’ between the two. Because it is the same ‘connection’ from the point of view of Moodle and your Web browser, it does not matter how near or far apart they are. But clearly, the further away they are, then the longer the communication signal has to travel and compete with other ‘signals’.

When you connect to your Moodle instance (and any other web page), for every page that you visit your computer requests (using the URL) the web page from the server. The server receives the request from the network connection, does some processing to generate your page and then sends the completed page back to you over the network connection.

Have you ever been in a crowded room with lots of people talking and you’re attempting to have a conversation with someone a few meters / feet away? Well you have to work hard to make yourself heard by them. They have to work hard to hear you. Sometimes because you did not hear them you have to ask for them to repeat what they said (a collision). Now because all of our voices are slightly different then we can distinguish the signals a bit. However, network connections over a network, be it an Internet or Intranet etc. all have the same frequency on any given part of the infrastructure and thus effectively everyone sounds the same. Therefore if two computers attempt to communicate at the same time then the message they are ‘talking’ about gets corrupted, a collision happens.

Computer networks also have bandwidths, simply put, the amount of ‘data’ that can be handled at any one time. Hence you see adverts telling you that 4G is better than 3G for mobiles, this is because 4G can handle more data than 3G at any given moment in time.

The more computers that use a given network then the more likely that the amount of data increases. Just like the number of people in the room. This is also why WiFi is slower than cable / fibre connections as there are likely to be more computers using the same medium at the same frequency.

Therefore it is important that messages (the data) between computers are as small as possible.

An example

In the following customised header:

I have removed the user’s picture and name with the custom CSS:

#page-header .page-context-header {
    display: none;

But if we look at the markup on the page we still see that it is there along with the link to the image. If we then look at what has come over the network, then the user’s picture has still been received (‘downloaded’) by the client from the server:

Getting the user profile image over the network

This I believe is because the CSS is applied after the markup has been downloaded and any dependencies like images loaded, as CSS can change the formatting of an image. Thus it would be illogical to apply the CSS twice to first see if an image is not shown before applying any CSS that styles the other images.

All of this extra markup (HTML) and an image that we did not actually need because the user cannot actually see it!

Therefore our page could have:

  • Taken longer to receive and load because it is bigger than it needs to be.
  • Increased the probability of collisions with other pages causing not only it but other pages to need to be resent*.
  • Taken the server longer to generate it when it was processing the request.

*Ok, with this the complexities of computer networks mean that messages are broken down into individual smaller ‘packets’ whereby only a single packet may have to be re-transmitted. However the consequence is still effectively the same.

Now imagine the impact of this as the number of users increases? A small problem replicated lots of times becomes a bigger one.

The better solution

The solution is not to generate what you don’t need in the first place! Therefore in this instance, if we edit the Moodle (version 3.5) file ‘/theme/boost/templates/header.mustache’:

Boost header template

and remove what is highlighted, perform a ‘Purge all caches’ then the data will not be on the page and therefore not sent back to the client in the first place!

With this I have shown a solution that is not quite complete as there is some PHP code that needs changing to remove the bit that creates the data in the first place, but I hope you get the idea.

Why it can be useful

I’m not saying that ‘display: none’ is all bad though. I use it in my Collapsed Topics course format ( because the user interacts with the web page at the browser to change the visibility of the toggled sections dynamically. This works using JavaScript at the client end and is far more efficient to get the whole page once rather than keep requesting bits of it every time a section is opened.

There is a related concept called ‘Lazy load’ which could help here, but that’s another story.


In my view ‘display: none’ is bad. It is far better to not generate the data that will be hidden in the first place. However there are times when constraints mean that you have to use it. Therefore when either solving a theme problem yourself or asking a developer to do so, think if it is possible to solve it at the server end rather than using ‘none’ as a value of ‘display’.

Gareth Barnard

Gareth Barnard

Developer at HRDNZ
Gareth is a developer of numerous Moodle Themes including Essential (the most popular Moodle Theme ever), Shoelace, and other modules such as course formats.
Gareth Barnard

Latest posts by Gareth Barnard (see all)


Gareth Barnard

Gareth is a developer of numerous Moodle Themes including Essential (the most popular Moodle Theme ever), Shoelace, and other modules such as course formats.

Add a reply or comment...