Search code examples
csspaddinghierarchy

How to sequentually increase CSS value for Padding property for Hierarchy structure?


I have hardcoded padding for each of the padding hierarchy level.

I need the solution for any of level without hardcoding padding for each level.

.jdm-nav li {
    font-size: 16px;
    position: relative;
}

.jdm-nav li a {
    padding-left: 15px;
}

.jdm-nav li li a {
    padding-left: 30px;
}

.jdm-nav li li li a {
    padding-left: 45px;
}

.jdm-nav li li li li a {
    padding-left: 60px;
}

li li li li ... a

Every next step could be increased by 15px.

Full code example. There is the mobile menu with ability to dropdown each item by click dropdown icon in the right item corner. If there are the items to expand.

.jdm-nav {
  background-color: white;
  width: 100%;
  padding: 0;
}

.jdm-nav ul {
  padding: 0;
}

.jdm-nav {
  list-style: none;
}

.jdm-nav li {
  list-style: none;
}

.jdm-nav ul {
  margin: 0;
}

.jdm-nav a {
  text-align: left;
  display: flex;
  color: rgb(76, 92, 104);
  font-weight: 500;
  padding: .5em 0;
  font-size: 16px;
  border-bottom: 1px solid rgba(76, 92, 104, 0.1);
}

.jdm-nav li {
  font-size: 16px;
  position: relative !important;
}

.jdm-nav li a {
  padding-left: 15px;
}

.jdm-nav li li a {
  padding-left: 30px;
}

.jdm-nav li li li a {
  padding-left: 45px;
}

.jdm-nav li li li li a {
  padding-left: 60px;
}

.jdm-nav li {
  position: relative;
}

.jdm-nav li>[data-jdm-sub-menu-switcher] {
  font-size: 13px;
  display: flex;
  width: 100%;
  height: 100%;
  border-bottom: 1px solid rgba(76, 92, 104, 0.1);
  position: relative;
}

.jdm-nav li {
  position: relative !important;
}

.jdm-nav li.menu-item-has-children>ul {
  max-height: 0;
  overflow: hidden;
  transition: 150ms max-height ease-out;
}

.jdm-nav li.menu-item-has-children>ul[data-jdm-state="expanded"] {
  max-height: initial;
}

.jdm-nav li.menu-item-has-children> :first-child {
  grid-column: 1;
}

.jdm-nav li.menu-item-has-children>[data-jdm-sub-menu-switcher] {
  grid-column: 2;
}

.jdm-nav li.menu-item-has-children>ul {
  grid-row: 2;
  grid-column-start: 1;
  grid-column-end: 3;
}

.jdm-nav li>[data-jdm-sub-menu-switcher]::after {
  position: absolute;
}

.jdm-nav li>[data-jdm-sub-menu-switcher]::after {
  position: absolute;
  width: 1em;
  height: 1em;
  content: '';
  clip-path: url(#prefix-mobile-dropdown-clip-mask);
  font-size: 13px;
  background-color: rgb(76, 92, 104);
  display: inline-flex;
  top: 50%;
  right: 50%;
  transform: translateY(-50%) translateX(50%);
}

.jdm-nav li.menu-item-has-children {
  display: grid;
  grid-template-columns: 100fr 15fr;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<div id="prefix-mobile-menu" class="mobile-menu-area prefix-mobile-menu" data-prefix-status="collapsed">
  <nav id="mobile-menu" class="jdm-nav">
    <ul id="primary-menu" class="menu-overflow">
      <li id="menu-item-2420" class="menu-item-has-children">
        <a href="1">1</a>
        <button data-jdm-sub-menu-switcher=""></button>
        <ul class="sub-menu" style="" data-jdm-state="expanded">
          <li id="menu-item-2418" class="menu-item-has-children"><a href="#">1.1</a>
            <button data-jdm-sub-menu-switcher=""></button>
            <ul class="sub-menu" style="" data-jdm-state="expanded">
              <li id="menu-item-2434" class="menu-item-has-children"><a href="1.1">1.1.1</a>
                <button data-jdm-sub-menu-switcher=""></button>
                <ul class="sub-menu">
                  <li id="menu-item-2435">
                    <a href="1.1.1.1">1.1.1.1</a>
                  </li>
                  <li id="menu-item-2436"><a href="1.1.1.2">1.1.1.2</a>
                  </li>
                  <li id="menu-item-2437"><a href="1.1.1.3/">1.1.1.3</a>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li id="menu-item-1832"><a href="2/">2</a></li>
    </ul>
  </nav>
  <svg width="0" height="0" viewBox="0 0 448 512">
		<defs>
			<clipPath
					viewbox="0 0 448 512"
					transform="scale(0.00223, 0.00195)"
					clipPathUnits="objectBoundingBox"
					id="prefix-mobile-dropdown-clip-mask">
				<path fill="#000000"
						d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"
						class=""></path>
			</clipPath>
		</defs>
	</svg>
</div>


Solution

  • Put the padding on the li and stretch the left of the a out by a large fixed amount.

    Illustrated:

    body > ul {
      border: 1px solid #eee;
      border-radius: 2px;
      margin: 1em;
      padding: 1em;
      overflow: hidden;
    }
    
    ul {
      list-style: none;
      padding: 0;
    }
    
    li {
      padding-left: 15px;
    }
    
    a {
      display: block;
      margin-left: -150px;
      margin-right: -1em;
      padding-left: 150px;
    }
    
    a:hover {
        background-color: #cff;
    }
    <ul>
      <li>
        <a href="javascript:;">nested</a>
        <ul>
          <li>
            <a href="javascript:;">navigation</a>
            <ul>
              <li>
                <a href="javascript:;">forever</a>
                <ul>
                  <li>
                    <a href="javascript:;">and</a>
                    <ul>
                      <li>
                        <a href="javascript:;">ever</a>
                    </ul>
                </ul>
            </ul>
          <li>
            <a href="javascript:;">foo</a>
          <li>
            <a href="javascript:;">bar</a>
        </ul>
      <li>
        <a href="javascript:;">baz</a>
    </ul>

    (Notice how the clickable area of each link extends all the way to the left.)