NavMenu
A component for creating navigation menu lists.
Overview
<NavMenu.Root> <NavMenu.Item> <NavMenu.Link href="#menu"> Menu item 1 </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#menu"> Menu item 2 </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#menu"> Menu item 3 </NavMenu.Link> </NavMenu.Item></NavMenu.Root><ul class="b--navMenu"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#menu">Menu item 1</a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#menu">Menu item 2</a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#menu">Menu item 3</a> </li></ul>Use <NavMenu.Nest> for nested structures.
Styles
The NavMenu base styles are defined in the following CSS.
@layer lism-block {
.b--navMenu {
--link-td: none;
--hl: var(--hl--s);
--item-p: 0.5em;
--focus-offset: -1px; /* アコーディオン化した時にoutlineが一部見えなくなるのを防ぐ */
}
.b--navMenu_nest {
--item-p: inherit;
padding-inline-start: 1em;
}
.b--navMenu_link {
display: flex;
align-items: center;
gap: 0.5em;
color: inherit;
padding: var(--item-p);
}
.b--navMenu_nest,
.b--navMenu_item {
--bdc: inherit;
}
} The full source code is available on GitHub.
Usage
Provided as NavMenu (b--navMenu) from the @lism-css/ui package.
Import
import { NavMenu } from '@lism-css/ui/react'; import { NavMenu } from '@lism-css/ui/astro'; <link href="https://cdn.jsdelivr.net/npm/@lism-css/ui@0.28.0/dist/style.css" rel="stylesheet" /> Props
| Prop | Description |
|---|---|
<NavMenu.Root> hovBgc | Outputs --hov-bgc. (For use when -hov:-bgc is applied to b--navMenu_link.) |
<NavMenu.Root> hovC | Outputs --hov-c. (For use when -hov:-c is applied to b--navMenu_link.) |
<NavMenu.Root> itemP | Outputs the --item-p variable. Adjusts the padding of each link at once. |
<NavMenu.Link> hov | Specifies the hover style. Defaults to -bgc, changing the background color on hover. |
Examples
Setting common styles for all items at once
Some props can be specified on NavMenu.Root and applied to all links at once, instead of setting them directly on each NavMenu.Link.
itemPadjusts the padding (--item-p) of eachNavMenu.Link.hovBgcprovides the hover background color (--hov-bgc). (Requires-hov:-bgconNavMenu.Link.)hovCprovides the hover text color (--hov-c). (Requires-hov:-conNavMenu.Link.)
To change the padding per breakpoint, set p on each <NavMenu.Link> instead of using itemP.
<NavMenu.Root bd itemP="20" hovBgc="text" hovC="base"> <NavMenu.Item> <NavMenu.Link href="#menu1" hov="-bgc,-c">Menu item</NavMenu.Link> </NavMenu.Item> <NavMenu.Item bd-t> <NavMenu.Link href="#menu2" hov="-bgc,-c">Menu item</NavMenu.Link> </NavMenu.Item> <NavMenu.Item bd-t> <NavMenu.Link href="#menu3" hov="-bgc,-c">Menu item</NavMenu.Link> </NavMenu.Item></NavMenu.Root><ul class="b--navMenu -bd" style="--hov-bgc:var(--text);--hov-c:var(--base);--item-p:var(--s20)"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -hov:-c" href="#menu1">Menu item</a> </li> <li class="b--navMenu_item -bd-t"> <a class="b--navMenu_link -hov:-bgc -hov:-c" href="#menu2">Menu item</a> </li> <li class="b--navMenu_item -bd-t"> <a class="b--navMenu_link -hov:-bgc -hov:-c" href="#menu3">Menu item</a> </li></ul>Adding icons and badges
<NavMenu.Root> <NavMenu.Item> <NavMenu.Link href="#menu1" bgc="text" c="base"> <span>Menu item</span> <Lism as="span" bd px="10" bdrs="10" fz="xs" fw="bold"> New </Lism> <Icon icon="caret-right" ms="auto" /> </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#menu2" bgc="text" c="base"> <span>Menu item</span> <Icon icon="caret-right" ms="auto" /> </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#menu3" bgc="text" c="base"> <span>Menu item</span> <Icon icon="caret-right" ms="auto" /> </NavMenu.Link> </NavMenu.Item></NavMenu.Root><ul class="b--navMenu" style="--item-p:1em"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -bgc:text -c:base" href="#menu1"> <span>Menu item</span> <span class="-bd -px:10 -bdrs:10 -fz:xs -fw:bold">New</span> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="1em" height="1em" fill="currentColor" focusable="false" class="a--icon -ms:auto" aria-hidden="true"> <path d="M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z"></path> </svg> </a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -bgc:text -c:base" href="#menu2"> <span>Menu item</span> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="1em" height="1em" fill="currentColor" focusable="false" class="a--icon -ms:auto" aria-hidden="true"> <path d="M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z"></path> </svg> </a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -bgc:text -c:base" href="#menu3"> <span>Menu item</span> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="1em" height="1em" fill="currentColor" focusable="false" class="a--icon -ms:auto" aria-hidden="true"> <path d="M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z"></path> </svg> </a> </li></ul>Nested menus
<NavMenu.Root hovBgc="base-2"> <NavMenu.Item> <NavMenu.Link href="#menu1"> Menu item 1 </NavMenu.Link> </NavMenu.Item> <NavMenu.Item bd-t> <NavMenu.Link href="#menu2"> Menu item 2 </NavMenu.Link> <NavMenu.Nest bd-t> <NavMenu.Item> <NavMenu.Link href="#child-menu1"> Nested item </NavMenu.Link> </NavMenu.Item> <NavMenu.Item bd-t> <NavMenu.Link href="#child-menu3"> Nested item </NavMenu.Link> <NavMenu.Nest bd-t> <NavMenu.Item> <NavMenu.Link href="#child-menu4"> Nested level 2 item </NavMenu.Link> </NavMenu.Item> <NavMenu.Item bd-t> <NavMenu.Link href="#child-menu5"> Nested level 2 item </NavMenu.Link> </NavMenu.Item> </NavMenu.Nest> </NavMenu.Item> </NavMenu.Nest> </NavMenu.Item></NavMenu.Root><ul class="b--navMenu" style="--hov-bgc:var(--base-2)"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#menu1">Menu item 1</a> </li> <li class="b--navMenu_item -bd-t"> <a class="b--navMenu_link -hov:-bgc" href="#menu2">Menu item 2</a> <ul class="b--navMenu_nest -bd-t"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu1">Nested item</a> </li> <li class="b--navMenu_item -bd-t"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu3">Nested item</a> <ul class="b--navMenu_nest -bd-t"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu4">Nested level 2 item</a> </li> <li class="b--navMenu_item -bd-t"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu5">Nested level 2 item</a> </li> </ul> </li> </ul> </li></ul>Expanding nested menus with an accordion
Since link padding is managed by --item-p, you can use var(--item-p) inside an accordion to apply the same padding amount.
<NavMenu.Root bd-y itemP="0.75em" hovBgc="base-2"> <NavMenu.Item> <NavMenu.Link href="#menu1"> Menu item </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <Accordion.Root> <Accordion.Item> <Accordion.Heading> <Accordion.Button hov="-bgc" p="var(--item-p)"> Menu item (Accordion) </Accordion.Button> </Accordion.Heading> <Accordion.Panel p="0"> <NavMenu.Nest> <NavMenu.Item> <NavMenu.Link href="#child-menu1"> Nested item </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#child-menu2"> Nested item </NavMenu.Link> </NavMenu.Item> </NavMenu.Nest> </Accordion.Panel> </Accordion.Item> </Accordion.Root> </NavMenu.Item></NavMenu.Root><ul class="b--navMenu -bd-y" style="--hov-bgc:var(--base-2);--item-p:0.75em"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#menu1">Menu item</a> </li> <li class="b--navMenu_item"> <div class="b--accordion"> <div class="b--accordion_item"> <div class="b--accordion_heading" role="heading"> <button class="b--accordion_button set--plain -hov:-bgc -p" style="--p:var(--item-p)" aria-controls="{id}" aria-expanded="false" > Menu item (Accordion) <span class="b--accordion_icon a--icon" aria-hidden="true"></span> </button> </div> <div class="b--accordion_panel" id="{id}" hidden="until-found"> <div class="b--accordion_content l--flow -p:0"> <ul class="b--navMenu_nest"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu1">Nested item</a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu2">Nested item</a> </li> </ul> </div> </div> </div> </div> </li></ul>Displaying submenus on hover
Set layout='flex' on <NavMenu.Root> to lay out items horizontally, then add set='hov' to <NavMenu.Item> and hov='in:show' to the submenu element to reveal the child menu on hover.
<Box min-h="15rem"> <NavMenu.Root layout="flex" hl="s" itemP="0.5em .75em" pos="relative"> <NavMenu.Item set="hov" pos="relative"> <NavMenu.Link href="#menu3"> Parent Item <Icon icon="caret-down" /> </NavMenu.Link> <Box hov="in:show" pos="absolute" t="100%" l="50%" w="12rem" pt="5" style={{ translate: '-50% 0' }}> <Box fz="s" hl="s" bgc="base" bxsh="30" bd ov="hidden" p="5"> <NavMenu.Root> <NavMenu.Item> <NavMenu.Link href="#child-menu1">Nested item A</NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#child-menu2">Nested item B</NavMenu.Link> </NavMenu.Item> </NavMenu.Root> </Box> </Box> </NavMenu.Item> <NavMenu.Item set="hov" pos="static"> <NavMenu.Link href="#menu3"> Parent Item <Icon icon="caret-down" /> </NavMenu.Link> <Box hov="in:show" pos="absolute" t="100%" l="0" w="100%" pt="5"> <Box fz="s" hl="s" bgc="base" bxsh="30" bd ov="hidden" p="5"> <NavMenu.Root layout="columns" cols="2" g="5" itemP="10"> <NavMenu.Item> <NavMenu.Link href="#child-menu-a" g="10"> <Frame ar="1/1" bgc="base-2" w="3rem" bdrs="10"> <img src="https://cdn.lism-css.com/img/a-1.jpg" alt="" width="960" height="640" /> </Frame> <Stack> <span>Nested item A</span> <span class="-fz:s -o:p">This is the description for the item.</span> </Stack> </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#child-menu-b" g="10"> <Frame ar="1/1" bgc="base-2" w="3rem" bdrs="10"> <img src="https://cdn.lism-css.com/img/a-2.jpg" alt="" width="960" height="640" /> </Frame> <Stack> <span>Nested item B</span> <span class="-fz:s -o:p">This is the description for the item.</span> </Stack> </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#child-menu-c" g="10"> <Frame ar="1/1" bgc="base-2" w="3rem" bdrs="10"> <img src="https://cdn.lism-css.com/img/a-3.jpg" alt="" width="960" height="640" /> </Frame> <Stack> <span>Nested item C</span> <span class="-fz:s -o:p">This is the description for the item.</span> </Stack> </NavMenu.Link> </NavMenu.Item> <NavMenu.Item> <NavMenu.Link href="#child-menu-d" g="10"> <Frame ar="1/1" bgc="base-2" w="3rem" bdrs="10"> <img src="https://cdn.lism-css.com/img/a-4.jpg" alt="" width="960" height="640" /> </Frame> <Stack> <span>Nested item D</span> <span class="-fz:s -o:p">This is the description for the item.</span> </Stack> </NavMenu.Link> </NavMenu.Item> </NavMenu.Root> </Box> </Box> </NavMenu.Item> </NavMenu.Root></Box><div class="l--box -min-h" style="--min-h:15rem"> <ul class="b--navMenu l--flex -hl:s -pos:relative" style="--item-p:0.5em .75em"> <li class="b--navMenu_item set--hov -pos:relative"> <a class="b--navMenu_link -hov:-bgc" href="#menu3"> <p> Parent Item <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="1em" height="1em" fill="currentColor" focusable="false" class="a--icon" aria-hidden="true"> <path d="M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"></path> </svg> </p> </a> <div class="l--box -hov:in:show -pos:absolute -t:100% -l:50% -w -pt:5" style="translate:-50% 0;--w:12rem"> <div class="l--box -fz:s -hl:s -bgc:base -bxsh:30 -bd -ov:hidden -p:5"> <ul class="b--navMenu"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu1">Nested item A</a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc" href="#child-menu2">Nested item B</a> </li> </ul> </div> </div> </li> <li class="b--navMenu_item set--hov -pos:static"> <a class="b--navMenu_link -hov:-bgc" href="#menu3"> <p> Parent Item <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="1em" height="1em" fill="currentColor" focusable="false" class="a--icon" aria-hidden="true"> <path d="M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"></path> </svg> </p> </a> <div class="l--box -hov:in:show -pos:absolute -t:100% -l:0 -w:100% -pt:5"> <div class="l--box -fz:s -hl:s -bgc:base -bxsh:30 -bd -ov:hidden -p:5"> <ul class="b--navMenu l--columns -g:5" style="--item-p:var(--s10);--cols:2"> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -g:10" href="#child-menu-a"> <div class="l--frame -ar:1/1 -bgc:base-2 -w -bdrs:10" style="--w:3rem"> <img src="https://cdn.lism-css.com/img/a-1.jpg" alt="" width="960" height="640" /> </div> <div class="l--stack"> <span>Nested item A</span> <span class="-fz:s -o:p">This is the description for the item.</span> </div> </a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -g:10" href="#child-menu-b"> <div class="l--frame -ar:1/1 -bgc:base-2 -w -bdrs:10" style="--w:3rem"> <img src="https://cdn.lism-css.com/img/a-2.jpg" alt="" width="960" height="640" /> </div> <div class="l--stack"> <span>Nested item B</span> <span class="-fz:s -o:p">This is the description for the item.</span> </div> </a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -g:10" href="#child-menu-c"> <div class="l--frame -ar:1/1 -bgc:base-2 -w -bdrs:10" style="--w:3rem"> <img src="https://cdn.lism-css.com/img/a-3.jpg" alt="" width="960" height="640" /> </div> <div class="l--stack"> <span>Nested item C</span> <span class="-fz:s -o:p">This is the description for the item.</span> </div> </a> </li> <li class="b--navMenu_item"> <a class="b--navMenu_link -hov:-bgc -g:10" href="#child-menu-d"> <div class="l--frame -ar:1/1 -bgc:base-2 -w -bdrs:10" style="--w:3rem"> <img src="https://cdn.lism-css.com/img/a-4.jpg" alt="" width="960" height="640" /> </div> <div class="l--stack"> <span>Nested item D</span> <span class="-fz:s -o:p">This is the description for the item.</span> </div> </a> </li> </ul> </div> </div> </li> </ul></div>


