When creating the [rescue Trans rescue site](https://rescue-trans-rescue.glitch.com), I started with a right-aligned navbar. While developing and testing on my iPad, I got in the habit of hovering my hand over the top-right corner of the tablet, always ready to try the light/dark toggle or switch pages.
And then I thought about left-handed people - left handed tablet or touchscreen users in particular. Reaching across the screen repeatedly would start to be a real drag, wouldn't it?
Ok, let's make a toggle!
(Want to just see the outcome? Head on down the page to the [summary](#summary).)
## the button
First we'll need some HTML for our button. I added this to my menu:
```html
<buttonid="alignment"
title="toggle left/right navbar alignment"
aria-label="toggle left/right navbar alignment"
class="menu-link">
<!-- autopopulated by nav.js -->
</button>
```
It's important to note here that I added it to the *beginning* of the menu list. I want it to be the first item in the list so that it points over the left side of the screen with nothing obstructing it.
### handling narrow screens
Let's quickly take a moment to ensure that the toggle only shows up on wider screens with a bit of CSS:
```css
@media(max-width:500px){
#alignment{
display:none;
}
}
```
Now users on phones won't have an unhelpful button taking screen space.
Now let's move to `nav.js` and define some consts for ease of use. We're going to use [Font Awesome icons](https://fontawesome.com/icons) for this button, so we'll go grab their HTML for the left and right pointing hands.
So that gets us the basic functionality of changing the icon when the toggle is clicked. However, it does nothing for the navbar alignment. What do we need for that?
### alignment
Well, that depends on your navbar CSS. For this, let's run through the simplest possible version: your navbar is a flexbox and all items are treated equally. Maybe your CSS looks sorta like this:
```css
#navbar{
position:sticky;
top:0px;
width:100%;
display:flex;
/* This is the line that matters to us */
/* we'll want to swap between flex-start and flex-end */
justify-content:flex-end;
}
```
Let's add that `justify-content` setting to our JS (as well as a line to fetch the navbar by id):
```js
letnavbar=document.getElementById("navbar");
functionsetAlignRight(){
alignToggle.innerHTML=LEFT_ICON;
navbar.style.justifyContent="flex-end";
// If you have other necessary style changes, add them here
}
functionsetAlignLeft(){
alignToggle.innerHTML=RIGHT_ICON;
navbar.style.justifyContent="flex-start";
// If you have other necessary style changes, add them here
}
```
Now, the menu should re-orient itself when we interact with the toggle. However, you'll notice that the left-aligned menu shows up in the same order as the right aligned menu: handedness toggle first, then the rest of the menu.
(Forgive the lack of continuity with the header image.)

### moving the button
I don't want that; I want the handedness toggle to always point, unobstructed, to the side of the screen it moves things to. So let's move it around when we set alignment. It'll need to be the first item in the menu list for right-handed alignment, and the last item for left-handed. We can do that with `prepend()` and `append()`.
```js
functionsetAlignRight(){
alignToggle.innerHTML=LEFT_ICON;
navbar.style.justifyContent="flex-end";
navbar.prepend(alignToggle);
}
functionsetAlignLeft(){
alignToggle.innerHTML=RIGHT_ICON;
navbar.style.justifyContent="flex-start";
navbar.append(alignToggle);
}
```
Cool! Now we have a menu that re-aligns itself *and* repositions the alignment button.

### keyboard navigation
Oooh, but wait: keyboard navigation is broken.
When I tab over to the alignment button and hit `Enter`/`space`, it does what we expect, but it *also* loses keyboard focus. Because of that little `prepend()`/`append()` move, the element is removed from the DOM and re-added in a new location - now without focus. We'll need to add focus back to the `alignToggle` manually, so it's not lost.
We can do that with the `.focus()` function:
```js
functiontoggleAlign(){
if(align===LEFT)align=RIGHT;
elsealign=LEFT;
changeAlign(align);
// Replace focus on the toggle that's been moved
alignToggle.focus();
}
```
Ok, now focus is maintained... but it also shows up after a mouse click, not just a keyboard interaction. That's a little irritating. How do we fix that?
### managing focus
`toggleAlign()` is an event handler, which means it can optionally take an `event` var. For "click" events, that `event` var includes a field `detail` which provides the *click count*. This can be used to disambiguate single vs double clicks, *or* it can be used to test for keyboard interaction, which creates *zero clicks*.
Let's add that in:
```js
functiontoggleAlign(event){
if(align===LEFT)align=RIGHT;
elsealign=LEFT;
changeAlign(align);
// Zero clicks means this was a keyboard interaction
// Replace focus on the toggle that's been moved
if(event.detail===0)alignToggle.focus();
}
```
Now we should only replace visible focus for keyboard interactions.

## thanks for reading
Want to see further changes? Found a bug with this implementation? [Contact me](/contact)!
---
## summary
Here's the referenced HTML, CSS, and JS in full:
### HTML
```html
<buttonid="alignment"
title="toggle left/right navbar alignment"
aria-label="toggle left/right navbar alignment"
class="menu-link">
<!-- autopopulated by nav.js -->
</button>
```
### CSS
```css
#navbar{
position:sticky;
top:0px;
width:100%;
display:flex;
/* nav.js handles justify-content instead */
/* justify-content: flex-end; */
}
/* Remove the handedness toggle on narrow screens */