CSS Sidebar Menu

And just to let you know, you'll need the Grandmaster level membership, as it uses container and section BBCode.
Preface
Menu Code Location
Well at first I had the menu code in the Global World Navigation Sidebar Custom Content section of the world settings. (Shown to the right)
However, I wanted a unique feature for the sidebar:
So on any Character page, the character menu item will have a dark background and be colored gold. On any Location page, the location menu item will have a dark background and be colored gold.
Etc, etc.
I mean, look at it now! The Miscellaneous menu item is highlighted with gold because this page has the misc tag!
In order to do this tag based menu highlighting, I had to move the menu code to the Global Copyright Footer section. This is because where the actaul code gets placed, and because CSS is a cascading thing.
I needed the menu code to be within the .user-css.page div. With the original way I had it, the #world-navigation-sidebar is above this .user-css.page div, and I cannot check for CSS class selectors if it is not a parent or child. Putting the code within the Global Footer section makes the sidebar a child of the .user-css.page div, and I can use advanced CSS selectors to do what I want.
If you do not care, you can put the menu code in the Global World Navigation Custom Content section.
Just be sure the CSS selectors you use are the appropriate ones, depending on where you put the menu code.
Global World Navigation Sidebar Custom Content section
Global Copyright Footer section
Base-line CSS
Ok finally into some code stuff. I'm going to start with the base-line CSS. World Anvil has it where you have to click a button to expand their sidebar thing. I didn't want that so I changed it.CSS
.user-css-presentation .world-navigation-palette-trigger {
display: none;
}
Just set that element to not display. That's it, the button's gone.
Important!: This next CSS is a little different depending if you put the menu code in the Global World Navigation Sidebar Custom Content section or the Global Footer section.
Global Navigation Sidebar CSS
.user-css-presentation #world-navigation-sidebar {
display: block!important;
position: fixed;
left: 0;
top: 55px;
margin: 0;
padding: 12px 0 0 0;
width: 64px;
min-width: 0;
max-height: 100%;
overflow-x: hidden;
}
Be sure the CSS base selector is .user-css-presentation and the div ID selector is #world-navigation-sidebar! This is specific to putting the menu code in the Global World Navigation Sidebar Custom Content section.
Now it's not best practice to use the !important flag, but there was no other way to set the display mode to block. Anyway, now that we've got it always showing, we can style it. Here's where you can do what you want, but I'll go over the basics for the positioning and whatnot.
Global Footer CSS
.user-css .sidebar {
display: block;
position: fixed;
left: 0;
top: 55px;
margin: 0;
padding: 12px 0 0 0;
width: 64px;
height: 100%;
z-index: 1500;
overflow-x: hidden;
}
Be sure the CSS base selector is .user-css and the div CLASS selector .sidebar! This is specific to putting the menu code in the Global Footer section.
The main differences in the CSS between the Global Footer and the other way:
Now for the on hover state.
.user-css .sidebar:hover {
width: 250px;
transition: all 0.2s ease-in-out;
}
All I do it set the width for the :hover state, and that's it. I also add the transition property for the smoothness.
Compensating for the World Editor Bar
I want to make a note on how to compensate for the World Edit bar. I mentioned the World Anvil bar and to not mess with it, so I set the top variable to 55px. If you have sage, you can disable this banner and set the top to 0.However, for authors of a world, you will have this "World Editor" bar. You could disable this if you want, but I find it useful. So with some CSS magic, you can have your normal CSS for normies who don't see the bar, and specific CSS for when the bar is there.
CSS
.user-css-presentation:has(.world-editor-bar) .sidebar {
top: 53px;
}
The CSS :has() selector checks to see if an element has a child with whatever thing you put in. In this case, .sidebar is selected if .user-css-presentation currently has the child div .world-editor-bar. If it does, then it sets the top of the sidebar to 53px, which is the height of the World Editor bar.
(Since I have Sage and disabled the World Anvil bar, my sidebar's normal top is 0 and not 55px like I mentioned before. Set the variable here to compensate for the World Anvil bar and the World Editor bar.)
The Menu Code
I originally put the menu code in the Global World Navigation Sidebar Custom Content section in the World Settings (shown to the right). However, like I mentioned before, I moved it to the Global Copyright Footer section, which is just above the Global World Navigation Sidebar Custom Content section.
This menu used to use World Anvil's default sidebar menu thing. Either way, I disabled the World Codex / Table of Contents and any Maps from showing up on the sidebar at all. I essentially replace the World Codex with the menu items I'm about to get into, so I don't need it. I customize all my world elements, include category pages.
Ok, now for the code parts.
Base level menu items, with no submenus
[url:https://www.worldanvil.com/w/dragonguard][container:menu-item][section:fas fa-fw fa-lg fa-house] [/section] [p]Homepage[/p][/container][/url]
Unfortunetly you can't line break between the URL tags; it won't work so you've got to slap it on all one line. I want the container of the menu item to also be the link, so I wrap the menu item container in the URL. Otherwise the text will be the only thing that's the link, and there will be a little empty space if the text is shorter than the width of the menu. This always annoys me, so wrap the container in the URL tags.
You also can't use the tagging system here, so you have to use the actual link.
Remeber to update the links in your menu, if there are any changes to your URLs!
The section tags with the fas stuff in it is for the FontAwesome icon. In this case, this was my homepage button, so it uses a house.
You've got to add a space between the section tags for some reason, if you're just using it to display a FontAwesome icon. I don't know why, you just do.
I wrap the menu item's name "Homepage" in a p tag so I can select it with CSS later.
Now for the menu item CSS code. (Again, based off of the Global Footer way of doing things, since it's shorter and easier to read.)
CSS
.user-css .sidebar .menu-item,
.user-css .sidebar .submenu-item {
padding-left: 16px;
text-align: left;
align-content: center;
height: 44px;
}
.user-css .sidebar a:hover .menu-item,
.user-css .sidebar a:hover .submenu-item,
.user-css .sidebar .menu-dropout:hover .menu-item {
color: #HEXColor;
text-decoration: none;
background-color: #HEXColor;
}
Both menu items and submenu items actually get the same CSS.
The 2nd part is for on hover state, where the element gets a darker background and a specific color (a blue color in my case here). The last one in that list will keep the base menu item dark while your mouse is in the dropout submenu container.
Menu Item Text CSS
.user-css .sidebar .menu-item p {
display: inline-block;
height: 44px;
font-size: 0px;
align-content: center;
vertical-align: middle;
margin-bottom: 0;
padding-left: 10px;
transition: all 0.2s ease-in-out;
}
.user-css .sidebar:hover .menu-item p {
font-size: 20px;
transition: all 0.2s ease-in-out;
}
There's actually a decent amount of CSS just for the text that shows up. Most of it is positioning.
The second section is for the on hover state when you mouse over the sidebar. The font size is set from 0px to 20px, with a smooth transition. Now our text shows up when we mouse over the sidebar, and disappears when the sidebar collapses! I use this trick elsewhere too, as doing display: none to display: block does not do smooth transitions.
Menu items with submenu dropout
[container:menu-dropout] [url:https://www.worldanvil.com/w/dragonguard/a/locations][container:menu-item menu-locations][section:fas fa-fw fa-lg fa-location-dot] [/section] [p]Locations[/p][/container][/url]
[container:submenu] [url:https://www.worldanvil.com/w/dragonguard/a/geographical-locations][container:submenu-item][section:fas fa-fw fa-lg fa-mountains] [/section] [p]Geographic[/p][/container][/url]
[url:https://www.worldanvil.com/w/dragonguard/a/landmarks][container:submenu-item][section:fas fa-fw fa-lg fa-monument] [/section] [p]Landmarks[/p][/container][/url] [/container] [/container]
This still uses the base menu item code, but slightly different. First off, I wrap the whole thing in a container named menu-dropout. The first menu item is the base, so that's normal. Then below that, I make another container that wraps any submenu items, named submenu. Then any submenu items have a different CSS class name of submenu-item, just in case if I want to do something slightly different with them.
CSS
.user-css .sidebar .submenu {
visibility: hidden;
position: fixed;
width: 0;
left: 249px;
margin-top: -44px;
font-size: 0;
background: #HEXColor;
transition: all 0.2s ease-in-out;
}
.user-css .sidebar .menu-dropout:hover .submenu {
visibility: visible;
width: 250px;
font-size: inherit;
transition: all 0.2s ease-in-out;
}
The visibility property here will hide and show the dropout submenu. We don't do this with the text on the base menu because it messes with the positioning of stuff. This is just for the submenu container, not an element within it, like the menu text.
The second section is for the on hover state.
That's really about it for the menu items.
Here are the other parts, if you want spacers and the Table of Contents in the sidebar too.
Menu Spacers
There are two kinds of spacers I use in the sidebar. One is padded, and the other is full width. Let's start with the padded one first.Padded Spacer
[container:menu-item menu-spacer][section:blank][hr][/section][/container]
Yup, that's it. We still use the menu-item CSS class so it has similar sizing and whatnot, but it has an extra class too. The blank section probably isn't necessary, I put it there just in case I needed to do extra stuff. I wrap the HR tag in a container so I can specifically edit the HR that's only in the menu, and not any that are on the pages themselves.
CSS
.user-css .sidebar .menu-item.menu-spacer {
width: 100%;
padding: 0 12px;
transition: width 0.2s ease-in-out;
}
.user-css .sidebar .menu-item.menu-spacer:hover {
background: none;
}
This actually has a width of 100% (so it grows with the sidebar when it's expanded), but the padding on the sides make it inset. Then, in the second section, I remove the background color. Since the code has the menu-item CSS class for the same universal styling, it also does the hover effect from the base menu item. I don't want the background changing color when you hover over this, this is just a spacer and not an actual menu link.
Now the way I setup the menu code in the World Settings is with line breaks in between each menu item / url tags. Unfortunately World Anvil will insert its own thing here when you do that, so to get rid of it while keeping the code readable, I just hide the element. Otherwise the menu items will be like.. doubled spaced. You have to use the !important flag here, which is not the best practice but it was the only way to hide the element. I don't necessarily recommend this, I just had to do it because I wanted the code to be easier to read.
If you don't add line breaks and separate the menu items in the code, you won't need this.
.user-css .sidebar .line-spacer {
display: none!important;
}
Full Width Spacer
I also have a full width spacer for the TOC section. It's more of a top border really, but I just used the same pre-defined HR spacer I had before, with a slightly different CSS. It was easier.[container:menu-item menu-spacer-full][section:blank][hr][/section][/container]
Yeah the same code as the other spacer, but with the menu-spacer-full CSS class instead.
CSS
.user-css .sidebar .menu-item.menu-spacer-full {
padding: 22px 0 0 0;
height: 0;
position: relative;
z-index: 10;
}
The CSS for the full width spacer is different than the inset one.
Tag Based Menu Highlighting
One of the specific features I wanted to have was the menu items highlighting based on the current page's tags. I finally figured it out, so here's how I did it.You also need to setup a Tagging System for your article pages.
The base sidebar CSS is slightly different for this than if you put the menu code in the Global World Navigation Sidebar Custom Content section.
First the base sidebar CSS, just in-case you forgot, or skipped to this part.
Relavent CSS - Recap
.user-css .sidebar {
display: block;
position: fixed;
left: 0;
top: 55px;
margin: 0;
padding: 12px 0 0 0;
width: 64px;
height: 100%;
z-index: 1500;
overflow-x: hidden;
}
The main differences here vs the other way is:
Now for the actual Menu Highlighting based on the page's tags.
CSS
.user-css.page[class*=tag-character] .sidebar a .menu-characters,
.user-css.page[class*=tag-location] .sidebar a .menu-locations,
.user-css [class*=world-meta] .sidebar a .menu-world-meta {
background: #HEXColor;
color: #HEXColor;
}
In this case I only showed three menu items. If you have more, just add them to the end and edit accordingly.
Since I'm checking for tags, I use the CSS attribute slector. Here I'm checking if the .user-css.page div also has the class tag-character on it. If you add the tag "character" to any page, it will have this div class added to it. Now you can select what you need afterwards, and in this case I select the specific menu item for characters. Do this for each of your menu items that you want highlighted based on tags.
In the last element listed, there is no tag for the World Meta page, however, it does have a specifc div class only found on it. This is why there is no .page and why there is a space between .user-css and [class*=world-meta].
Full CSS Code
CSS
.user-css.page[class*=tag-character] .sidebar a .menu-characters,
.user-css.page[class*=tag-location] .sidebar a .menu-locations,
.user-css.page[class*=tag-fauna] .sidebar a .menu-fauna,
.user-css.page[class*=tag-flora] .sidebar a .menu-flora,
.user-css.page[class*=tag-item] .sidebar a .menu-objects,
.user-css.page[class*=tag-prose] .sidebar a .menu-proses,
.user-css.page[class*=tag-indices] .sidebar a .menu-glossary,
.user-css.page[class*=tag-misc] .sidebar a .menu-misc,
.user-css.page[class*=tag-wa-event] .sidebar a .menu-events,
.user-css [class*=world-meta] .sidebar a .menu-world-meta
{
background: #HEXColor;
color: #HEXColor;
}
But wait, there's more!
Remember the Menu Item on hover states above? Well that wasn't the full code. I also add the class attribute selector stuff to that as well, all with the :hover after each a. I do this so that the highlighted menu item, even when colored gold, will still turn blue when you hover over it.
Full CSS Code
.user-css .sidebar a:hover,
.user-css .sidebar a:hover .menu-item,
.user-css .sidebar a:hover .submenu-item,
.user-css .sidebar .menu-dropout:hover .menu-item,
.user-css.page[class*=tag-character] .sidebar a:hover .menu-characters,
.user-css.page[class*=tag-location] .sidebar a:hover .menu-locations,
.user-css.page[class*=tag-fauna] .sidebar a:hover .menu-fauna,
.user-css.page[class*=tag-flora] .sidebar a:hover .menu-flora,
.user-css.page[class*=tag-item] .sidebar a:hover .menu-objects,
.user-css.page[class*=tag-prose] .sidebar a:hover .menu-prose,
.user-css.page[class*=tag-indices] .sidebar a:hover .menu-glossary,
.user-css.page[class*=tag-misc] .sidebar a:hover .menu-misc,
.user-css.page[class*=tag-wa-event] .sidebar a:hover .menu-events
{
background: #HEXColor;
color: #HEXColor;
text-decoration: none;
}
Well that's how I did tag based menu hightlighting! All of that was the reason I needed to put the menu code in the global footer section, unfortunately. I hope you found it useful, and maybe even inspire you to add it to your site too! :)
Table of Contents in the Sidebar
So I've seen some other World Anvil sites and noticed a few have the table of contents in the sidebar. However, these other sites that have the TOC in the navigation bar, do not have a collapsable sidebar. A few had a hidden pullout menu on the other size, but none had everything in on place. So I figured out how to do it and added it to my site.A lot of the CSS is positioning, and I do a little stylized header box. But first the code; this goes under that full width spacer. Pretty much just at the bottom of your sidebar code wherever you put it, in the World Settings.
[container:sidebar-toc] [container:sidebar-toc-title-box] [container:sidebar-toc-title] [section:fas fa-fw fa-lg fa-bars-staggered] [/section][p]Table of Contents[/p] [/container] [/container] [container:sidebar-toc-separater] [/container] [container:sidebar-scroll-to] [url:#full-layout][section:fas fa-fw fa-arrow-up-to-line] [/section] Scroll to top[/url][br] [url:#comments][section:fas fa-fw fa-comments] [/section] Comments[/url] [hr] [/container] [articletoc] [/container]
The whole TOC section is wrapped in a container. Then the title is wrapped in it's own box (for CSS styling). The text for the TOC title box is after that, but there's also the FontAwesome icon. Using CSS, the icon will be hidden when the sidebar is expanded, but visible when it's collapsed.
After the title box stuff comes the actual TOC stuff. Well kind of. First there's a TOC separater, just for CSS purposes and is how I made the stylized angled slant to the title box. After that there is are Scroll to Top and Comments links, this will always be there even when there are no TOC contents. Then there's a horizontal line, and finally the articletoc tag. This articletoc tag (not to be confused with the world codex or just toc) will grab the headers from any article page and put them in the TOC.
CSS time. There are a lot of "empty" containers for CSS stuff.
CSS - Title Box
.user-css .sidebar .sidebar-toc-title-box {
padding: 15px 0;
text-align: center;
background: linear-gradient(85deg, #HEXColor 0%, #HEXColor 15%) ;
transition: all 0.2s ease-in-out;
}
Stylized title box cutoff
.user-css .sidebar .sidebar-toc-separater {
width: 0;
height: 0;
border-left: 0;
border-bottom: 0;
margin-top: 0;
transition: all 0.2s ease-in-out;
}
.user-css .sidebar:hover .sidebar-toc-separater {
width: 0;
height: 0;
margin-top: -10px;
border-left: 250px solid transparent;
border-bottom: 10px solid #HEXColor;
transition: all 0.2s ease-in-out;
}
A lot of this is just zeroing out stuff, just to be sure, and for the collapsed sidebar. The main part of this is on the sidebar on hover state.
Swapping Icon and Title Text
Bunch of CSS for hiding the icon when the sidebar is expanded, but showing it when the sidebar is collapsed, and then the opposite for the title text. Like most of the other stuff, a lot of this is just freaking positioning it. Anyway..CSS - Title Text
/ * Closed * /
.user-css .sidebar .sidebar-toc-title p {
display: inline-block;
margin: 0;
font-size: 0;
transition: all 0.2s ease-in-out;
}
/ * Open * /
.user-css .sidebar:hover .sidebar-toc-title p {
margin-left: 5px;
font-size: 23px;
transition: all 0.2s ease-in-out;
}
Because the icon and text are on the same line, we have to set their display to inline-block so they're.. inline.
For when the sidebar is expanded, this is where the title text will show.
The CSS for the icon is pretty much the same, just the opposite.
CSS - Icon
/ * Closed * /
.user-css .sidebar .sidebar-toc-title .fas {
transition: all 0.2s ease-in-out;
}
/ * Open * /
.user-css .sidebar:hover .sidebar-toc-title .fas {
font-size: 0;
transition: all 0.2s ease-in-out;
}
This is a little weird because I'm not actually setting the font size here. The first block is when the sidebar is closed and I do a smooth transition for the font size, which it defaults to inheriting what the FontAwesome CSS is (the icon CSS classes were fa-fw and fa-lg). This is why I don't specifically set it myself, because I do not know what actual size it is.
Anyway, while the sidebar is expanded, the icon gets hidden in the second section, with the font size of 0.
Ok wow all that just for the TOC Title Box. There's still the actual TOC stuff to get through. oof.
TOC Section
I'll repost the relevant code for this section. This is for everything under that TOC Title Box, so pretty much the actual TOC stuff.Relavent Code - Recap
[container:sidebar-scroll-to] [url:#full-layout][section:fas fa-fw fa-arrow-up-to-line] [/section] Scroll to top[/url][br] [url:#comments][section:fas fa-fw fa-comments] [/section] Comments[/url] [hr] [/container] [articletoc]
So here I add a permanent Scroll to Top and Comments link just above the articletoc itself. This is for convenience, and I've seen it on a few other sites as well. All it is are two plain links that link to an anchor at the top of the page (#full-layout), and the other one links to an anchor if the comments section exists (#comments). They both have a FontAwesome icon as well.
After that is a horizontal line, and then finally, the freaking article's TOC contents itself.
CSS time.
CSS
/ * Closed * /
.user-css .sidebar .sidebar-scroll-to {
margin: 0;
font-size: 0;
transition: all 0.2s ease-in-out;
}
/ * Open * /
.user-css .sidebar:hover .sidebar-scroll-to {
margin: 5px 15px;
font-size: 14px;
transition: all 0.2s ease-in-out;
}
The anchor links of course get hidden too, when the sidebar is collapsed. Again, for the 69th time, using the font size trick. Also adjusting the margins and setting them to 0 when it's hidden because it would otherwise mess with the positioning of stuff.
There's also some general styling for this part too, that I didn't include. All I do is add some left padding to the links, so they're offset a bit, and style the horizontal line.
Now for the moment you've been waiting for! The Krabby Patty Secret Formula is — wait, no, wrong thing.
Ah yes, the TOC thing and its CSS. Bet you can't guess how I did it. Go on guess.
CSS - part 1
.user-css .sidebar .articletoc {
border: none;
font-size: 0;
margin: 5px 15px;
padding: 0;
padding-bottom: 6em;
width: -webkit-fill-available;
transition: all 0.2s ease-in-out;
}
.user-css .sidebar:hover .articletoc {
font-size: 16px;
transition: all 0.2s ease-in-out;
}
That's right!
Default font size of 0, then actually set it on the sidebar on hover state!
I also remove the border, because I didn't want that garbage. Everything else is just positional stuff. I also change the link's color and add an underline (it's actually a bottom border) when you hover over it (shown below).
I do this because of the Accessibility button that shows up at the bottom. This will ensure there is enough space to scroll and see the very last item in the Table of Contents, no matter how long it is.
But wait, there's more!
If you have a page with many headings, this will make the TOC long, even if the font size is zero. This will screw up the positions of your menu items and their icons when the sidebar is collapsed, and a scrollbar will be introduced.
Setting the TOC's height to 0 won't be completly fix this issue.
CSS - part 2
.user-css .sidebar .articletoc .article-toc-link {
padding: 0;
margin: 0;
border: 0;
}
.user-css .sidebar:hover .articletoc .article-toc-link {
padding-bottom: 3px;
margin-bottom: 3px;
}
.user-css .sidebar .articletoc .article-toc-link:hover {
color: #HEXColor;
border-bottom: 1px solid #HEXColor;
}
If you have many headings, such as on an Index page, the padding and margins of the items will be enough to still mess up the sidebar. So set everything on the TOC link to zero, then on the on hover state of the sidebar, set the TOC link's bottom padding and margin to 3px. This is what it was initially.
The last block is just for the on hover state for the TOC item itself; setting the border to what it was before, instead of just it's color.
Conclusion
No conclusion, there's already enough here to read, we don't need more. That's it, that's my navigation sidebar and it's CSS.The End. Now go and sleep; you're done for the day, I know you are.

I love this, Thank you for this... I wish I could get it to work, and maybe I have been staring at it for too long and need to step away and take a break. But I love it all the same and really hope I can get it working. There something not adding up with the code put in the global footer on my end me thinks.