cssmenu

Margin and padding of sub-ULs inside LIs, how can I get around the (still) missing ::text-pseudoelement?


See the following snipped: Item 4 and 4.2 have sub-UL. Optically, I want to apply the padding just to the text-node, which is (as of now) not possible in CSS. I tried to give the sublists a negatve margin, but then I cant get them to fill the LI-element horizontally. What I want is that all items get the size of the largest visible items, that all horizontal paddings are --menu-padding and that LIs that have ULs inside don't have horizontal padding. But that their text-note has a (optical) --menu-padding-margin to its border. Somehow, I cant get all three working. Is there a way?

Like this

I am not looking for a javascript-solution or a change in the html.

:root {
  --menu-clr-item-bk:#84744dff;
  --menu-clr-item-tx:#ddddddff;
  --menu-clr-item-tx-hov:#84744dff;
  --menu-clr-item-bk-hov:#ddddddff;
  --menu-clr-item-tx-clildhov:#ccccccff;
  --menu-clr-item-bk-clildhov:#847b65ff;
  --menu-h-clr-tile-bk:#ddddddff;
  --menu-h-clr-item-bk:var(--menu-clr-item-bk);
  --menu-h-clr-item-bk-hov:var(--menu-clr-item-bk-hov);
  --menu-h-clr-item-tx:var(--menu-clr-item-tx);
  --menu-h-clr-item-tx-hov:var(--menu-clr-item-tx-hov);
  --menu-h-separator:0;
  --menu-h-shadow:none;
  --menu-v-clr-tile-bk:#ddddddff;
  --menu-v-clr-item-bk:var(--menu-clr-item-bk);
  --menu-v-clr-item-bk-hov:var(--menu-clr-item-bk-hov);
  --menu-v-clr-item-tx:var(--menu-clr-item-tx);
  --menu-v-clr-item-tx-hov:var(--menu-clr-item-tx-hov);
  --menu-v-separator:1px;
  --menu-v-shadow:0.1em 0.1em 0.1em #0008;
  --menu-padding:0.5em;
  --menu-checkmargin:0.5em;
  --menu-checksize:1em; }

* {
  box-sizing: border-box; }

body, html {
  height: 100%; }

nav > h1 {
  display: none; }

/* all menues and items */
nav ul {
  position: absolute;
  white-space: nowrap;
  display: flex;
  width: fit-content;
  list-style-type: none;
  margin: 0;
  padding: 0; }
  nav ul > li:has(> a) {
    padding: 0; }
    nav ul > li:has(> a) > a {
      display: inline-block;
      padding: var(--menu-padding); }
  nav ul li:focus-within > ul {
    display: flex; }

nav li {
  position: relative;
  align-items: left;
  display: flex;
  box-sizing: border-box;
  justify-content: space-between;
  line-height: 1;
  padding: var(--menu-padding); }
  nav li:has(ul:hover):hover {
    color: #999;
    background: #444; }
  nav li:hover {
    color: #fff;
    background: #000; }

nav ul:not(nav ul ul) {
  position: relative;
  text-align: left;
  flex-direction: column;
  white-space-collapse: collapse;
  left: 0;
  row-gap: var(--menu-v-separator);
  background: var(--menu-v-clr-tile-bk);
  box-shadow: var(--menu-v-shadow); }
  nav ul:not(nav ul ul) > li:focus-within:has(ul) {
    flex-direction: column;
    justify-content: space-between; }
  nav ul:not(nav ul ul) > li {
    display: flex; }
  nav ul:not(nav ul ul) > li > ul {
    bottom: calc(-1 * var(--menu-padding)); }
  nav ul:not(nav ul ul) ul {
    position: relative; }

nav ul:not(nav ul ul) > li {
  width: 100%;
  color: var(--menu-v-clr-item-tx);
  background: var(--menu-v-clr-item-bk); }

nav ul ul {
  display: none;
  position: relative;
  text-align: left;
  flex-direction: column;
  white-space-collapse: collapse;
  row-gap: var(--menu-v-separator);
  background: var(--menu-v-clr-tile-bk);
  box-shadow: var(--menu-v-shadow); }
  nav ul ul > li:focus-within:has(ul) {
    flex-direction: column;
    justify-content: space-between; }
  nav ul ul > li {
    display: flex; }
  nav ul ul > li > ul {
    bottom: calc(-1 * var(--menu-padding)); }
  nav ul ul ul {
    position: relative; }

nav li li {
  color: var(--menu-v-clr-item-tx);
  background: var(--menu-v-clr-item-bk); }
<!DOCTYPE html>
<html><head>
</head><body>
<nav>
<ul>
<li tabindex="0">[Item 1]</li>
<li tabindex="0">[Item 2]
<ul>
<li tabindex="0">[Item 2.1]</li>
<li>[Item 2.2] some</li>
<li tabindex="0">[Item 2.3]</li>
</ul>
</li>
<li tabindex="0">[Item 3]</li>
<li tabindex="0">[Item 4]
<ul tabindex="-1">
<li tabindex="0">[Item 4.1] some</li>
<li tabindex="0">[Item 4.2]
<ul tabindex="-1">
<li tabindex="0">[Item 4.2.1]
<ul tabindex="-1">
<li tabindex="0">[Item 4.2.1.1]</li>
<li tabindex="0">[Item 4.2.1.2]</li>
<li tabindex="0">[Item 4.2.1.3]</li>
</ul>
<li tabindex="0">[Item 4.2.2]</li>
<li><a href="">[Item 4.2.3]</a></li>
</ul>
</li>
<li tabindex="0">[Item 4.3]</li>
</ul>
</li>
<li tabindex="0">[Item 5]</li>
<li tabindex="0">[Item 6]
</li>
</ul>
</nav>
</body></html>


Solution

  • Giving the sublists a negative margin is almost right, all that was missing is that because the CSS contains nav ul { width: fit-content; } the width of the sublists are over-constrained, causing the right margin value to be ignored. Instead set the sublists' width to auto.

    So just add

    nav ul ul {
      margin-inline: calc(0px - var(--menu-padding));
      width: auto;
    }
    

    :root {
      --menu-clr-item-bk:#84744dff;
      --menu-clr-item-tx:#ddddddff;
      --menu-clr-item-tx-hov:#84744dff;
      --menu-clr-item-bk-hov:#ddddddff;
      --menu-clr-item-tx-clildhov:#ccccccff;
      --menu-clr-item-bk-clildhov:#847b65ff;
      --menu-h-clr-tile-bk:#ddddddff;
      --menu-h-clr-item-bk:var(--menu-clr-item-bk);
      --menu-h-clr-item-bk-hov:var(--menu-clr-item-bk-hov);
      --menu-h-clr-item-tx:var(--menu-clr-item-tx);
      --menu-h-clr-item-tx-hov:var(--menu-clr-item-tx-hov);
      --menu-h-separator:0;
      --menu-h-shadow:none;
      --menu-v-clr-tile-bk:#ddddddff;
      --menu-v-clr-item-bk:var(--menu-clr-item-bk);
      --menu-v-clr-item-bk-hov:var(--menu-clr-item-bk-hov);
      --menu-v-clr-item-tx:var(--menu-clr-item-tx);
      --menu-v-clr-item-tx-hov:var(--menu-clr-item-tx-hov);
      --menu-v-separator:1px;
      --menu-v-shadow:0.1em 0.1em 0.1em #0008;
      --menu-padding:0.5em;
      --menu-checkmargin:0.5em;
      --menu-checksize:1em; }
    
    * {
      box-sizing: border-box; }
    
    body, html {
      height: 100%; }
    
    nav > h1 {
      display: none; }
    
    /* all menues and items */
    nav ul {
      position: absolute;
      white-space: nowrap;
      display: flex;
      width: fit-content;
      list-style-type: none;
      margin: 0;
      padding: 0; }
      nav ul > li:has(> a) {
        padding: 0; }
        nav ul > li:has(> a) > a {
          display: inline-block;
          padding: var(--menu-padding); }
      nav ul li:focus-within > ul {
        display: flex; }
    
    nav li {
      position: relative;
      align-items: left;
      display: flex;
      box-sizing: border-box;
      justify-content: space-between;
      line-height: 1;
      padding: var(--menu-padding); }
      nav li:has(ul:hover):hover {
        color: #999;
        background: #444; }
      nav li:hover {
        color: #fff;
        background: #000; }
    
    nav ul:not(nav ul ul) {
      position: relative;
      text-align: left;
      flex-direction: column;
      white-space-collapse: collapse;
      left: 0;
      row-gap: var(--menu-v-separator);
      background: var(--menu-v-clr-tile-bk);
      box-shadow: var(--menu-v-shadow); }
      nav ul:not(nav ul ul) > li:focus-within:has(ul) {
        flex-direction: column;
        justify-content: space-between; }
      nav ul:not(nav ul ul) > li {
        display: flex; }
      nav ul:not(nav ul ul) > li > ul {
        bottom: calc(-1 * var(--menu-padding)); }
      nav ul:not(nav ul ul) ul {
        position: relative; }
    
    nav ul:not(nav ul ul) > li {
      width: 100%;
      color: var(--menu-v-clr-item-tx);
      background: var(--menu-v-clr-item-bk); }
    
    nav ul ul {
      display: none;
      margin-inline: calc(0px - var(--menu-padding));
      width: auto;
      position: relative;
      text-align: left;
      flex-direction: column;
      white-space-collapse: collapse;
      row-gap: var(--menu-v-separator);
      background: var(--menu-v-clr-tile-bk);
      box-shadow: var(--menu-v-shadow); }
      nav ul ul > li:focus-within:has(ul) {
        flex-direction: column;
        justify-content: space-between; }
      nav ul ul > li {
        display: flex; }
      nav ul ul > li > ul {
        bottom: calc(-1 * var(--menu-padding)); }
      nav ul ul ul {
        position: relative; }
    
    nav li li {
      color: var(--menu-v-clr-item-tx);
      background: var(--menu-v-clr-item-bk); }
    <!DOCTYPE html>
    <html><head>
    </head><body>
    <nav>
    <ul>
    <li tabindex="0">[Item 1]</li>
    <li tabindex="0">[Item 2]
    <ul>
    <li tabindex="0">[Item 2.1]</li>
    <li>[Item 2.2] some</li>
    <li tabindex="0">[Item 2.3]</li>
    </ul>
    </li>
    <li tabindex="0">[Item 3]</li>
    <li tabindex="0">[Item 4]
    <ul tabindex="-1">
    <li tabindex="0">[Item 4.1] some</li>
    <li tabindex="0">[Item 4.2]
    <ul tabindex="-1">
    <li tabindex="0">[Item 4.2.1]
    <ul tabindex="-1">
    <li tabindex="0">[Item 4.2.1.1]</li>
    <li tabindex="0">[Item 4.2.1.2]</li>
    <li tabindex="0">[Item 4.2.1.3]</li>
    </ul>
    <li tabindex="0">[Item 4.2.2]</li>
    <li><a href="">[Item 4.2.3]</a></li>
    </ul>
    </li>
    <li tabindex="0">[Item 4.3]</li>
    </ul>
    </li>
    <li tabindex="0">[Item 5]</li>
    <li tabindex="0">[Item 6]
    </li>
    </ul>
    </nav>
    </body></html>