Question
Why is the bootstrap-sass makeColumn(X) mixin not behaving the same as the Bootstrap .spanX class? For example, a class using makeColumn(9) does not look the same as the same div using a .span9 class.
Context
I'm building an application using Ruby on Rails and having major problems trying to use the mixins in the bootstrap-sass gem.
When I use the classes I've defined I don't get the same styling as if I were to just use the .span class in Bootstrap. I've looked all over the Internet and can't figure out what's wrong. I'm guessing it's something fairly obvious that I'm just not seeing because I've been staring at a screen for too long.
HTML
<div class="content">
<div class="main">...</div>
<div class="sidebar">...</div>
</div>
scss file
#import "bootstrap";
body {
.main-content {
#extend .container;
}
.content {
#include makeRow();
}
.content .main {
#include makeColumn(9);
}
.content .sidebar {
#include makeColumn(3);
}
.feature {
#include makeColumn(4);
}
padding-top: 60px;
}
footer {
#extend .container;
}
#import "bootstrap-responsive";
Thanks for the help.
I'm not sure what SASS Adaptation you're using but in the one I'm using (https://github.com/anjlab/bootstrap-rails), there isn't a lot of documentation and the format changes.
Instead of #include makeRow(); you have to use:
#include make-row();
Instead of #include makeColumn(3); you have to use:
#include make-column(3);
more documentation can be found here: https://github.com/anjlab/bootstrap-rails/blob/master/app/assets/stylesheets/twitter/bootstrap/_mixins.scss
Related
I'm getting some strange behavior and was wondering if I am using a grid-column-row incorrectly.
I have the following HTML structure:
<div id="homeTop">
<!-- homeTop content such as headings and other nested rows and columns -->
</div>
<div id="homeMain">
<div id="homeMain-left"></div>
<div id="homeMain-right"></div>
</div>
<div id="homeBottom">
<!-- homeBottom content such as headings and other nested rows and columns -->
</div>
I then have the following SCSS to style this content:
#homeTop {
#include grid-column-row;
}
#homeMain {
#include grid-row;
}
#homeMain-left {
#include grid-column(12);
#include breakpoint(medium) {
#include grid-column(8/12);
}
}
#homeMain-right {
#include grid-column(12);
#include breakpoint(medium) {
#include grid-column(4/12);
}
}
#homeBottom {
#include grid-column-row;
}
When I view the page on a desktop-sized screen, there is one line of css that's causing the homeBottom div to float right, which is throwing off the layout. The line of CSS causing the issue is here:
#homeBottom:last-child:not(:first-child) {
float: right;
}
Since a column-row is meant to be a single element acting as a row and a column, in other words, a full width container, I'm confused why I would ever want it to have a float property. It seems that this line of CSS makes sense for columns, but not for column-rows, since the column-row behavior shouldn't depend on whether or not it's the last-child of its parent.
Is this a bug, or am I using the column-row incorrectly? I'm just trying to avoid setting homeBottom as a grid-row, and then including an extra html element inside of it just to act as a full-width grid-column. As you can see, this isn't necessary for homeTop, even though it's also using the grid-column-row mixin. This makes me think I may be using it incorrectly.
I guess another option would be to define my own my-grid-column-row mixin that includes the float declaration:
#mixin my-grid-column-row {
#include grid-column-row;
float: none !important;
}
But this seems like it shouldn't be necessary.
It looks like this is an issue with foundation:
http://github.com/zurb/foundation-sites/issues/8108
My workaround for now is to override the grid-column-row mixin with the following:
#mixin grid-column-row(
$gutter: $grid-column-gutter
) {
#include grid-row;
#include grid-column($gutter: $gutter);
float: none !important;
}
I'm using the SASS port of Bootstrap, and I'm wondering if there's any difference between using the pre-defined mixins and using SASS's #extend.
For instance, if I have:
<div class="wrapper">
Some content here....
</div>
Is there any difference between doing
.wrapper {
#include make-row();
}
and
.wrapper {
#extend .row;
}
?
If there's no difference, are there other mixins that aren't equivalent to a single #extend statement? If there aren't such mixins, why do the mixins even exist?
The big difference between #extend and a mixin is the way the css is compiled. It doesn't look like much in simple examples, but the differences and implications are significant and can be a real headache in the wild if used carelessly. #extend is a little bit like fools gold, looks great at first, but ...
Let's look at a simple example:
#extend
.row {
width: 50px;
}
.new-row {
#extend .row;
}
.another-row {
#extend .row;
}
compiles into:
.row,
.new-row,
.another-row {
width: 50px;
}
mixin
#mixin row() {
width: 50px;
}
.new-row {
#include row();
}
.another-row {
#include row();
}
compiles into:
.new-row {
width: 50px;
}
.another-row {
width: 50px;
}
A mixin includes the properties everywhere it is hit - copying them each time - whereas an #extend groups the selectors and defines the properties once. This isn't immediately obvious, because the difference is in the compiled css but it has some important implications:
Load order
With #extend the selectors will be grouped at the first point in the sass where they are encountered which can lead to some weird over-riding. If you define a selector and use #extend to bring in a property to and try to override a property defined earlier in your sass, but after the point at which the extended properties are grouped in the css then the override will not work. This can be quite perplexing.
Consider this logically ordered set of css definitions and the likely HTML: <div class='row highlight-row'></div>:
.red-text {
color: red;
}
.row {
color: green;
}
.highlight-row {
#extend .red-text;
}
compiles into:
.red-text,
.highlight-row {
color: red;
}
.row {
color: green;
}
So even though the sass ordering makes it look like the row colour would be red, the compiled css will make it green
Poor groupings
#extend can result in poorly grouped selectors in the resulting css. You can end up with thirty or forty unrelated things all sharing the same property for example. Using #extend for fonts is a good example of this.
Nesting
If you are using deeply nested sass (which is not good, btw) and you use #extend you will duplicate the fully nested selector for every #extend you use, resulting in bloated css. I've seen this a lot:
.selector-1 .selector-2 .selector-3 .selector-4,
.selector-1 .selector-2 .selector-3 .selector-4 a,
.selector-1 .selector-2 .selector-3 .selector-4 li,
.selector-1 .selector-2 .selector-3 .selector-4 td {
font-family: arial;
}
If you're new to SASS it pays to look at the compiled css.
Media queries
#extend do not work inside media queries, because media queries are not selectors.
Conclusion
My rule of thumb is to use an #extend over a mixin if you have no parameters and if you can reasonably define the #extend and share it amongst a few tightly related selectors that exist nearby in the sass, for example, in the same file that defines a sass module. Buttons are a good example of well used #extend:
%button {
padding: 10px;
}
.call-to-action {
#extend %button;
background-color: $green;
}
.submit {
#extend %button;
background-color: $grey;
}
The best article to help make the choice is here
PS, the % sign is a use of placeholder extends
tl:dr version: is there a way to #extend a css class and not have the original class appear in my compiled css without changing all my css classes to %placeholder classes?
Short answer based on the below answers: it appears there is no way to do this unless you go through and convert the css to silent/placeholder classes e.g. convert .one{} to %one{} and even then that will cause problems with media queries.
I have a css file (lets call it "style.css") which contains 200+ CSS classes to style various elements like forms and buttons etc. What I want is to include some of those classes in a project and other classes from that file in other random projects/websites. With each new project I also want to give the classes random semantic class names of my choosing.
My preprocessor of choice when working with CSS is SCSS and I really need an answer that uses the power of SCSS.
Here is a quick example of what I'm talking about - loading css into a SCSS file and then extending that css with my own class names:
//style.css
.one {
color: red;
padding-top: 1px;
}
//style2.scss
#import "style.css";
.two {
#extend .one;
}
The problem here is that my SCSS file will compile to CSS and look like this:
//style2.css
.one {
color: red;
padding-top: 1px;
}
.two {
color: red;
padding-top: 1px;
}
But what I want to do is only include the second class, which I gave a special name.
I've tried a few ways of doing this but here's one example that does not work but is along the lines of what I was thinking I should be able to do:
A.) First, I grab the style.css file and chuck copy/paste it into a style.scss file.
B.) Second I wrap all the whole thing in a placeholder/silent class, like so:
//style.scss
%placeholder {
.one {
color: red;
padding-top: 1px;
}
}
C.) Then I import that SCSS file and try and extend a class of my choosing that is within the placeholder, like this:
//style2.scss
#import "style";
.two {
#extend .one;
}
When I try and compile this I get a blank css file (and rightly so for trying to be too tricky). The other thing I know is that you can't extend nested selectors so "#extend %placeholder .one;" is also out of the question.
My question is this: does anyone know of a way to import and then extend a css class so that the compiled result does not include the imported css?
The only other solution I can think of is to just delete the imported css from the top of my file before I let it out into the wild. But this is honestly less than ideal solution.
Thank you in advance to any answers :)
You're using placeholders incorrectly, the placeholder should simply be one, no need to wrap it. Try this:
// style.scss
%one {
color: red;
padding-top: 1px;
}
// style2.scss
#import "style";
.two {
#extend %one;
}
Note that there is an issue with this approach. While the outputted CSS is leaner than using a mixin (#include), you will not be able to use %one inside of any #media queries. Ie. this will not work:
// style2.scss
#import "style";
#media screen and (max-width:1024px) {
.two {
// This won't produce CSS as it's inside the media query
#extend %one;
}
}
The only way I'm aware to get around this is to use a mixin instead of a placeholder which will result in more CSS (if you use one more than once).
// style.scss
#mixin one() {
color: red;
padding-top: 1px;
}
// style2.scss
#import "style";
#media screen and (max-width:1024px) {
.two {
#include one();
}
}
I've detailed the difference in output between mixins and placeholder selectors on my blog if you're not aware.
On their website, the first feature is "Experience cleaner markup without presentational classes.", how do they solve this problem?
I think what Compass has to offer in order to allow us to create cleaner and semantic markup comes for free if you already use SASS alone.
By instance take this trivial example:
Some Mixins
#mixin box {
display: block;
}
#mixin sized_box($width:auto, $height:auto) {
#include box;
width: $width;
height: $height;
}
#mixin floated_box($direction:none, $width:auto, $height:auto) {
#include sized_box($width, $height);
float: $direction;
}
#mixin left_box($width:auto, $height:auto) {
#include floated_box(left, $width, $height);
}
#mixin right_box($width:auto, $height:auto) {
#include floated_box(right, $width, $height);
}
A Placeholder
// divs will be red
div%colored_floating {
#include left_box;
background-color: #ff0000;
}
// paragraphs will be blue
p%colored_floating {
#include right_box;
background-color: #0000ff;
}
Our stylesheet
// if #some.selector * turns out to be a div it will be red,
// and if it is a paragraph it will be blue
#some.selector *{
#extend %colored_floating;
}
Finally on your markup, you don't need any presentational classes
Except for those to make the placeholders more specific, of course.
<section id="some" class="selector">
<div>This will float and it will be red</div>
<p>But this will float right and will be blue</p>
</section>
You could always do:
// to make the placeholders absolutely generic to the whole markup,
* {
#extend %colored_floating;
}
Again, sorry for the very trivial example, but hopefully it will give you an idea on how to get rid of the presentational classes on your markup, aiming to pure semantic content.
What Compass gives us in addition is a complete framework of these mixins, placeholders and so on, ready to be used for good.
Cheers!
I have researched SASS and Blueprint seperately, and think I understand how they work, and I have set up my project directory using the compass CLI tool, but I am at a loss as to the correct way to organize my project.
After initializing my project with
$ compass create my_project --using blueprint/semantic
...I was told to link the generated CSS files in my HTML with these lines
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" />
...but where should I put my own application-specific .scssfiles and how should I include the appropriate blueprint files?
It seems to me that I should not be including the generated print.css and screen.css directly into my HTML but instead doing something like:
#import "screen";
body {
#include container;
}
...and then using only the file generated from the above in my HTML. Otherwise why would we have a line like this in screen.scss?:
// Import all the default blueprint modules so that we can access their mixins.
#import "blueprint";
I can't use mixins in my HTML.
I'm finding the docs to be very vague and contradictory, and any sort of short example illustrating the combination of:
HTML
SCSS files generated from compass command above
SCSS files containing site-specific styling
would be very helpful for me and probably others.
The "screen.scss" and "print.scss" files are nothing magical. These are just example filenames given to the output which you can link from your HTML, but you don't have to: just delete them and create your own files if you prefer, or add your own styles to them. The intent with these 2 files is to keep the style concerns organized separately: you could add a "mobile.scss" and then link all these in your HTML, or import them together into one master file under #media blocks.
I can't use mixins in my HTML.
Mixins don't apply to your HTML. They are a helpful technique used for writing your SCSS source code: the compiled CSS output or the HTML doesn't know anything about them. You should be using mixins to take advantage of Sass.
I have researched SASS and Blueprint seperately
It's important to understand what the Blueprint classes do first, but when you use Compass there are different approaches for how you apply frameworks like Blueprint:
1. Use Blueprint's original non-semantic class names throughout your HTML
This is not considered best-practice, but it's a way to get started especially when wireframing/scaffolding:
screen.scss
#import "blueprint";
// This outputs Blueprint's classes into your stylesheet:
#include blueprint;
#sidebar { background: $blue; }
#main { background: $yellow; }
screen.css (compiled)
.column { float: ... }
.span-6 { width: ... }
.span-12 {width: ... }
/* ...etc., all of Blueprint's classes ... */
#sidebar { background: #ccf; }
#main { background: #ffc; }
index.html
<div id="sidebar" class="column span-6">sidebar content</div>
<div id="main" class="column span-12">main content</div>
The result is the same as using Blueprint without Sass/Compass. Your HTML would contain the presentational classes, which are really not too different from just using style="width:120px" on your elements: it's just done using classes instead.
2. Use Blueprint as mixins into your own semantic class names:
screen.scss
#import "blueprint";
// Do not output Blueprint's classes into your stylesheet.
// Instead, write your own classes and mixin the functionality:
#sidebar {
#extend .column;
#include span(6);
background: $blue; }
#main {
#extend .column;
#include span(12);
background: $yellow; }
screen.css (compiled)
.column, #sidebar, #main { float: left; ... }
#sidebar { width: 240px; background: #ccf; }
#main { width: 480px; background: #ffc; }
index.html
<div id="sidebar">sidebar content</div>
<div id="main">main content</div>
As you can see, the second method moves Blueprint's presentation logic out of the HTML and into the stylesheet.
The judicious use of #extend (instead of #include) is an optimization that lets you group common styles together, e.g. all the elements that are "columns" are defined once as a list of selectors; only their different widths are included directly into each element.