简体   繁体   中英

How to organize less classes correctly

I am newbie in LESS world, so I have question about the way I can organize my classes.

Here is my current less code for classes.

.links {
    width: 9em;
    height: 4em;
    position: absolute;
    top: 40%;
    left: 50%;
    margin-top: -20px;
    margin-left: -45px;
    opacity: 0;
    -webkit-transform: translate(0,-50px);
    -moz-transform: translate(0,-50px);
    -ms-transform: translate(0,-50px);
    -o-transform: translate(0,-50px);
    transform: translate(0,-50px);
    a {
        i {
            position: relative;
            color: @colorMainGreen;
            font-size: 16px;
            margin: 0 13px;
            z-index: 100;
            &::after {
                position: absolute;
                content: "";
                left: -7px;
                top: -7px;
                width: 30px;
                height: 30px;
                border: 1px solid @colorMainGreen;
                z-index: -1;
                border-radius: 3px;
                -webkit-transform: rotate(45deg);
                   -moz-transform: rotate(45deg);
                    -ms-transform: rotate(45deg);
                     -o-transform: rotate(45deg);
                        transform: rotate(45deg);
            }
            &:hover i {
                color:  #fff;
            }
        }
        &:hover {
            i {
                &:hover {
                    background-color: @colorMainGreen;
                }
            }
        }
    }
}

To make things clear, here is compiled version

.links {
  width: 9em;
  height: 4em;
  position: absolute;
  top: 40%;
  left: 50%;
  margin-top: -20px;
  margin-left: -45px;
  opacity: 0;
  -webkit-transform: translate(0, -50px);
  -moz-transform: translate(0, -50px);
  -ms-transform: translate(0, -50px);
  -o-transform: translate(0, -50px);
  transform: translate(0, -50px);
}
.links a i {
  position: relative;
  color: #68c3a3;
  font-size: 16px;
  margin: 0 13px;
  z-index: 100;
}
.links a i::after {
  position: absolute;
  content: "";
  left: -7px;
  top: -7px;
  width: 30px;
  height: 30px;
  border: 1px solid #68c3a3;
  z-index: -1;
  border-radius: 3px;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}
.links a i:hover i {
  color: #fff;
}
.links a:hover i:hover {
  background-color: #68c3a3;
}

And I need to add in my less code this part

.links,
.links a i,
.links a i::after {
    -webkit-transition: all 400ms;
    -moz-transition: all 400ms;
    -o-transition: all 400ms;
    transition: all 400ms;
}

As you can see

I need to apply this class in links and it's child classes.
I am not aware of all available methods, so I can only consider using mixins and add it in each class, but this is code duplication. Maybe there is another way to accomplish this, I've read about extension, maybe it is possible to use it here ? In OOP languases this would simple inheritence. Please suggest the best way to organize such code.

Short answer to your question is instead of writing selectors that target specific html structure (ie .links ai ) write reusable, generic classes that you sprinkle on your html or use them as a mixin (since every class is considered a mixin in LESS).

Better yet, use a known and documented CSS methodology, such as OOCSS which promotes the use of generic css classes.


Long answer: I can tell you are not very experienced with CSS and therefore you are not yet familiar with common practices and abstractions that can be used t structure your CSS code. Here's a few pointers to help you, not just with LESS but CSS in general.

General CSS Structure:

  1. Use as little nesting as possible. Nesting is more of a curse than a boon as I'm sure you'll figure out soon enough. It creates long selectors that are hard to read, hard to refactor and are bad for performance . But the worse thing about nesting is that it enforces a specific html structure .

    Instead apply your namespace using single classes (eg .links-anchor instead of .links a ) that way the namespace of links is preserved but no html structure is enforced. (i understand this html structure is too basic to see the benefits, but bear with me for now)

  2. Do not use element names in your selectors (this is called qualifying selectors). This again enforces a specific html structure (eg you can only use an i element in your current css) and it affects performance because browsers parse your selectors from right to left .

    That means that when a browser sees .links a it will first find all anchors in your page and then filter them down to those that are under an element with a class of .links .

    Instead, create single classes for every element you wish to style and namespace them using a parent that makes sense semantically. Eg: .links , .links-anchor and .links-anchor-i (i have no idea what the i element is meant to be represent in your code.

  3. Which leads me to my next point. Write semantic classes that describe what you are styling rather than targeting random html elements like i . This includes both your root element as well as any children you are styling.

    For example if those links are meant to be your main navigation component, choose a classname called .main-navigation for your root element then .main-navigation-link and .main-navigation-label (if that what i was referring too)

There are just some of the ways you can improve your CSS. I suggest reading the excellent http://cssguidelin.es/ page, which contains a lot more improvements as well as examples and resources. After reading through that and understanding some of the pitfalls of CSS, I suggest to start using an existing CSS methodology such as OOCSS , BEM , SMACSS or ITCSS


Now onwards to LESS/Tooling suggestions

1) Try to use nesting only for styling the variations element your selector is targetting and pseudo elements ( :before and :after ). This is possible via the & operator which is a shorthand for your original selector.

.navigation-link {
    &:hover {...}
    &:active {...}

    &:before {...}
}

2) Add a post-processor to your CSS build, such as Autoprefixer which allows you to write clean, web standard compliant CSS and that will later get expanded to the prefixed versions that your supported browsers require.

3) Avoid "magic numbers" where you can. Instead use LESS variables and calculations, so that it's self explanatory where that number comes from.

@layout-header-height: 40px;
@layout-padding: 10px;
.layout-header {position: fixed; height: @layout-header-height; ...}
.layout-body { padding-top: (@layout-header-height + @layout-padding); ...}

I think that's enough for now, but there are loads more info out there.

  • Look up articles by CSS legends such as Harry Roberts (CSS Wizardy), Nicole Sullivan (OOCSS), Jonathan Snook (SMACSS) and Nicolas Gallagher.
  • Look at the source code for big css projects such as Bootstrap and Foundation and see how they are using preprocessors to structure their code
  • And of course keep asking questions on Stackoverflow!

I hope this helps and good luck :)

you can do that by creating 1 more class. Just for example

create 1 more extra class like below and you can add this class into another class. so you don't need to write this code repeatedly. it is mixins provided by LESS.

.trans {
   -webkit-transition: all 400ms;
    -moz-transition: all 400ms;
    -o-transition: all 400ms;
    transition: all 400ms;
}

Now, you can add this class into all your 3 classes like below.

.links {
     .trans;
     a{
        i{
            .trans;
            &:after{
                .trans;
            }
        }
     }
}

to be more precise you can include below mixin classes so you don't need to write even this 4 lines for transition.

MIXIN LIBS

This may not be the answer you are looking for (and if not, then not to worry) but if you are learning LESS because you want to have more organised, easier-to-maintain stylesheets, then grouping-selectors-by-style , rather than grouping-styles-by-selector is one alternative approach (using standard CSS) which - although not widely adopted - offers as much control and ease of maintainance as pre-processors like SASS and LESS (but, self-evidently, does not require compliling).

Grouping-selectors-by-style is not for everyone, but because it breaks stylesheets up into a series of mini-stylesheets, I find (personally) it makes CSS debugging very easy indeed.

It also gets rid of the need for variables.

Eg To take a simple example, if h1 and nav h2 and footer h2 are the same color blue and aside h2 and article h2 and header h2 are all red and you decide you want h1 and nav h2 and footer h2 to be green, then a single update to a stylesheet where selectors are grouped by style will suffice, from:

.TEXT-COLOR,
h1, nav h2, footer h2 {color: rgb(0,0,191);}
header h2, aside h2, article h2 {color: rgb(255,0,0);}

to:

.TEXT-COLOR,
h1, nav h2, footer h2 {color: rgb(0,191,0);}
header h2, aside h2, article h2 {color: rgb(255,0,0);}

In a conventional stylesheet, where styles are grouped by selector, you'd need to make at least 2 changes from:

h1 {color: rgb(0,0,191);}
h2 {color: rgb(0,0,191);}
header h2, aside h2, article h2 {color: rgb(255,0,0);}

to:

h1 {color: rgb(0,191,0);}
h2 {color: rgb(0,191,0);}
header h2, aside h2, article h2 {color: rgb(255,0,0);}

and bear in mind this example is deliberately simple. If you were changing margin , padding , font-size and box-shadow all at once - that would be 4 changes in a stylesheet where selectors are grouped by style... but at least 8 changes in a stylesheet where styles are grouped by selector.

Here is your stylesheet above, with the selectors grouped by style:

.POSITION,
.links, .links a i::after {position: absolute;}
.links a i {position: relative;}

.CO-ORDINATES,
.links {top: 40%; left: 50%;}
.links a i {z-index: 100;}
.links a i::after {top: -7px; left: -7px; z-index: -1;}

.WIDTH_HEIGHT,
.links {width: 9em; height: 4em;}
.links a i::after {width: 30px; height: 30px;}

.MARGIN_PADDING,
.links {margin: -20px 0 0 -45px;}
.links a i {margin: 0 13px;}

.TEXT-COLOR,
.links a i {color: #68c3a3;}
.links a i:hover i {color: #fff;}

.TEXT-PRESENTATION,
.links a i {font-size: 16px;}

.BACKGROUND,
.links a:hover i:hover {background-color: #68c3a3;}

.BORDER,
.links a i::after {border: 1px solid #68c3a3; border-radius: 3px;}

.MISCELLANEOUS,
.links {opacity: 0;}

.PSEUDO-ELEMENTS,
.links a i::after {content: '';}

.TRANSFORM,
.links {
-webkit-transform: translate(0, -50px);
   -moz-transform: translate(0, -50px);
    -ms-transform: translate(0, -50px);
     -o-transform: translate(0, -50px);
        transform: translate(0, -50px);
}


.links a i::after {
-webkit-transform: rotate(45deg);
   -moz-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
     -o-transform: rotate(45deg);
        transform: rotate(45deg);
}

I have asked myself multiple times when started with sass. However, nesting is not the must option and you will make handling pure .css an nightmare for some developers, who might not want to use compilers

You should add some classes to your li and simplify nesting when possible. You can use BEM and follow DRY methodology

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM