NovelEmber event is going on right now!

CSS Sidebar Menu

Thought I'd write out a page on how exactly I made the Navmenu Sidebar thing used on this site, for anyone else wanting to know. It's not the best CSS; I'm garbage, but it works.. I guess.   And just to let you know, you'll need the Grandmaster level membership, as it uses container and section BBCode.      

Preface

  • This tutorial has not been updated for the most recent version of the sidebar. This version not optimized for mobile.
  • I am not using a premade World Anvil theme, this is the default one. I made my own theme and wrote all of the CSS for it.
  • The menu code was at first in the Global World Navigation Sidebar Custom Content section, but I had to move it to the Global Copyright Footer because I wanted to do Tag Based Menu Highlighting. The sidebar will still work if you put it in either section, the CSS will just be a little different. I will talk about both ways.
  • The CSS on this page is based off of the Global Footer way as it's a little easier to read.
  •  

    Menu Code Location

    Global Nav Sidebar Location
    Showing the location for the Global Navigation Sidebar Custom Content for the custom CSS Sidebar Menu
    "Ok what's with all this "where I put the menu code" stuff, what do you mean?" I hear you ask..   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:
    On any given page, the CSS will look at the tags and highlight the menu item based on what it has.   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 want this tag based menu highlighting; put the menu code in the Global Footer section.
    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
  • Base class selector: .user-css-presentation
  • Div ID selector: #world-navigation-sidebar
  •   Global Copyright Footer section
  • Base class selector: .user-css
  • Div class selector: .sidebar
  •  

    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.  
    Any CSS that has stuff like var(--midnight) or var(--w30) or whatever, are my color variables I set in my CSS. Just replace the whole var() thing with your colors, or CSS variables. This is just so I can reuse colors without having to put the hex code in every time I want to use 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.  
  • Position: fixed will make it.. well in a fixed position. We want this, as we don't want it scrolling away from us.
  • Left and Top will set it all the way against the left side and just under the World Anvil banner, at 55px.
  • Do not mess with the World Anvil banner; it is against TOS. (If you have Sage membership, you can disable the banner. If you do that; set the top to 0.)
  • Margin and Padding is making sure it's all zeroed out, just in case if some theme or whatever is adding extra stuff here.
  • Also added some top padding just to push the first element away from the very top edge a bit.
  • Width is the default width when the sidebar is closed / collapsed, or not hovered over. I set it to 64px which seemed good to me.

  • Min width needed to be here because it was doing weird things if I didn't specifiy. I think it's because of the default CSS code for the sidebar.
  • Max height for expanding it to the bottom of the page. I forget why I used "Max height" specifically and not just height. idk.
  • I set overflow-x to hidden because of the Table of Contents title box stylized angled cut thing. It uses borders and I can't change the size of that. Without this, the border makes a horizontal scroll bar, if the sidebar is long enough to vertical scroll. The vertical scrollbar actually gets placed within the sidebar, slightly squishing everything, but because the title box element uses borders, it doesn't resize. I need it to be 250px specifically for when there is no scrollbar. This was annoying, so I just set this to hidden to get rid of the horizontal scrollbar. You do not need this if you do not use the stylized Table of Contents box.
  •  

    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.  
  • Position: fixed will make it.. well in a fixed position. We want this, as we don't want it scrolling away from us. This also allows us to position is wherever we want, even if it's apart of the Footer section.
  • Left and Top will set it all the way against the left side and just under the World Anvil banner, at 55px.
  • Do not mess with the World Anvil banner; it is against TOS. (If you have Sage membership, you can disable the banner. If you do that; set the top to 0.)
  • Margin and Padding is making sure it's all zeroed out, just in case if some theme or whatever is adding extra stuff here.
  • Also added some top padding just to push the first element away from the very top edge a bit.
  • Width is the default width when the sidebar is closed / collapsed, or not hovered over. I set it to 64px which seemed good to me.
  • Height of 100% so it expands all the way to the bottom.

  • z-index of 1500 makes it display overtop of pretty much anything, just in case, since it is technically apart of the footer section.
  • I set overflow-x to hidden because of the Table of Contents title box stylized angled cut thing. It uses borders and I can't change the size of that. Without this, the border makes a horizontal scroll bar, if the sidebar is long enough to vertical scroll. The vertical scrollbar actually gets placed within the sidebar, slightly squishing everything, but because the title box element uses borders, it doesn't resize. I need it to be 250px specifically for when there is no scrollbar. This was annoying, so I just set this to hidden to get rid of the horizontal scrollbar. You do not need this if you do not use the stylized Table of Contents box.
  •     The main differences in the CSS between the Global Footer and the other way:
  • You don't need the !important flag for the display.
  • You don't need to use min-width.
  • Used z-index just in case.
  •     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.)    
    Global Nav Sidebar Location
    Showing the location for the Global Navigation Sidebar Custom Content for the custom CSS Sidebar Menu
    Finally, the imfamous 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.  
    Note: Every icon used in the menu also has fa-fw and fa-lg CSS classes on them too. This is FontAwesome's CSS styling and will set it to a fixed width and specific font size.
      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: var(--bluesky)
    text-decoration: none;
    background-color: var(--midnight)
    }
    
      Both menu items and submenu items actually get the same CSS.
  • Padding left pushes the icon away from the edge.
  • Text align and align content are to center the text to the middle, and to the left.
  • Height is so we can have a uniform height for all the menu buttons since we always use these CSS classes.
  •   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.
  • Inline-block display will display the text inline with the icon. Otherwise the text will be below the icon.
  • Height 44px again just to be sure. I think. It slightly changes the position of the menu item when the sidebar is closed. idk
  • Font size is important here. This is how the text is hidden while the sidebar is closed. I did not do display: none because you cannot do smooth transitions with that, but you can with font size.
  • The rest of the properties after font size are just for positioning the text in the middle and stuff.   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: var(--darkcloud
    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.
  • Fixed position because we don't want it to scroll away from us.
  • Default width is 0 (for when sidebar is collapsed), because I was actually still able to hover over the hidden element and randomly have a dropout menu appear. It was kinda funny actually.
  • Left is so far because you have to take into account the expanded sidebar.
  • Margin top is at -44px so it lines up with the element that it's a submenu of. The height of the menu items are 44px, so we just minus that amount.
  • Font size is 0 because I'm doing that trick I used for the base menu.
  •   The second section is for the on hover state.
  • Visibility of course has to be set to visible.
  • The width will now be set to 250px, the same width as the base expanded sidebar.
  • Font size is inherit because I do not know what the default font size was, so I just set it to that.
  • Transition for smoothness.
  •   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.  
    Do as I say, not as I do
    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.
  • Padding of 22px on the top, and then ensured it's zeroed out for all other sides.
  • Position of relative (so I can use z-index), and z-index of 10 because otherwise it gets hidden behind the TOC title box.
  •   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.  
    The menu code needs to be in the Global Copyright Footer section for this to work.
    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:
  • You don't need the !important flag for the display.
  • You don't need to use min-width.
  • Used z-index just in case.
  • (In my specific case) Set overflow-x to hidden.
  •     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: var(--b50)
    color: var(--lightgold)
    }
    
      In this case I only showed three menu items. If you have more, just add them to the end and edit accordingly.  
    This is why I needed the sidebar to be within the .user-css.page div. I'm using the attribute CSS selector, and the tagging system will add the tags as a class to the .page div. If you put the sidebar code in the Global World Navigation Sidebar Custom Content section, it will put outside of the .user-css.page div, and then you can't use the .user-css.page[class*=tag-] CSS selector.
      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
    Here's the full CSS code, if you wanted to see. It's a lot, which is why I chose to only show a few elements.   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: var(--b50)
    color: var(--lightgold)
    }
    
        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
    CSS
    .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: var(--midnight)
    color: var(--bluesky)
    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.  
    Using the trick I've used above for the menu items, everything in the TOC is hidden by setting it's font to 0 while the sidebar is collapsed. However, for the title, the icon is actually visible when the sidebar is collapsed, and it hides when the sidebar is expanded. At the same time, the "Table of Contents" text font size is set, making it seem like the icon and text switch states or whatever.
      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, var(--b60) 0%, var(--midnight) 15%
    transition: all 0.2s ease-in-out;
    }
    
     
  • Padding of 15px on the top and bottom, ensure zeroed out sides.
  • Align text to the center.
  • Base (very slight) gradient background.
  •     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 var(--stormcloud
    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.  
  • Top margin of -10px will push it over the title box.
  • Left border of 250px will push it all the way to the right (ah little tricky trick) (the sidebar's full width is also 250px). It is set to transparent so the background color behind it shows through.
  • Bottom border is set to 10px to perfectly line up with the bottom of the title box. (If you change this, you'll have to also change the top margin)
  • Tada!
  • This little stylized angled slant thing is the reason I have overflow-x set to hidden, which I mentioned all the way at the top for the base sidebar CSS. The vertical scrollbar actually gets placed within the sidebar, slightly squishing everything, but because the title box element uses borders, it doesn't resize. I need it to be 250px specifically for when there is no scrollbar. This was annoying, so I just set this to hidden to get rid of the horizontal scrollbar.
     

    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.
  • Margin set to 0 because it otherwise affects the icon's position when the sidebar is closed.
  • Using that trick again by setting the font size to 0, or it will (again) mess with the position of stuff.
  •   For when the sidebar is expanded, this is where the title text will show.
  • Left margin of 5 so it's not up against the edge.
  • Set the actual font size so it.. actually shows.
  •     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).  
    Ooh, and an important thing I've found out. Set the bottom padding to something large (in this case, 6em)
    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: var(--bluesky)
    border-bottom: 1px solid var(--bluesky)
    }
    
      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.

    Comments

    Please Login in order to comment!
    Jun 5, 2024 16:53 by Tempest LaRaut

    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.

    I'm a pastry who likes to make up stories and run/play TTRPG's, queer, neurospicy,she/they.
    Jun 27, 2024 19:40 by Annie Stein

    Using tags to highlight parts of the sidebar is so clever! Thanks for sharing how you went about making your sidebar, it's really cool to see how people approach things.

    Creator of Solaris -— Come Explore!
    Powered by World Anvil