Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Mirantis reveals Lens Prism, an AI copilot for operating Kubernetes clusters

      July 3, 2025

      Avoid these common platform engineering mistakes

      July 3, 2025

      Full-Stack Techies vs Toptal: Which Is Better for React.js Outsourcing?

      July 3, 2025

      The AI productivity paradox in software engineering: Balancing efficiency and human skill retention

      July 2, 2025

      Microsoft Gaming studios head Matt Booty says “overall portfolio strategy is unchanged” — with more than 40 games in production

      July 3, 2025

      Capcom reports that its Steam game sales have risen massively — despite flagship titles like Monster Hunter Wilds receiving profuse backlash from PC players

      July 3, 2025

      Cloudflare is fighting to safeguard “the future of the web itself” — standing directly in the way of leading AI firms

      July 3, 2025

      Microsoft reportedly lacks the know-how to fully leverage OpenAI’s tech — despite holding IP rights

      July 3, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      PHP 8.5.0 Alpha 1 available for testing

      July 3, 2025
      Recent

      PHP 8.5.0 Alpha 1 available for testing

      July 3, 2025

      Recording cross browser compatible media

      July 3, 2025

      Celebrating Perficient’s Third Databricks Champion

      July 3, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Microsoft Gaming studios head Matt Booty says “overall portfolio strategy is unchanged” — with more than 40 games in production

      July 3, 2025
      Recent

      Microsoft Gaming studios head Matt Booty says “overall portfolio strategy is unchanged” — with more than 40 games in production

      July 3, 2025

      Capcom reports that its Steam game sales have risen massively — despite flagship titles like Monster Hunter Wilds receiving profuse backlash from PC players

      July 3, 2025

      Cloudflare is fighting to safeguard “the future of the web itself” — standing directly in the way of leading AI firms

      July 3, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»A Reader’s Question on Nested Lists

    A Reader’s Question on Nested Lists

    May 19, 2025

    A couple of days back, among the tens of crypto-scams that flood our contact inbox, we found an interesting question on nested lists from one of our readers.

    I have a problem (related to list-numbering) that seems commonplace, but I can’t seem to solve it or find any solution for. If any of your geniuses can answer this, I’m sure there are going to be a lot of people interested.

    Styling lists? Enough to catch my attention. After all, I just completed an entire guide about CSS counters. The message continues:

    Here’s the problem. It’s a routine numbering sequence, of different levels, found in (for example) [government], legislation, and in my case, condominium bylaws. I have five levels represented by the first number at each level of 1., (1), (a) (lower-alpha), (i) (lower-roman), (A) (upper-alpha). Of course, I have 5 levels here, but if you could demonstrate a solution for 3 levels.

    Fair enough! So, what we are looking to achieve is a nested list, where each sublist marker/counter is of a different kind. The example linked in the message is the following:

    8 The strata corporation must repair and maintain all of the following:
        (a) common assets of the strata corporation;
        (b) common property that has not been designated as limited common property;
        (c) limited common property, but the duty to repair and maintain it is restricted to
            (i) repair and maintenance that in the ordinary course of events occurs less often than once a year, and
            (ii) the following, no matter how often the repair or maintenance ordinarily occurs:
                (A) the structure of a building;
                (B) the exterior of a building;
                (C) chimneys, stairs, balconies and other things attached to the exterior of a building;
                (D) doors, windows and skylights on the exterior of a building or that front on the common property;

    While simple at first glance, it still has some nuance, so let’s try to come up with the most maintainable solution here.

    The ugly way

    My first approach to this problem was no approach at all; I just opened CodePen, wrote up the HTML, and tried to get my CSS to work towards the final result. After translating the Markdown into ol and li elements, and with no special styling on each list, the base list would look like the following:

    CodePen Embed Fallback

    Once there, my first instinct was to select each ol element and then change its list-style-type to the desired one. To target each level, I selected each ol depending on its number of ol ancestors, then let the specificity handle the rest:

    ol {
      list-style-type: decimal; /* Unnecessary; just for demo */
    }
    
    ol ol {
      list-style-type: lower-alpha;
    }
    
    ol ol ol {
      list-style-type: lower-roman;
    }
    
    ol ol ol ol {
      list-style-type: upper-alpha;
    }

    And as you can see, this works… But we can agree it’s an ugly way to go about it.

    CodePen Embed Fallback

    Nesting to the rescue

    Luckily, CSS nesting has been baseline for a couple of years now, so we could save ourselves a lot of ol selectors by just nesting each element inside the next one.

    ol {
      list-style-type: decimal;
      
      ol {
        list-style-type: lower-alpha;
         
        ol {
          list-style-type: lower-roman;
              
           ol {
            list-style-type: upper-alpha;
          }
        }
      }
    }
    

    While too much nesting is usually frowned upon, I think that, for this case in particular, it makes the CSS clearer on what it intends to do — especially since the CSS structure matches the HTML itself, and it also keeps all the list styles in one place. All to the same result:

    CodePen Embed Fallback

    It’s legal

    I don’t know anything about legal documents, nor do I intend to learn about them. However, I do know the law, and by extension, lawyers are finicky about how they are formatted because of legal technicalities and whatnot. The point is that for a legal document, those parentheses surrounding each list marker — like (A) or (ii) — are more than mere decoration and have to be included in our lists, which our current solution doesn’t.

    A couple of years back, we would have needed to set a counter for each list and then include the parentheses along the counter() output; repetitive and ugly. Nowadays, we can use the @counter-style at rule, which as its name implies, allows us to create custom counter styles that can be used (among other places) in the list-style-type property.

    In case you’re unfamiliar with the @counter-style syntax, what we need to know is that it can be used to extend predefined counter styles (like decimal or upper-alpha), and attach to them a different suffix or prefix. For example, the following counter style extends the common decimal style and adds a dash (-) as a prefix and a colon (:) as a suffix.

    @counter-style my-counter-style {
      system: extends decimal;
      prefix: "- ";
      suffix: ": ";
    }
    
    ol {
      list-style-type: my-counter-style;
    }
    CodePen Embed Fallback

    In our case, we’ll need four counter styles:

    • A decimal marker, without the ending dot. The initial submission doesn’t make it clear if it’s with or without the dot, but let’s assume it’s without.
    • A lower alpha marker, enclosed in parentheses.
    • A lower Roman marker, also enclosed in parentheses.
    • An upper alpha marker, enclosed in parentheses as well.

    All these would translate to the following @counter-style rules:

    @counter-style trimmed-decimal {
      system: extends decimal;
      suffix: " ";
    }
    
    @counter-style enclosed-lower-alpha {
      system: extends lower-alpha;
      prefix: "(";
      suffix: ") ";
    }
    
    @counter-style enclosed-lower-roman {
      system: extends lower-roman;
      prefix: "(";
      suffix: ") ";
    }
    
    @counter-style enclosed-upper-alpha {
      system: extends upper-alpha;
      prefix: "(";
      suffix: ") ";
    }

    And then, we just gotta replace each with its equivalent in our initial ol declarations:

    ol {
      list-style-type: trimmed-decimal;
    
      ol {
        list-style-type: enclosed-lower-alpha;
    
        ol {
          list-style-type: enclosed-lower-roman;
    
          ol {
            list-style-type: enclosed-upper-alpha;
          }
        }
      }
    }
    CodePen Embed Fallback

    It should work without CSS!

    Remember, though, it’s a legal document, so what happens if the internet is weak enough so that only the HTML loads correctly, or if someone checks the page from an old browser that doesn’t support nesting or @counter-style?

    Thinking only about the list, in most websites, it would be a mild annoyance where the markers go back to decimal, and you have to go by padding to know where each sublist starts. However, in a legal document, it can be a big deal. How big? I am no lawyer, so it beats me, but we still can make sure the list keeps its original numbering even without CSS.

    For the task, we can use the HTML type attribute. It’s similar to CSS list-style-type but with its own limited uses. First, its use with ul elements is deprecated, while it can be used in ol elements to keep the lists correctly numbered even without CSS, like in legal or technical documents such as ours. It has the following values:

    • "1" for decimal numbers (default)
    • "a" for lowercase alphabetic
    • "A" for uppercase alphabetic
    • "i" for lowercase Roman numbers
    • "I" for uppercase Roman numbers

    Inside our HTML list, we would assign the correct numbering for each ol level:

    CodePen Embed Fallback

    Depending on how long the document is, it may be more the hassle than the benefit, but it is still good to know. Although this kind of document doesn’t change constantly, so it wouldn’t hurt to add this extra safety net.

    Welp, that was kinda too much for a list! But that’s something intrinsic to legal documents. Still, I think it’s the simplest way to achieve the initial reader’s goal. Let me know in the comments if you think this is overengineered or if there is an easier way.

    More on lists!

    Almanac

    on

    Apr 23, 2021


    list-style


    ul { list-style: square outside none; }

    lists


    Sara Cope

    Almanac

    on

    Jan 28, 2025


    @counter-style


    @counter-style apple-counter { ... }

    lists


    Juan Diego Rodríguez

    Article

    on

    May 7, 2025


    Styling Counters in CSS

    lists


    Juan Diego Rodríguez


    A Reader’s Question on Nested Lists originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleCVE-2025-4916 – PHPGurukul Auto Taxi Stand Management System SQL Injection Vulnerability
    Next Article Vivaldi 7.4 Update Adds Keyboard Shortcut Controls

    Related Posts

    News & Updates

    Microsoft Gaming studios head Matt Booty says “overall portfolio strategy is unchanged” — with more than 40 games in production

    July 3, 2025
    News & Updates

    Capcom reports that its Steam game sales have risen massively — despite flagship titles like Monster Hunter Wilds receiving profuse backlash from PC players

    July 3, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Representative Line: Get Explosive

    News & Updates

    All You Need to Know About Frontend Architecture

    Web Development

    CVE-2025-4462 – TOTOLINK N150RT Buffer Overflow Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Sitecore PowerShell commands – XM Cloud Content Migration

    Development

    Highlights

    News & Updates

    Microsoft Edge for Android will copy this Google Chrome feature for private browsing

    June 4, 2025

    Microsoft Edge for Android is testing a feature that locks InPrivate tabs behind a PIN…

    How SkillShow automates youth sports video processing using Amazon Transcribe

    June 24, 2025

    CVE-2025-43003 – SAP S/4 HANA Configuration Privilege Escalation

    May 13, 2025

    CVE-2025-47762 – Apple iOS Unvalidated Redirect

    May 10, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.