Jasny-Bootstrap using ".offcanvas-sm" in lessfile - css

I would like to use .offcanvas-sm which is assigned to an <nav> element into the Less file. The Less file looks like:
#import "../../jasny-bootstrap.less";
.test {
.offcanvas-sm;
}
Problem is that the Less processor says - class offcanvas-sm doesn't exist. Its from this "https://github.com/jasny/bootstrap/blob/master/less/offcanvas.less" Less file included in "jasny-bootstrap.less". But how can I import this code to a class?

The compiler is correct there, indeed .offcanvas-sm does not exist in the context you try to invoke it. The key word here is Scope: selectors defined in a media query can be used as a mixin only within this same media query block.
For this particular case extend will do the trick. Scope handling of the extend is somewhat orthogonal to that of mixins, so selectors defined within media query blocks are open for "extending" from an outer scope (but not in opposite):
.test {
&:extend(.offcanvas-sm all);
}
Or just:
.test:extend(.offcanvas-sm all) {
}
---
all keyword is necessary in this case since .offcanvas-sm style is actually a set of two rulesets: .offcanvas-sm and .offcanvas-sm.in

Related

LessCss - extending css on the fly

I am aware of that you can declare a class :
.someclass { ... }
And then extend it
.otherclass { &:extend(.someclass all) }
But does the .someclass really has to be declared ?
In my case only callers will apply the logic and there is no need for someclass to have the logic declared as well, as it is only a placeholder for similar css.
It would be nice if there was a &:extend(groupingFunction all) .
But maybe there is already?
Currently Less don't support this "placeholder-equivalent".
Checkout this issue: :extend mixins.
You can use the "#import (reference)" feature to somewhat "simulate" this behavior but it can cause unexpected problems in some cases (there are quite a few issues about the import reference feature).

Using BEM CSS with Angular Directives

I've been using BEM style CSS to style my angular directives and usually use replace: true to so that my Block level class can be on the "root" of the custom element. This makes it so that I can write all my CSS primarily with classes.
However, replace: true sometimes causes issues (having two ng-if, etc...) and is now marked as deprecated. So I'm starting to try to stay away from replace completely.
But now I'm having trouble applying BEM to these elements that have an actual custom tag the DOM -- now I have to use a tag name instead of a class name, which means I can't really use BEM anymore (since I'll have to use the tag name since I can't apply classes directly to my element in my template). Additionally, using modifiers on my custom element now seems impossible, as does using sibling CSS selectors.
Here's an example that hopefully will illustrate what I mean:
The directive:
angular.module('my.module')
.directive('customElement', function() {
return {
restrict: 'E',
scope: {
isSpecial: '='
},
template: '<div class="custom-element" ng-class="{\'custom-element--special\': isSpecial"></div>'
};
});
The CSS:
.custom-element {
background-color: white;
}
.custom-element--special {
background-color: red;
}
.custom-element--special + .custom-element--special { // this won't work without replace: true
background-color: blue;
}
If I use replace: true everything works as expected (but then it comes with its own headaches).
If I don't use replace, the classes are not applied to the root custom element so the child selector doesn't work.
I could always add classes to the element in the postLink function, but that makes the template much less clear.
Does anyone have any experience using BEM with angular and using classes instead of tag names in your custom directives? What did you do to solve this problem?
i known it's a problem having replace:false for readability purpose.
The actual problem is that we need our OOCSS but you are handling Angular Components with custom tags has CSS Objects, and is not the case.
There is no practical solution for this, i won't recommend you to start adding classes on postLink function.
However what we are use to do is treat the custom tag as is own CSS Object besides the inner object structure. Forcing us to implement an extra CSS class for the custom tag.
block-context
block-context__element
custom-element
Why doing this when block-context__element is a redundant' class?
Because the rest of your BEM structure is the one you will maintain, the custom-element block should have meaning by it self and the block-context__element element is no expected to, you should abstract the CSS Objects from the directive's implementation, if you in some point start changing your html components your classes should still apply.
I hope this answer helps you

Problems with less mix-ins

I'm trying to do (I think) a really simple mixin in LESS, and I'm not sure what's going wrong here.
I'm compiling with Visual Studio Web Essentials.
So here's my goal:
I want a style that is just like the boostrap control-label, except I want to change some property (let's say padding):
Here's my LESS:
#import (reference) 'bootstrap/bootstrap.less';
.my-test-class {
.control-label;
padding: 4;
}
This results in a compile error:
NameError: .control-label is undefined.
What am I doing wrong here?
As far as I can tell, all the .control-label class definitions reside within other class definitions in this file. Specifically, inside either .form-inline and .form-horizontal. However within .form-inline it is also inside a media query, which at present prevents it from being accessed as a mixin.
So that means you must access it via the only namespace available, like so:
#import (reference) 'bootstrap/bootstrap.less';
.my-test-class {
.form-horizontal > .control-label;
padding: 4;
}
The general principle to learn from this is one really needs to be aware of what the bootstrap code actually outputs to be able to access (or know whether you can even access) a piece of it as a mixin (whether importing it as (reference) or not).

Using less.css and Twitter Bootstrap 3 - mixins not working

Alrighty, so I am trying to add classes to my page via css. Below is an example of the less.css file I am writing:
.someClass {
.col-sm-6;
}
I swear this worked before, but for whatever reason, my compiler throws an error:
".col-sm-6 is undefined"
Compiler: WinLess
Essentially I'm just trying to assign the col-sm-6 class to a div for width/float etc... Please let me know if you can think of any reasons this wouldn't work.
Thanks!
Bootstrap 3 makes these class names via a dynamic mixin, so they are not directly accessible as mixins themselves (dynamically generated class names are not currently able in LESS to be accessed as mixins). Instead, you need to call the mixin to generate the code by doing this:
.someClass {
.make-sm-column(6);
}

Is it error-prone to use ID-attribute selectors (not #id) on body elements to namespace CSS files?

I'm using Sass to compile my SCSS stylesheets into a single assembled.css to reduce HTTP requests. To namespace individual pages for styling, I wrap each page-specific CSS file in an ID selector for that page's <body> element - for example:
body#support {
.introduction {
#extend %dropcap;
}
}
In nanoc (using ERB), I have a helper that assigns each page's body a dash-separated unique ID based on the HTML folder structure, so the root pages will be #support or #products, while their sub-pages would have an ID like `#products-giantspacelaser'.
I want to make a set of SCSS rules that only apply to these 'products' sub-pages (not including the root-level #products page itself). Is there anything I should look out for regarding specificity if I use an attribute selector instead of an ID for this, as follows?
body[id^="products-"] {
.introduction {
#extend %dropcap;
}
}
I really don't want to use !important, but I do want to ensure that these page-specific rules take precedent over styles set in the '_base.scss' partial that precedes them in the #import order. Seeing as I have full control over the HTML structure, I could also theoretically use Erb in the Sass files to substitute in a comma-separated list of IDs like so:
body#products-giantspacelaser,
body#products-laboratorycamouflage,
body#products-resurrecteddinosaur {
.introduction {
#extend %dropcap;
}
}
- but that seems quite inelegant. Thanks in advance.
EDIT:
I've written my other styles in a really cascade-reliant way:
Normalise CSS
HTML5 Boilerplate's & my own sensible house rules
CSS Libraries (in this case Bourbon & Neat)
A "_source.scss" which in turn imports its own mixins & placeholder selectors.
A "_base.scss" which styles the default layout framework of every page.
A series of .scss files for each page's individual content styling - and, I hoped, overrides of base.scss layout decisions when necessary (if the page needs to take a serious departure from the norm).
Either way, these individual page stylesheets would need to definitely have a higher specificity than earlier defaults, as they were written for a specific purpose & page.
I'm intentionally not using any ID selectors except for this one specific purpose - namespaceing page stylesheets.
Using, say
.services .sharktraining .introduction .disarmingJoke {} --0,0,4,0
in "_base.scss" would surpass
body[id^="products-"] .disarmingJoke {} --0,0,2,1
in a further-down-the-cascade "products.scss", wouldn't it? (N.B. I know needing to use four classes is awful practice, I just don't want to worry about something slipping through the namespace).
I suppose there's another - really dirty - option: to repeat the body[id^="products-"] selector many times, to simply outnumber even the most specific class-strength rule.
It's going to have to depend on how you've written your other styles and whether or not they should take precedence (see: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/).
If you match the selector exactly but prefix one of them with your body selector, the prefixed one will be specific enough to take precedence no matter what (even if the order was reversed):
body[id^="products-"] .widget {
color: green;
}
.widget {
color: red;
}
The .widget will be green because the first selector is more specific than the second.
The only problem with using attribute selectors over ids is if you care about IE6. If that's a concern for you, the IE7 JS library by Dean Edwards can help you out: http://code.google.com/p/ie7-js/
If changing how the page information is attached to the body element is an option, my recommendation would be to have the parent directory be an id and the child pages be classes:
<body id="products" class="giantspacelaser" />
This way you can retain the specificity of the id:
// excludes the body#products page, which wouldn't have a class set at all
body[class]#products {
// styling here
}

Resources