1

This nested mess is what the layout of my less stylesheet looks like (minus any actual styles):

#branding {
    h1 {

    }
    #tagline {

    }
    .ticker {

    }
    nav {
        ul {
            li {
                a {

                }
            }
        }
    }
    #search-form {
        input {

        }
        button {

        }
    }
}
#masthead {
    #store-locator {

    }
    #slider {
        ul {
            li {

            }
        }
    }
    #events {
        article {
            img {

            }
            h4 {

            }
            p {

            }
        }
    }
}
#main {
    #buckets {
        ul {
            li {
                img {

                }
                h3 {

                }
                .description {
                    .author {
                        a {

                        }
                    }
                    p {

                    }
                    blockquote {

                    }
                }
                .more {

                }
            }
        }
    }
    #social-feed {
        hgroup {

        }
        #filters {
            ul {
                li {

                }
            }
        }
        #feeds {
            .feed-column {
                > div {
                    img {

                    }
                    h3 {
                        span {

                        }
                    }
                    .description {
                        p {

                        }
                        .author {
                            a {

                            }
                        }
                    }
                }
            }
        }
        #feed-amount {
            a {
                &:before {

                }
                &:after {

                }
            }
        }
    }
}
#summary {
    nav {
        ul {
            li {
                a {

                }
            }
        }
    }
    #newsletter-form {
        h4 {

        }
        input {

        }
        button {

        }
    }
    #stay-connected {
        h4 {
            a {

            }
        }
    }
    #donation {

    }
    #contact-info {
        #contact-number {
            span {
                strong {

                }
            }
        }
        #contact-details {
            address {
                strong {
                    a {

                    }
                }
            }
            p {

            }
        }
    }
}

This makes sense to me in some ways because it mimics the layout of the markup, but it has some serious drawbacks such as overly specific selectors, IE:

#main #social-feed #feeds .feed-column > div .description p {}

My question is, what would be a better way to lay this document out?

Am I abusing LESS here? I searched "LESS stylesheet examples" and similar things, but I could not find one single example of a less stylesheet in its entirety--can anyone provide me of an example of a well-crafted less document?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Ivan Durst
  • 1,163
  • 2
  • 12
  • 24

2 Answers2

2

If LESS allows to nest selectors, then it does not mean that you necessarily should do that. Just do same things as you would do with regular CSS.

If your purpose is just visual hierarchy, then you can do this without real nesting:

#social-feed {
    /**/
}
    #feeds {
        /**/
    }

It typically does not make sense to nest id selectors (like #foo #bar) (as long as your elements hierarchy is persistent across different pages).

Also, it makes sense to use child combinator when it's applicable:

nav {
    & > ul {
        & > li {
            & > a {

            }
        }
    }
}

sothat resulting selector (NAV > UL > LI > A) could work potentially faster than a context selector (NAV UL LI A or NAV A).

Marat Tanalin
  • 13,927
  • 1
  • 36
  • 52
  • I agree, great point on the visual hierarchy without nesting. The resulting CSS can now be the same as if I had hand-typed it, which wouldn't have been the case with nesting – Ivan Durst Jan 04 '13 at 22:56
1

Selector bloating like you illustrate as one of the "serious drawbacks" is why I would use nesting of selectors sparingly. For me, having the CSS exactly match the layout of the markup is not that significant. I can use a few sparse comments to help me know what "section" I'm in in the CSS. So let me walk through some thoughts about how I might change things.

Keep Near, not Necessarily Nested

Example

/* branding */

#branding {
    h1 { }

    .ticker { }

    nav {
        ul { }
        li { }
        a { }
    }
}

#tagline { }

#search-form {
    input { }
    button { }
}

Discussion

First, note how put a comment as my section heading, rather than just using the #branding to group everything. This is my keeping of some "structure" like the html, I group by major "wrapper" headings and keep them near each other.

Second, any id tag's should be there own top level nesting group, assuming that you are correctly structuring your html to keep id's unique to a page. The only exception in my mind would be if you are using some class on the body element to switch looks on pages, and part of that look change includes a change to styling on an element selected by id (but even that may be handled by still putting id as top level; see "Utilize the Power of &" below). So I have pulled out your #tagline and #search-form from the nest under #branding.

Third, think about your design and code for minimal bloat. For example, if you have other nav elements on page (sub navs in side bars, etc.), then nesting the nav in #branding is worthwhile. Likewise, if you have other h1 or .ticker uses outside that wrapper. However, a common nest that I despise is the ul li a nest. If the only list inside nav is the ul, then there is no reason to nest the li inside it and end up with ul li in your selector string, because it is a given that all the li are located there. Likewise, if the only a tags in the nav are inside the list, then no need to nest that. Having this css...

#branding nav ul { }
#branding nav li { }
#branding nav a { }

...is just as clean and far less bloated in its selector string than the full nest version.

Utilize the power of &

I like the idea of using the & to add key parents to code. Recall the exception above about adding a class on the body element to control theming (or looks) across pages. You could nest it in the theme class, or you could do this:

Example

#branding {
    .theme1 & { }
    .theme2 & { }

    h1 { }

    .ticker { }

    nav {
        ul { }
        li { }
        a { }
    }
}

Discussion

Which would then produce a selector like .theme1 #branding to change the look of the #branding by the theme class. If you needed this to change properties for the items nested in it, there are various ways you can do it (it depends so much on what structure you want your final output to look like). One way is add it only to what is needed:

Example

#branding {
    .theme1 & { }
    .theme2 & { }

    h1 { 
      .theme2 & { //special code only for theme2 here }
    }

    .ticker { }

    nav {
        ul { 
          //main code here
          .theme1 & { //special code here }
          .theme2 & { }
        }
        li { }
        a { }
    }
}

Discussion

The disadvantage is some extra repetition of .theme classes in the code, while the advantage to this is that it keeps the end point targets grouped, so for example the ul above would produce code like this...

#branding nav ul {}
.theme1 #branding nav ul {}
.theme2 #branding nav ul {} 
#branding nav li {}
#branding nav a {}

...which keeps the all the various ul code next to each other. Now, if the li and a elements also needed changing on theme, you would have to decide if you want to move the themeing up a level so that the ul, li and a for a particular theme are grouped next to each other by theme, or if you keep it at the lowest level like above so that each ul, li, and a stay grouped by endpoint tag that is actually being styled.

Of course, using & to append normally is still useful in nesting, so...

a {
  &:hover {}
}

...to produce the a:hover {} info no matter how deeply nested the a may be is a great use of nesting and & combined.

Conclusion

There is certainly more that could be said on the subject. The key is to utilize the power of preprocessors where it is needed, not just because it is available. For me, mixins are the more useful part of preprocessors as opposed to nesting.

Community
  • 1
  • 1
ScottS
  • 71,703
  • 13
  • 126
  • 146
  • Very thorough, educational answer. That makes sense that IDs don't to be nested, and I didn't even know about using the `&` in that way to target the parent. Thank you for taking the time to explain this to me, I hope it helps others too – Ivan Durst Jan 04 '13 at 22:54