How to customise Bootstrap navbar-toggler or mobile menu or burger menu icon

In my Bootstrap 4 project I want to have a mobile or burger menu symbol (the 3 horizontal bars) that is as customisable as possible and just in pure CSS / HTML (I know I need JS for it to function but I mean the appearance).

I am sure this was pretty easy in Bootstrap 3 but I am a bit frustrated with Bootstrap 4 now they are using an SVG for the collapse menu graphic or mobile menu icon. I tried using Font Awesome which is easier to customise for size and color but really seems a big overhead just to get a slightly customisable icon.

I decided to try my own solution which works perfectly using CSS -

.burger {			
			width: 25px;
			height: 3px;
			background-color: blue;
			margin: 3px 0;	

and HTML-

<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse">					
<div class="burger"></div>
<div class="burger"></div>
<div class="burger"></div>

BUT W3C validator and research tells me I should not have a div as a child of button, only inline elements.

I tried using span and display:inline-block and other ways but cannot get same result, either I get the 3 bars all on one line or no bars at all.

I really like my solution, it works great, I can even have different colour bars! SVG is just too complicated a solution. But although it seems to work great - apparently my idea is bad coding

Any ideas guys on getting an easily customisable button or am I resigned to learning SVG or including Font-Awsome?

Cheers guys

Just rhetorically, have you also tried give the spans a display:block?

1 Like

You don’t need 3 extra elements to make a hamburger from a button you can do it just with the button element itself.


1 Like

@Erik_J No, but I will, I was just worried that giving the spans a block attribute would flag the same error since child elements of buttons should be inline - but thanks, I’ll give it a try

@ PaulOB I will try this as well thanks mate

No, the html semantics are important for additional use and processing information on the web. The CSS styling doesn’t infer with the raw html content/information.

And, if the browser is rendering the pure HTML without additional styles, it will render elements with their default semantically styles in order to make the page accessible.

Further, illegal html would give unexpected rendering even if the browser intelligently tries to understand the author’s intention or mistyping.

@Erik_J - that works ! But to be honest I did not understand everything you said in your last comment.

I think you were saying the HTML and CSS are separate as far as HTML validation is concerned, so changing a div to a span is OK even if the span is defined as display:block in the CSS?

This went completely over my head, can you explain a little more for this duffer? :blush:

I think here you were saying even if my div solution works, it is illegal html so should be avoided as it could give unexpected results at some point

But adding display:block; to the .burger css for the spans works - so am I ok with tis solution? It validates ok and works ok!

@PaulOB I am also going to explore your solution, thank you, since although more complicated and mor coding for me it seems to gather many attributes together for the burger button that could give more flexibility for the future

So I may have 2 solutions thanks guys, Is there any advantage of either solution over the other ?

Firstly in most cases CSS doesn’t care what an element looks like. :slight_smile:

You can make an element look and behave exactly as your layout needs. Never choose an element based on what it looks like but rather on the semantics of the html required. You can always change how the element behaves with CSS (such as changing its display:value).

However, the rules of html must always be obeyed and elements are defined as block elements or inline elements (or the other variations) and you construct your html according to the rules of html. The css display value of an element infers no semantics on the html element. A span is always a span and a div is always a div. You can change the display:value of each but that doesn’t change them form being block elements or inline elements. What you are changing is their display value which is not the same thing.

All elements are actually rendered as display:inline by default. The UA (User Agent) applies its own set of rules to style these elements appropriately. This varies by browser but would roughly look like this.

That allows an html document to render quite nicely without you adding any styles at all. e.g.

That’s correct. Browsers are good at rendering broken code but they don’t have to be.

Yes that’s fine. use CSS to change how an element appears.

The benefit of my solution is that it is one element doing one job. Always try to avoid adding extra elements just for appearance sake. Sometimes its not possible to avoid but usually with a little bit of thinking and care you can achieve the result with less elements than you thought. This makes maintenance easier and the code cleaner. The :before and :after elements are ideal for visual styling and can be treated like two extra elements in the html. I use them extensively to avoid adding extra divs or spans for non important content or visuals etc.


Cool, as always thanks to all for the clarity, patience and technical expertise :grinning: