Menu structure and CSS
Short guide for styling the menu with Custom CSS for this menu, Reusable Classes (CSS), and the default HTML. The menu has three levels: main bar, submenu, nested submenu.
Note: This demo covers a Slide / Standard menu. Structure is the same for most menu types; TABBAR and Mega Menu may have minor differences — use DevTools on the live page to confirm.
Custom CSS — what to type
In Advanced → Custom CSS for this menu, Navi+ adds a prefix (including #SF-… and menu scope). Write normal selectors only — do not type #SF-12345678 yourself.
.inner-level1 { padding: 12px 16px; }
ul.children[menulevel="2"] { border-radius: 8px; }
& = the menu itself (the #SF-… container). It’s optional — but it’s the clean way to style the whole menu, and the only way to do it inside @media:
& { background: #111; } /* the menu container */
&:hover { box-shadow: 0 4px 12px rgba(0,0,0,.15); }
& .inner-level1 { padding: 12px 16px; } /* '& ' with a space = inside the menu, same as .inner-level1 */
/* Responsive — only on small screens */
@media (max-width: 768px) {
& { padding: 6px; }
.name { font-size: 13px; }
}
You don’t have to use & — CSS without it keeps working exactly as before (.inner-level1 { … } is unchanged). & is just a shortcut for “this menu”.
Use #SF-… manually only when you are not using this box (for example CSS in the theme file).
Global Stylesheet / CSS is a separate field: it applies to the whole site and is not scoped to one menu — use with care.
Reusable Classes (CSS): define .yourClass { … } in the Reusable table and assign the class to items — rules stay in the same internal CSS bundle; you do not need to add #SF-… in the box. The class appears on the li.
Do not wrap content in a <style> tag in the box — plain CSS only.
Per-item CSS (style just one item)
Every menu item has its own CSS box: edit the item → Advanced → Internal Stylesheet / CSS. This is separate from Custom CSS for this menu (which is menu-wide). Per-item CSS travels with the item — if you copy or duplicate the item, its styling comes along.
Full guide: for one item’s HTML structure and every CSS syntax, see Menu item structure and CSS.
Write plain CSS. & means this item (the item’s own row / li) — like & in Sass:
& { background: #fff5f5; border-radius: 10px; }
&:hover { background: #ffe4e6; }
Target the inner parts of the item with normal class selectors (same names as the rest of the menu: .inner, .name, .description, .icon, .image, .arrow):
.name { color: #b91c1c; }
.icon i { font-size: 22px; }
& .description { opacity: 0.8; }
A space after & means “a part inside the item”, so & .name and .name are the same. & written without a space (&:hover, &.active) styles the item’s own row.
Responsive (@media) works — great for mobile-only tweaks. Inside @media you must use a selector (this is standard CSS), so use & for the item itself:
@media (max-width: 768px) {
& { padding: 8px; }
.name { font-size: 13px; }
}
Notes:
- No
#SF-…needed, and no<style>tag — Navi+ scopes everything to this one item automatically, so it never affects other items. The CSS also travels with the item if you duplicate it. - You can still write a bare declaration without a selector (
color: red;) — it applies to this item’s row. This older style keeps working, but&is clearer and it’s the only way to style the row inside@media. - If a property is set both here and by the item’s visual settings (Media box / Inner box shadow, etc.), the visual setting wins. Remove/override that setting if you want the CSS to take over.
- To show/hide an item by device, use Display on mobile / Display on desktop in the editor — not CSS. On Wix, viewport-based
@mediamay not match the real screen; prefer the Display settings there. - Use the expand icon (top-right of the box) to open a larger code editor; press Esc or Done to close.
Use Per-item CSS for a one-off tweak to a single item; use Custom CSS for this menu (with .inner-level1, [data-name="…"], etc.) when you want to style many items or whole levels at once.
Detailed demo: one three-level branch (icon, image, name, description)
Example labels: Shop (level 1: icon + name + description) → Clothing (level 2: image + name) → T-Shirts (level 3: icon + name + description). This shows both media types and description.
The whole menu sits in one block:
<div id="SF-…" class="…">
<ul class="navigation"> … </ul>
</div>
SF-… is the menu embed id — visible in the Navi+ dashboard (the blue badge next to the menu title) and in DevTools on the live page.
Order inside each div.inner (runtime)
span.arrow— arrow (submenu / mobile, depends on menu type).- (Optional)
span.cart_count— only when the item uses cart badge with count. - Media — one of:
- Icon (Remix Icon /
ri-…):span.icon→i.ri-… - Image:
div.image-border→span.image-box→span.image→img
\&#xNAN;Note: if the item has an image, the app shows the image and does not render the icon for that row.
- Icon (Remix Icon /
div.info→div.flexcol→span.name(label) →div.description(only if you fill description in the editor).- (Optional / SEO) icon or image may be wrapped in
a[href]— you may see<a>…</a>aroundspan.iconor the image block in DevTools.
li classes explained
| Class | Meaning |
|---|---|
level-1 / level-2 / level-3 |
Depth of this item |
is-parent-top |
Level-1 item that has children |
is-parent |
Level-2+ item that has children |
data-name="…" |
Item label (attribute, useful for CSS [data-name] selectors) |
Full HTML demo (illustrative classes / URLs)
<div id="SF-8167331678" class="naviItem …">
<ul class="navigation">
<li class="item level-1 is-parent-top" linkto="/collections/all" data-name="Shop">
<!-- LEVEL 1: icon + name + description -->
<div class="inner inner-level1">
<span class="arrow"></span>
<!-- <span class="cart_count">3</span> ← cart badge only -->
<!-- ICON: Remix Icon (ri-…) -->
<span class="icon">
<i class="ri-store-2-line"></i>
</span>
<div class="info">
<div class="flexcol">
<span class="name">Shop</span>
<div class="description">Browse all categories</div>
</div>
</div>
</div>
<ul class="children" menulevel="2">
<li class="child level-2 is-parent" linkto="/collections/clothing" data-name="Clothing">
<!-- LEVEL 2: image + name (no description) -->
<div class="inner inner-level2">
<span class="arrow"></span>
<!-- IMAGE: when set, icon is not rendered -->
<div class="image-border">
<span class="image-box">
<span class="image">
<img
src="https://cdn.shopify.com/…/clothing.jpg"
alt="Clothing"
title="Clothing"
loading="lazy"
decoding="async">
</span>
</span>
</div>
<div class="info">
<div class="flexcol">
<span class="name">Clothing</span>
<!-- no .description if description is empty in the editor -->
</div>
</div>
</div>
<ul class="children" menulevel="3">
<li class="child level-3" linkto="/collections/t-shirts" data-name="T-Shirts">
<!-- LEVEL 3: icon + name + description -->
<div class="inner inner-level3">
<span class="arrow"></span>
<span class="icon">
<i class="ri-t-shirt-line"></i>
</span>
<div class="info">
<div class="flexcol">
<span class="name">T-Shirts</span>
<div class="description">New collection</div>
</div>
</div>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Media snippets (for reference)
Icon only (no image):
<span class="icon"><i class="ri-home-5-line"></i></span>
Image only (image URL set on the item):
<div class="image-border">
<span class="image-box">
<span class="image">
<img src="…" alt="…" title="…" loading="lazy" decoding="async">
</span>
</span>
</div>
Selector examples for Custom CSS (in the Navi+ box — do not type #SF-…)
/* Arrow */
.inner-level1 .arrow { }
/* Icon (any level) */
.inner-level2 .icon i { font-size: 20px; }
/* Image */
.inner-level2 .image img { border-radius: 8px; }
/* Title and description */
.inner-level1 .name { font-weight: 600; }
.inner-level1 .description { font-size: 12px; opacity: 0.85; }
/* Target by item name */
[data-name="Shop"] .name { color: red; }
Remember: level 2 / 3 submenus sit inside the parent li, after the parent’s div.inner — not as direct children of ul.navigation.
Same branch, text diagram:
Shop ← level 1 (main bar)
└─ Clothing ← level 2 (first submenu)
└─ T-Shirts ← level 3 (nested submenu)
Quick reference (suggested classes)
| Level | Row (li) |
Content wrapper | Next submenu |
|---|---|---|---|
| 1 | level-1 |
.inner-level1 |
ul.children[menulevel="2"] |
| 2 | level-2 |
.inner-level2 |
ul.children[menulevel="3"] if any |
| 3 | level-3 |
.inner-level3 |
— |
menulevel="2" / "3" is the index of that submenu panel — not the same as level-1 on a top-level item.
Quick tips
- Target one depth with
.inner-level1,.inner-level2,.inner-level3instead of only.inner. - Style a whole panel (background, radius):
ul.children[menulevel="2"]or[menulevel="3"]. - Text:
.info→.flexcol→.name,.description. - Icon:
.iconor.icon i— image:.image-border,.image img(see detailed demo above). - Arrow:
.arrow(usually first inside.inner). - Target a specific item by name:
[data-name="Home"] .name { … }.
Classes missing on the store?
Clear theme cache, republish the menu, or check the script version. Use DevTools to confirm class names on the live page.
Support documentation — Navi+