Reputation: 9591
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?
Upvotes: 8
Views: 7366
Reputation: 68319
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!).
Upvotes: 5