Template:SubpageNav/styles.css: Difference between revisions
Template page
More actions
Created page with "→Template:SubpageNav/styles.css: .subpage-nav-wrapper { margin-bottom: 24px; } .subpage-nav { display: flex; align-items: center; flex-wrap: wrap; background: var(--color-surface-1); border: 1px solid var(--border-color-base); border-radius: 4px; padding: 0 12px; min-height: 48px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); } .subpage-nav-brand { display: flex; align-items: center; gap: 8px; font-weight: 800;..."  |
Rewrite to styles to align with the template rewrite  |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
/* Template:SubpageNav/styles.css */ | /* ============================================================================= | ||
 Template:SubpageNav/styles.css | |||
 UnfinishedProjects Wiki | |||
 | |||
 TABLE OF CONTENTS | |||
 1. Wrapper | |||
 2. Main Bar | |||
 3. Brand / Root Title | |||
 4. Links Container & Top-Level List | |||
 5. Nav Item Links & Folder Labels | |||
 6. Caret Toggle Button | |||
 7. Dropdown Panel (1st level) | |||
 8. Dropdown Items | |||
 9. Deep Nesting (3rd level+) | |||
 10. Current-Page Highlight | |||
 11. Hide raw PrefixIndex output | |||
 12. Mobile | |||
 ============================================================================= */ | |||
 | |||
 | |||
/* ============================================================================= | |||
 1. WRAPPER | |||
 clear:both prevents the nav from overlapping a floated ProjectInfobox. | |||
 ============================================================================= */ | |||
.subpage-nav-wrapper { | .subpage-nav-wrapper { | ||
   margin-bottom: |    margin-bottom: 0.75em; | ||
  clear: both; | |||
  width: 100%; | |||
} | } | ||
/* ============================================================================= | |||
 2. MAIN BAR | |||
 Compact single-row bar. overflow:visible is required so that absolutely- | |||
 positioned dropdowns can escape the bar's bounds. | |||
 ============================================================================= */ | |||
.subpage-nav { | .subpage-nav { | ||
   display: flex; |    display: flex; | ||
   align-items: center; |    align-items: center; | ||
   background: var(--color-surface-1); |    background: var(--color-surface-1); | ||
   border: 1px solid var(--border-color-base); |    border: 1px solid var(--border-color-base); | ||
   border-radius: |    border-radius: 6px; | ||
   padding: 0 12px; |    padding: 0 12px; | ||
   min-height: |    min-height: 38px; | ||
   box-shadow: 0 1px |    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); | ||
  font-size: 0.875em; | |||
  overflow: visible; | |||
} | } | ||
/* ============================================================================= | |||
 3. BRAND / ROOT TITLE | |||
 Separated from the links with a vertical divider. flex-shrink:0 stops | |||
 the brand from squishing when there are many nav links. | |||
 ============================================================================= */ | |||
.subpage-nav-brand { | .subpage-nav-brand { | ||
   display: flex; |    display: flex; | ||
   align-items: center; |    align-items: center; | ||
   gap: 8px; |    gap: 8px; | ||
   font-weight: |    font-weight: 700; | ||
   padding-right: 12px; | |||
   padding-right: |    margin-right: 12px; | ||
   margin-right: | |||
   border-right: 1px solid var(--border-color-base); |    border-right: 1px solid var(--border-color-base); | ||
   |    white-space: nowrap; | ||
  flex-shrink: 0; | |||
} | |||
 | |||
.subpage-nav-brand img { | |||
  flex-shrink: 0; | |||
} | } | ||
.subpage-nav- | .subpage-nav-title a { | ||
   color: |    color: var(--color-base); | ||
   text-decoration: none; |    text-decoration: none; | ||
} | } | ||
.subpage-nav- | .subpage-nav-title a:hover { | ||
   color: var(--wiki-primary); |    color: var(--wiki-primary); | ||
} | } | ||
/* | Â | ||
/* ============================================================================= | |||
 4. LINKS CONTAINER & TOP-LEVEL LIST | |||
 The container is a flex row; the <ul> inside is also a flex row so | |||
 items sit side-by-side. flex:1 lets the links area take remaining space. | |||
 ============================================================================= */ | |||
.subpage-nav-links { | |||
  display: flex; | |||
  align-items: center; | |||
  flex: 1; | |||
  min-width: 0; | |||
  position: relative; | |||
} | |||
 | |||
.subpage-nav-links > ul { | .subpage-nav-links > ul { | ||
   display: flex; |    display: flex; | ||
   flex-wrap: wrap; |    flex-wrap: wrap; | ||
  align-items: center; | |||
   list-style: none !important; |    list-style: none !important; | ||
   margin: 0 !important; |    margin: 0 !important; | ||
   padding: 0 !important; |    padding: 0 !important; | ||
   gap: |    gap: 2px; | ||
} | } | ||
.subpage-nav-links li { | .subpage-nav-links li { | ||
  position: relative; | |||
   margin: 0 !important; |    margin: 0 !important; | ||
   |    list-style: none !important; | ||
} | } | ||
.subpage-nav-links li a, | Â | ||
/* ============================================================================= | |||
 5. NAV ITEM LINKS & FOLDER LABELS | |||
 <a> for real pages, <span> for virtual folders with no direct page. | |||
 Both use inline-flex so the caret button sits flush next to the text. | |||
 ============================================================================= */ | |||
.subpage-nav-links li > a, | |||
.subpage-nav-links li > span { | .subpage-nav-links li > span { | ||
   display: |    display: inline-flex; | ||
   |    align-items: center; | ||
   |    padding: 4px 10px; | ||
   font-weight: |    font-weight: 600; | ||
   color: var(--color-base--subtle); |    color: var(--color-base--subtle); | ||
  border-radius: 4px; | |||
   text-decoration: none; |    text-decoration: none; | ||
   |    white-space: nowrap; | ||
   cursor: pointer; |    cursor: pointer; | ||
   transition: background 0. |    transition: background 0.1s, color 0.1s; | ||
  line-height: 1.4; | |||
} | } | ||
.subpage-nav-links li a:hover, | .subpage-nav-links li > a:hover, | ||
.subpage-nav-links li > span:hover, | .subpage-nav-links li > span:hover, | ||
.subpage-nav-links li.is-open > span { | .subpage-nav-links li.is-open > span { | ||
   background: var(-- |    background: var(--wiki-primary-subtle); | ||
   color: var(--wiki-primary); |    color: var(--wiki-primary); | ||
} | } | ||
/* ---------------------- | Â | ||
  | /* ============================================================================= | ||
  - |  6. CARET TOGGLE BUTTON | ||
.subpage-nav-links li ul { | Â Rendered as a <button> SIBLING to the <a> (not inside it). | ||
 This means clicking the link navigates normally; only the caret toggles. | |||
 Padding is tight so the button hugs the label. | |||
 ============================================================================= */ | |||
.subpage-nav-caret { | |||
  background: none; | |||
  border: none; | |||
  padding: 4px 2px 4px 0; | |||
  margin: 0; | |||
  cursor: pointer; | |||
  font-size: 0.7em; | |||
  line-height: 1; | |||
  color: var(--color-base--subtle); | |||
  vertical-align: middle; | |||
  border-radius: 3px; | |||
  transition: color 0.1s, transform 0.15s; | |||
} | |||
 | |||
.subpage-nav-caret:hover, | |||
.is-open > .subpage-nav-caret { | |||
  color: var(--wiki-primary); | |||
} | |||
 | |||
/* Rotate caret when dropdown is open */ | |||
.is-open > .subpage-nav-caret { | |||
  transform: rotate(180deg); | |||
} | |||
 | |||
 | |||
/* ============================================================================= | |||
  7. DROPDOWN PANEL (1st level) | |||
  Appears below the triggering <li>. z-index:1000 ensures it floats over | |||
 infoboxes and other page content. | |||
 ============================================================================= */ | |||
.subpage-nav-links li > ul { | |||
   display: none; |    display: none; | ||
   position: absolute; |    position: absolute; | ||
   top: 100%; |    top: calc(100% + 4px); | ||
   left: 0; |    left: 0; | ||
   min-width: |    min-width: 160px; | ||
   background: var(--color-surface-1); |    background: var(--color-surface-1); | ||
   border: 1px solid var(--border-color-base); |    border: 1px solid var(--border-color-base); | ||
   border-radius: |    border-radius: 6px; | ||
   box-shadow: 0 4px 16px rgba(0,0,0,0. |    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); | ||
   |    z-index: 1000; | ||
   padding: |    padding: 4px 0 !important; | ||
   |    list-style: none !important; | ||
} | } | ||
.subpage-nav-links li.is-open > ul { | |||
  display: block; | |||
} | } | ||
/* | Â | ||
.subpage-nav-links li. | /* ============================================================================= | ||
 8. DROPDOWN ITEMS (1st level children) | |||
 border-radius:0 so items fill the panel edge-to-edge. | |||
 padding-right is generous to give room before any nested caret. | |||
 ============================================================================= */ | |||
.subpage-nav-links li > ul > li > a, | |||
.subpage-nav-links li > ul > li > span { | |||
   display: flex; |    display: flex; | ||
  align-items: center; | |||
  padding: 6px 14px; | |||
  border-radius: 0; | |||
  white-space: nowrap; | |||
} | |||
/* ============================================================================= | |||
 9. DEEP NESTING (3rd level and deeper) | |||
 Sub-sub-menus open as an indented inline accordion WITHIN the dropdown | |||
 panel rather than as a second floating panel. This keeps the nav readable | |||
 without complex flyout positioning logic. | |||
 ============================================================================= */ | |||
.subpage-nav-links li > ul li > ul { | |||
  /* Override the absolute positioning set for 1st-level dropdowns */ | |||
  position: static; | |||
  box-shadow: none; | |||
  background: transparent; | |||
  border: none; | |||
  border-left: 2px solid var(--border-color-base); | |||
  border-radius: 0; | |||
  margin: 0 0 0 14px !important; | |||
  padding: 0 !important; | |||
  /* is-open controls display — handled by the same .is-open rule below */ | |||
  display: none; | |||
} | } | ||
.subpage-nav-links li ul li { | .subpage-nav-links li > ul li.is-open > ul { | ||
   |    display: block; | ||
} | } | ||
.subpage-nav-links li ul li a | .subpage-nav-links li > ul li > ul li > a, | ||
.subpage-nav-links li > ul li > ul li > span { | |||
   padding: |    padding: 5px 10px; | ||
   font- |    font-size: 0.95em; | ||
} | } | ||
.subpage-nav-links li | Â | ||
/* ============================================================================= | |||
 10. CURRENT-PAGE HIGHLIGHT | |||
 Applied by the gadget JS to the <a> that matches the current wgPageName. | |||
 Parent .has-dropdown items are also opened via JS (is-open class). | |||
 ============================================================================= */ | |||
.subpage-nav-links li > a.is-current { | |||
  color: var(--wiki-primary); | |||
   background: var(--wiki-primary-subtle); |    background: var(--wiki-primary-subtle); | ||
} | } | ||
/* | Â | ||
.subpage- | /* ============================================================================= | ||
 11. HIDE RAW PREFIXINDEX OUTPUT | |||
 Special:PrefixIndex renders a full <ul> of links before the gadget runs. | |||
 Hiding this element prevents a flash of unstyled content. The gadget | |||
   display: |  removes .subpage-auto-list entirely and inserts the clean nested list. | ||
 ============================================================================= */ | |||
.subpage-auto-list { | |||
   display: none; | |||
} | } | ||
.subpage-nav-links li. | Â | ||
.subpage-nav-links li. | /* ============================================================================= | ||
 12. MOBILE (≤ 720 px) | |||
 On small screens the bar stacks vertically. Dropdowns expand inline | |||
 (position:static) instead of floating, acting as an accordion. | |||
 ============================================================================= */ | |||
@media (max-width: 720px) { | |||
 | |||
  .subpage-nav { | |||
    flex-direction: column; | |||
    align-items: stretch; | |||
    padding: 0; | |||
    font-size: 1em; /* restore base size on mobile */ | |||
  } | |||
 | |||
  .subpage-nav-brand { | |||
    border-right: none; | |||
    border-bottom: 1px solid var(--border-color-base); | |||
    padding: 8px 14px; | |||
    margin-right: 0; | |||
  } | |||
 | |||
  .subpage-nav-links { | |||
    flex-direction: column; | |||
    align-items: stretch; | |||
  } | |||
 | |||
  .subpage-nav-links > ul { | |||
    flex-direction: column; | |||
    gap: 0; | |||
  } | |||
 | |||
  /* Full-width tap targets on mobile */ | |||
  .subpage-nav-links li > a, | |||
  .subpage-nav-links li > span { | |||
    padding: 10px 14px; | |||
    border-radius: 0; | |||
    width: 100%; | |||
    box-sizing: border-box; | |||
  } | |||
 | |||
  .subpage-nav-caret { | |||
    margin-left: auto; /* push caret to right edge */ | |||
    padding-right: 14px; | |||
  } | |||
 | |||
  /* 1st-level dropdown: expand inline, accent with primary-colour left border */ | |||
  .subpage-nav-links li > ul { | |||
    position: static; | |||
    box-shadow: none; | |||
    border: none; | |||
    border-left: 3px solid var(--wiki-primary); | |||
    border-radius: 0; | |||
    background: var(--color-surface-2); | |||
    min-width: 0; | |||
    margin: 0 !important; | |||
    padding: 0 !important; | |||
  } | |||
 | |||
  .subpage-nav-links li > ul > li > a, | |||
  .subpage-nav-links li > ul > li > span { | |||
    padding: 8px 14px 8px 24px; /* indent to show hierarchy */ | |||
  } | |||
 | |||
  /* 3rd-level+: extra indent */ | |||
  .subpage-nav-links li > ul li > ul { | |||
    border-left: 3px solid var(--border-color-base); | |||
    margin: 0 !important; | |||
  } | |||
 | |||
  .subpage-nav-links li > ul li > ul li > a, | |||
  .subpage-nav-links li > ul li > ul li > span { | |||
    padding: 8px 14px 8px 36px; | |||
  } | |||
} | } | ||
Latest revision as of 06:22, 23 March 2026
/* =============================================================================
Template:SubpageNav/styles.css
UnfinishedProjects Wiki
TABLE OF CONTENTS
1. Wrapper
2. Main Bar
3. Brand / Root Title
4. Links Container & Top-Level List
5. Nav Item Links & Folder Labels
6. Caret Toggle Button
7. Dropdown Panel (1st level)
8. Dropdown Items
9. Deep Nesting (3rd level+)
10. Current-Page Highlight
11. Hide raw PrefixIndex output
12. Mobile
============================================================================= */
/* =============================================================================
1. WRAPPER
clear:both prevents the nav from overlapping a floated ProjectInfobox.
============================================================================= */
.subpage-nav-wrapper {
margin-bottom: 0.75em;
clear: both;
width: 100%;
}
/* =============================================================================
2. MAIN BAR
Compact single-row bar. overflow:visible is required so that absolutely-
positioned dropdowns can escape the bar's bounds.
============================================================================= */
.subpage-nav {
display: flex;
align-items: center;
background: var(--color-surface-1);
border: 1px solid var(--border-color-base);
border-radius: 6px;
padding: 0 12px;
min-height: 38px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
font-size: 0.875em;
overflow: visible;
}
/* =============================================================================
3. BRAND / ROOT TITLE
Separated from the links with a vertical divider. flex-shrink:0 stops
the brand from squishing when there are many nav links.
============================================================================= */
.subpage-nav-brand {
display: flex;
align-items: center;
gap: 8px;
font-weight: 700;
padding-right: 12px;
margin-right: 12px;
border-right: 1px solid var(--border-color-base);
white-space: nowrap;
flex-shrink: 0;
}
.subpage-nav-brand img {
flex-shrink: 0;
}
.subpage-nav-title a {
color: var(--color-base);
text-decoration: none;
}
.subpage-nav-title a:hover {
color: var(--wiki-primary);
}
/* =============================================================================
4. LINKS CONTAINER & TOP-LEVEL LIST
The container is a flex row; the <ul> inside is also a flex row so
items sit side-by-side. flex:1 lets the links area take remaining space.
============================================================================= */
.subpage-nav-links {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
position: relative;
}
.subpage-nav-links > ul {
display: flex;
flex-wrap: wrap;
align-items: center;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2px;
}
.subpage-nav-links li {
position: relative;
margin: 0 !important;
list-style: none !important;
}
/* =============================================================================
5. NAV ITEM LINKS & FOLDER LABELS
<a> for real pages, <span> for virtual folders with no direct page.
Both use inline-flex so the caret button sits flush next to the text.
============================================================================= */
.subpage-nav-links li > a,
.subpage-nav-links li > span {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-weight: 600;
color: var(--color-base--subtle);
border-radius: 4px;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
transition: background 0.1s, color 0.1s;
line-height: 1.4;
}
.subpage-nav-links li > a:hover,
.subpage-nav-links li > span:hover,
.subpage-nav-links li.is-open > span {
background: var(--wiki-primary-subtle);
color: var(--wiki-primary);
}
/* =============================================================================
6. CARET TOGGLE BUTTON
Rendered as a <button> SIBLING to the <a> (not inside it).
This means clicking the link navigates normally; only the caret toggles.
Padding is tight so the button hugs the label.
============================================================================= */
.subpage-nav-caret {
background: none;
border: none;
padding: 4px 2px 4px 0;
margin: 0;
cursor: pointer;
font-size: 0.7em;
line-height: 1;
color: var(--color-base--subtle);
vertical-align: middle;
border-radius: 3px;
transition: color 0.1s, transform 0.15s;
}
.subpage-nav-caret:hover,
.is-open > .subpage-nav-caret {
color: var(--wiki-primary);
}
/* Rotate caret when dropdown is open */
.is-open > .subpage-nav-caret {
transform: rotate(180deg);
}
/* =============================================================================
7. DROPDOWN PANEL (1st level)
Appears below the triggering <li>. z-index:1000 ensures it floats over
infoboxes and other page content.
============================================================================= */
.subpage-nav-links li > ul {
display: none;
position: absolute;
top: calc(100% + 4px);
left: 0;
min-width: 160px;
background: var(--color-surface-1);
border: 1px solid var(--border-color-base);
border-radius: 6px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
z-index: 1000;
padding: 4px 0 !important;
list-style: none !important;
}
.subpage-nav-links li.is-open > ul {
display: block;
}
/* =============================================================================
8. DROPDOWN ITEMS (1st level children)
border-radius:0 so items fill the panel edge-to-edge.
padding-right is generous to give room before any nested caret.
============================================================================= */
.subpage-nav-links li > ul > li > a,
.subpage-nav-links li > ul > li > span {
display: flex;
align-items: center;
padding: 6px 14px;
border-radius: 0;
white-space: nowrap;
}
/* =============================================================================
9. DEEP NESTING (3rd level and deeper)
Sub-sub-menus open as an indented inline accordion WITHIN the dropdown
panel rather than as a second floating panel. This keeps the nav readable
without complex flyout positioning logic.
============================================================================= */
.subpage-nav-links li > ul li > ul {
/* Override the absolute positioning set for 1st-level dropdowns */
position: static;
box-shadow: none;
background: transparent;
border: none;
border-left: 2px solid var(--border-color-base);
border-radius: 0;
margin: 0 0 0 14px !important;
padding: 0 !important;
/* is-open controls display — handled by the same .is-open rule below */
display: none;
}
.subpage-nav-links li > ul li.is-open > ul {
display: block;
}
.subpage-nav-links li > ul li > ul li > a,
.subpage-nav-links li > ul li > ul li > span {
padding: 5px 10px;
font-size: 0.95em;
}
/* =============================================================================
10. CURRENT-PAGE HIGHLIGHT
Applied by the gadget JS to the <a> that matches the current wgPageName.
Parent .has-dropdown items are also opened via JS (is-open class).
============================================================================= */
.subpage-nav-links li > a.is-current {
color: var(--wiki-primary);
background: var(--wiki-primary-subtle);
}
/* =============================================================================
11. HIDE RAW PREFIXINDEX OUTPUT
Special:PrefixIndex renders a full <ul> of links before the gadget runs.
Hiding this element prevents a flash of unstyled content. The gadget
removes .subpage-auto-list entirely and inserts the clean nested list.
============================================================================= */
.subpage-auto-list {
display: none;
}
/* =============================================================================
12. MOBILE (≤ 720 px)
On small screens the bar stacks vertically. Dropdowns expand inline
(position:static) instead of floating, acting as an accordion.
============================================================================= */
@media (max-width: 720px) {
.subpage-nav {
flex-direction: column;
align-items: stretch;
padding: 0;
font-size: 1em; /* restore base size on mobile */
}
.subpage-nav-brand {
border-right: none;
border-bottom: 1px solid var(--border-color-base);
padding: 8px 14px;
margin-right: 0;
}
.subpage-nav-links {
flex-direction: column;
align-items: stretch;
}
.subpage-nav-links > ul {
flex-direction: column;
gap: 0;
}
/* Full-width tap targets on mobile */
.subpage-nav-links li > a,
.subpage-nav-links li > span {
padding: 10px 14px;
border-radius: 0;
width: 100%;
box-sizing: border-box;
}
.subpage-nav-caret {
margin-left: auto; /* push caret to right edge */
padding-right: 14px;
}
/* 1st-level dropdown: expand inline, accent with primary-colour left border */
.subpage-nav-links li > ul {
position: static;
box-shadow: none;
border: none;
border-left: 3px solid var(--wiki-primary);
border-radius: 0;
background: var(--color-surface-2);
min-width: 0;
margin: 0 !important;
padding: 0 !important;
}
.subpage-nav-links li > ul > li > a,
.subpage-nav-links li > ul > li > span {
padding: 8px 14px 8px 24px; /* indent to show hierarchy */
}
/* 3rd-level+: extra indent */
.subpage-nav-links li > ul li > ul {
border-left: 3px solid var(--border-color-base);
margin: 0 !important;
}
.subpage-nav-links li > ul li > ul li > a,
.subpage-nav-links li > ul li > ul li > span {
padding: 8px 14px 8px 36px;
}
}