Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to alias a class or tag to another class or tag in SASS or LESS?

I am trying to make my bootstrap 2.1 markup more semantic using Less or possibly Sass. Consider the following markup for Bootstrap's standard navigation bar:

<header id="main-nav" class="navbar navbar-static-top" role="banner">
    <nav class="navbar-inner" role="navigation">
        <div class="container">

            <!-- Collapse nav button -->
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>

            <!-- Nav -->
            <nav id="navlinks" class="nav-collapse collapse pull-right">
                <ul class="nav nav-pills">
                    <li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
            </nav>
        </div>
    </nav>
</header>

Obviously, it is easy to change DIVs to more semantic HTML 5 tags, but removing the chain of classes from the markup is more difficult. If you were to use mixins like:

header #main-nav {
    .navbar;
    .navbar-static-top;
}

The following definition wouldn't work because compound classes are not effected:

.navbar .btn-navbar {
    display: none;  // hide button in full width (Why a compound class? Redundant?)
}

Ideally, it would be nice if less or sass had such a syntax:

header#main-nav $= .navbar;  // copy .navbar definitions using #main-nav as the name

or

header#main-nav @= .navbar;  // rename .navbar definitions to #main-nav

Can this be done? If not, how can I achieve semantic markup?

like image 205
ATL_DEV Avatar asked Sep 14 '12 02:09

ATL_DEV


People also ask

What is alias in CSS?

Aliases allows you to define how to process Custom properties (sometimes referred to as CSS variables or cascading variables).

How do you add another class in CSS?

To select elements with a specific class, write a period (.) character, followed by the name of the class. You can also specify that only specific HTML elements should be affected by a class. To do this, start with the element name, then write the period (.)


1 Answers

There is no aliasing as you say it, but LESS and Sass both have the ability to write like this:

.navbar, #main-nav {
    .collapse {}
}

Which would output like this:

.navbar .collapse, #main-nav .collapse {}

Sass has a unique directive called @extend, which functions like this:

%common-styles {
    .collapse {}
}

.navbar {
    // unique navbar styles
    @extend %common-styles
}

#main-nav {
    // unique main-nav styles
    @extend %common-styles
}

The output would be identical to the output of the first for this simplified case, but allows you to add additional styling in an elegant way.

Update for rephrased question:

I use classes very sparingly, only to describe the collection of elements as a whole (is it a movie listing? Is it information about a client? Is it a call to action element?) and let descendant selectors take care of the rest. Chained classes (ala OOPCSS) are largely unnecessary when using a CSS Preprocessor: it can assemble styles for you.

In a theoretical Sass bootstrap, we might define a few things we like to reuse for navigation elements no matter what site we are designing (LESS has a slightly different syntax, but it can do this too).

@mixin drop-menu { // intended for use with ordered or unordered lists that contain unordered lists
    & > li {
        @include inline-menu;
        ul { display: none }
        &:hover {
            ul { display: list }
        }
    }
}

@mixin inline-menu { // use with ordered or unordered lists if you'd like
    display: inline;
    margin-right: 1em;
    & + li { margin-left: 1em; border-left: 1px solid }
}

@mixin subtle-box { // just a box with a subtle gradient and slightly rounded corners
    linear-gradient(white, #CCC);
    border-radius: .25em;
    padding: .5em;
}

@mixin clearfix {
    &:after {
        content: " ";
        display: table;
        clear: both;
    }
}

None of these items are part of your CSS until you ask them to be.

body > header nav { // this is our main navigation element
    @include drop-menu;
    @include subtle-box;
    color: blue;
    font-family: garamond, serif
}

nav.admin {
    @include inline-menu;
    color: orange;
}

section.gallery {
    @include clearfix;
    img { float: left; padding: 0 10px 10px 0 }
}

Now if you have multiple elements that are very different but have a good chunk of styling in common, by all means use the @extend directive mentioned in the original answer.

If you're deciding between Sass and LESS, Sass has considerably more features (like the really cool @extend directive, functions, lists, etc.). I initially chose LESS because it had a nice 3rd party Windows compiler so I didn't have to install Ruby on my virtual box, but fought against the language constantly (these variable variables are useless!).

like image 98
cimmanon Avatar answered Dec 07 '22 10:12

cimmanon