Pseudo-element z-index issues

Advertisements

I am trying to style lists in my website using pseudo elements to replace the default bullet point. However, the pseudo elements render on top of the dropdown menus in the navigation sidebar for some reason. Hover over one of the "Hover me" items to reproduce the issue.

:root {
/* Color definitions */
    --dark: #090515;
    --light: #EAE8F1;
    --accent: #667fcc;
    --accentLight: #8c9fd9;
    --accentDark: #5f73ad;

    /* Style settings */
    --contentWidth: 65vw;
    --sidebarWidth: calc(calc(100vw - var(--contentWidth))/2);
    --contentHorizontalPadding: 3%;
    --paragraphSpacing: 5px;
    --fontSize: 16px;
    --navFontSize: 16px;
    --navItemSpacing: 6px;
    --navVerticalPadding: 2px;
    --dropdownOffset: calc(calc(var(--navVerticalPadding)*2 + var(--navFontSize) + var(--navItemSpacing)*2)*-1);
    --ULBumpWidth: 5px;
    --ULMargin: 10px;
    --ULPadding: 5px;
    --borderRadius: 2px;
    --borderWidth: 2px;
}

    /* Text styling */
    body {
    background-color: var(--dark);
    color: var(--light);
    margin: 0;
    font-family: "Noto Sans Mono", monospace;
}

.content {
    margin-left: var(--sidebarWidth);
        padding: 10px;
    font-size: var(--fontSize);
}

.content>ul, ul>ul, ol>ul {
    list-style-type: none;
    border-left: var(--borderWidth) solid var(--accent);
    padding-left: var(--ULPadding);
    margin-left: var(--ULMargin);
}

.content>ul>li::before, ul>ul>li::before, ol>ul>li::before {
    content: "";
    position: relative;
    display: inline-block;
    background-color: var(--accent);
    height: calc(var(--fontSize)/2);
    width: var(--ULBumpWidth);
    bottom: calc(var(--fontSize)/8);
    right: var(--ULPadding);
    border-radius: 0 var(--borderRadius) var(--borderRadius) 0;
    z-index: 0
}

/* Navigation styling */
.header {
    position: fixed;
    height: 100%;
    width: var(--sidebarWidth);
    border-right: var(--borderWidth) solid var(--accent);
    background-color: var(--dark);
    background-blend-mode: difference;
}

.navigation {
    list-style-type: none;
    padding: 0;
    background-color: var(--dark);
}

.navigation a {
    font-size: var(--navFontSize);
    width: 90%;
    margin: 0 5% var(--navItemSpacing) 5%;
    display: inline-block;
    text-decoration: none;
    padding: var(--navVerticalPadding) 6px;
    background-color: var(--accentLight);
    color: var(--dark);
}

/* ul needs to be absolute so the dropdown does not displace other elements */
li.dropdown>ul {
    position: absolute;
    left: 100%;
    width: 100%;
    background: none;
    z-index: 100;
        display: none;
}

/* Some unorthodox positioning is needed list items since the parent element is offset and cannot be easily fixed */
li.dropdown>ul>li {
    position: relative;
    top: var(--dropdownOffset);
    background-color: var(--dark);
}

li.dropdown>ul>li>a {
    padding: var(--navVerticalPadding) 0;
}

li.dropdown:hover>ul>li>a {
    padding: var(--navVerticalPadding) 6px;
}

li.dropdown:hover>ul {
    display: block;
}
<div class="header">
    <ul class="navigation">
        <li><a>Home</a></li>
        <li><a>Page 1</a></li>
        <li><a>Page 2</a></li>
        <li><a>Page 3</a></li>
        <li class="dropdown">
            <a>Hover me</a>
            <ul class="navigation">
                <li><a>Page 1</a></li>
                <li><a>Page 2</a></li>
                <li><a>Page 3</a></li>
            </ul>
        </li>
        <li class="dropdown">
            <a>Hover me</a>
            <ul class="navigation">
                <li><a>Page 1</a></li>
                <li><a>Page 2</a></li>
                <li><a>Page 3</a></li>
            </ul>
        </li>
    </ul>
</div>
<div class="content">
    <!-- [split][begin sample] -->
    <h1>Page title</h1>
    <h2>Secondary title</h2>
    <ul>
        <li>Entry 1</li>
        <li>Entry 2</li>
        <li>Entry 3</li>
        <ul>
            <li>Sub-entry 1</li>
            <li>Sub-entry 2</li>
            <li>Sub-entry 3</li>
            <ul>
                <li>Sub-sub-entry 1</li>
                <li>Sub-sub-entry 2</li>
                <li>Sub-sub-entry 3</li>
            </ul>
            <li>Sub-entry 4</li>
        </ul>           
    </ul>
</div>

I tried just setting the Z-index of the navigation dropdowns to be higher than the pseudo elements in the list so that navigation dropdowns render over the bullet points, but this did not fix the issue. I thought that the bullets might be in a separate stacking context and tried moving the header HTML to the end of the document so that the stacking context might render correctly, but this caused the navigation menu to not render at all. I have a pretty weird setup for the dropdown menus, so I have included full context in case this is something totally out of left field.

>Solution :

This is pretty weird…

I tried multiple ways but nothing works. But, one way I found it works (but well… let’s say it’s not the best) is by setting the z-index to -1 in the style (.content>ul>li::before, ul>ul>li::before, ol>ul>li::before) .

.content>ul>li::before, ul>ul>li::before, ol>ul>li::before {
    /* more stuff here */
    z-index: -1; /* It was 0 before */
}

The code snippet with the change is below.

:root {
/* Color definitions */
    --dark: #090515;
    --light: #EAE8F1;
    --accent: #667fcc;
    --accentLight: #8c9fd9;
    --accentDark: #5f73ad;

    /* Style settings */
    --contentWidth: 65vw;
    --sidebarWidth: calc(calc(100vw - var(--contentWidth))/2);
    --contentHorizontalPadding: 3%;
    --paragraphSpacing: 5px;
    --fontSize: 16px;
    --navFontSize: 16px;
    --navItemSpacing: 6px;
    --navVerticalPadding: 2px;
    --dropdownOffset: calc(calc(var(--navVerticalPadding)*2 + var(--navFontSize) + var(--navItemSpacing)*2)*-1);
    --ULBumpWidth: 5px;
    --ULMargin: 10px;
    --ULPadding: 5px;
    --borderRadius: 2px;
    --borderWidth: 2px;
}

    /* Text styling */
    body {
    background-color: var(--dark);
    color: var(--light);
    margin: 0;
    font-family: "Noto Sans Mono", monospace;
}

.content {
    margin-left: var(--sidebarWidth);
        padding: 10px;
    font-size: var(--fontSize);
}

.content>ul, ul>ul, ol>ul {
    list-style-type: none;
    border-left: var(--borderWidth) solid var(--accent);
    padding-left: var(--ULPadding);
    margin-left: var(--ULMargin);
}

.content>ul>li::before, ul>ul>li::before, ol>ul>li::before {
    content: "";
    position: relative;
    display: inline-block;
    background-color: var(--accent);
    height: calc(var(--fontSize)/2);
    width: var(--ULBumpWidth);
    bottom: calc(var(--fontSize)/8);
    right: var(--ULPadding);
    border-radius: 0 var(--borderRadius) var(--borderRadius) 0;
    z-index: -1; /* The change is here */
}

/* Navigation styling */
.header {
    position: fixed;
    height: 100%;
    width: var(--sidebarWidth);
    border-right: var(--borderWidth) solid var(--accent);
    background-color: var(--dark);
    background-blend-mode: difference;
}

.navigation {
    list-style-type: none;
    padding: 0;
    background-color: var(--dark);
}

.navigation a {
    font-size: var(--navFontSize);
    width: 90%;
    margin: 0 5% var(--navItemSpacing) 5%;
    display: inline-block;
    text-decoration: none;
    padding: var(--navVerticalPadding) 6px;
    background-color: var(--accentLight);
    color: var(--dark);
}

/* ul needs to be absolute so the dropdown does not displace other elements */
li.dropdown>ul {
    position: absolute;
    left: 100%;
    width: 100%;
    background: none;
    z-index: 100;
        display: none;
}

/* Some unorthodox positioning is needed list items since the parent element is offset and cannot be easily fixed */
li.dropdown>ul>li {
    position: relative;
    top: var(--dropdownOffset);
    background-color: var(--dark);
}

li.dropdown>ul>li>a {
    padding: var(--navVerticalPadding) 0;
}

li.dropdown:hover>ul>li>a {
    padding: var(--navVerticalPadding) 6px;
}

li.dropdown:hover>ul {
    display: block;
}
<div class="header">
    <ul class="navigation">
        <li><a>Home</a></li>
        <li><a>Page 1</a></li>
        <li><a>Page 2</a></li>
        <li><a>Page 3</a></li>
        <li class="dropdown">
            <a>Hover me</a>
            <ul class="navigation">
                <li><a>Page 1</a></li>
                <li><a>Page 2</a></li>
                <li><a>Page 3</a></li>
            </ul>
        </li>
        <li class="dropdown">
            <a>Hover me</a>
            <ul class="navigation">
                <li><a>Page 1</a></li>
                <li><a>Page 2</a></li>
                <li><a>Page 3</a></li>
            </ul>
        </li>
    </ul>
</div>
<div class="content">
    <!-- [split][begin sample] -->
    <h1>Page title</h1>
    <h2>Secondary title</h2>
    <ul>
        <li>Entry 1</li>
        <li>Entry 2</li>
        <li>Entry 3</li>
        <ul>
            <li>Sub-entry 1</li>
            <li>Sub-entry 2</li>
            <li>Sub-entry 3</li>
            <ul>
                <li>Sub-sub-entry 1</li>
                <li>Sub-sub-entry 2</li>
                <li>Sub-sub-entry 3</li>
            </ul>
            <li>Sub-entry 4</li>
        </ul>           
    </ul>
</div>

Leave a ReplyCancel reply