Bootstrap: working with LESS, what's the good way? - css

I have a couple of questions I hope you help me to clarify about working with semantic markup, using less with bootstrap 3 mixins.
First, columns setup:
On a non-semantic html you'd declare the cols on the div class <div class="col-lg-4 col-md-6 col-sm-12 col-xs-12"></div> as example.
As stated on bootstrap documentation you should declare the amount of columns for a given div with the .make-xx-column(#columnms), but, if you want to replicate the non-semantic it's supposed that code would be:
.make-lg-column(4); .make-md-column(6); .make-sm-column(12); .make-xs-column(12);
With this I found that when you are on a big resolution (more than 1200px) and if I have defined .make-lg-column(4); and .make-md-column(6); the result will be the 6 medium columns will be showed. On my inspector it shows as #media (min-width: 992px) and will rule over the #media (min-width: 1200px)
What is then, the correct way to set the different column values for a div? It seems to not be equal to how you'd set them up on a non-semantic layout.
Finally a question about padding,
Why when on the regular bootstrap css the column has a defined padding (15px as default) on the mixins the default padding is 0px? That forces to set the padding each time you declare a column amount (.make-lg-column(12, 30px);) ?
I appreciate if someone can help me working with this the right way, I'm sorry but It's the first time I work with LESS and semantic html code with bootstrap.

I'm sure that this question has an answer on SO already, but for the time being.
You should call the mixins for the smallest grid (xs) first, or better call the mixins from small to width. (kind of mobile first)
The above make sense because of the media queries for the grid are defined with min-width, see also http://getbootstrap.com/css/#grid.
If you set the largest grid first (min-width:1200px) follow by (min-width:992px) then both will evaluate true for screensize wider than 1199 pixels, and so the latest override the first.
You should use:
.make-xs-column(12);
.make-sm-column(12);
.make-md-column(6);
.make-lg-column(4);
Why when on the regular bootstrap css the column has a defined padding
(15px as default) on the mixins the default padding is 0px? That
forces to set the padding each time you declare a column amount
(.make-lg-column(12, 30px);) ?
The default grids have a gutter of 30 pixels (set by #grid-gutter-width) between the columns. 15 pixels on each side of the columns, makes 2 x 15 pixels between each column.
Why when on the regular bootstrap css the column has a defined padding (15px as default) on >the mixins the default padding is 0px? That forces to set the padding each time you declare >a column amount (.make-lg-column(12, 30px);) ?
I found that:
#import "variables";
#import "mixins";
selector {
.make-lg-column(12, 30px);
}
compiles into CSS code as follows:
selector {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
#media (min-width: 1200px) {
selector {
float: left;
width: 100%;
}
}

Bootstrap uses predefined sizing to maintain responsiveness behavior regardless of the screen size. I know you are thinking "1200px is 1200px regardless the screen. But remember we are talking about percentages. So, if you were going to display a gallery with a tiles side to side in a laptop, you'll be fine with:
<div class="col-md-3">picture 1</div>
<div class="col-md-3">picture 2</div>
<div class="col-md-3">picture 3</div>
<div class="col-md-3">picture 4</div>
They will fit just fine and keep a great display. But will that be the case if the split the width of the screen 4 ways in a smartphone? Probably too small, right? In that case, you'll be better off with:
<div class="col-xs-12">picture 1</div>
<div class="col-xs-12">picture 2</div>
<div class="col-xs-12">picture 3</div>
<div class="col-xs-12">picture 4</div>
This way they display accross the entire screen
In summary, ideally, you'd want to do the following:
<div class="col-md-3 col-xs-12">picture 1</div>
<div class="col-md-3 col-xs-12">picture 2</div>
<div class="col-md-3 col-xs-12">picture 3</div>
<div class="col-md-3 col-xs-12">picture 4</div>
Hope that helped

Related

70% and 30% columns with Bootstrap

I got this "test" from a recruiting agency:
Create a page template with two layers, one 70% width and the second
30% of the page; in the first layer there will be the content, in the
second the featured image.
I was wondering if I can achieve those exact percent with Bootstrap even if it's not meant to be used that way.
If you can add your own bootstrap library :
Go to bootstrap cutomizing page:
Set the #grid-columns variable to 10.
Generate your own bootstrap css on clicking on download.
Now your grid is from col-xs-1 to col-lg-10.
To have 70% and 30% :
<div class="row">
<div class="col-xs-10 col-sm-7">70%</div>
<div class="col-xs-10 col-sm-3">30%</div>
</div>
Bootstrap is a framework - so it's a starting point... like a chassis in a car.. you'd want to build on top of it.
To resolve your conundrum start with deciding when, in terms of screen resolution, you want that split to happen. e.g. lets assume small screens (tablets and up).
You'll need one of the framework col's, in the e.g. use .col-sm-4 & .col-sm-8. This establishes the responsiveness of the framework with inherited css like position, min-height, paddin-*.
Then you'll need to override the CSS you want changed. Since we're looking to only show 30/70 on small screen an up we look to the variables.less file (in the Bootstrap source on github).
We find in there that small screens have a media breakpoint at 768px (#screen-sm-min). Now you can build a less file with the variable imported, or just hard code the value in a add-on CSS (as part of your pages own CSS) the following:
#media (min-width: 768px) {
.col-sm-30 { width: 30%; }
.col-sm-70 { width: 70%; }
}
You don't need anything else but width, as the rest will be inherited from .col-md-*
Finally, your code will then use this:
<div class="row">
<div class="col-md-4 col-md-30">...</div>
<div class="col-md-8 col-md-70">...</div>
</div>
Remember, that *md-30 must appear after *md-4 so that the *30 overrides the *4. The override behaviour is driven by the sequence of class definitions, where the last one wins.
Why don't you explicitly define the width for that div.
.thirty {
width: 30%;
display: block;
float: right;
}
.seventy {
width: 70%;
display: block;
float: left;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-4 seventy">Here You can add the content</div>
<div class="col-md-8 thirty">Place for the image</div>
</div>
</div>

how to create margin between bootstrap columns without destroying design?

I have my simple markup
<div class="row">
<div class="col-lg-6 loginField">
data
</div>
<div class=" col-lg-6 loginField">
<div class="">
test
</div>
</div>
</div>
.loginField{
background-color:white;
}
so my problem is that i am getting 1 white line on desktop screen, but i want to make a 10 px space between those 2 columns without destroying responsive design. Right now if i switch to smaller screen it works, but on desctop there are no space, and if i add margin, this margin presist on smaller screens which is ugly.
P.S. when i say it works on smaller screens, i mean that those 2 columns move under each other and width of the white lines are as they shopuld be.
You simply need to mimic the same breakpoints in the responsive design as is in bootstrap.css:
http://jsfiddle.net/G6nWh/4/
CSS:
#media (min-width: 1200px) {
.margin-left-10 { margin-left: 10px; }
}
HTML:
<div class="col-lg-6 loginField">
<div class="margin-left-10">
test
</div>
</div>
If you have changed the breakpoints, you'll need to update that min-width, but this is the default min-width for Bootstrap's large columns.
When the screen gets smaller, the rule stops being applied, so it won't affect your smaller screens.

Mixing natural width and Bootstrap width columns

So I've got a Bootstrap 3 form where I simply want to line up a bunch of spans in a neat row, degrading into a stack on mobile:
From [station1] to [station2] at [time]
From
[station1]
to
[station2]
at
[time]
Obviously I can do this, and it works:
<div class="row">
<div class="col-md-1">From</div>
<div class="col-md-3"><select>...</select></div>
<div class="col-md-1">To</div>
<div class="col-md-3"><select>...</select></div>
...
</div>
However, it looks rather silly if the screen is wide:
From [station1] to [station2] at [time]
If I queue up some spans without the col-X-Y classes, they don't play nice with Bootstrap. And if I try to mix together grid and non-grid spans or divs, they get ordered in weird and mysterious ways as shown in the last two rows of this JSFiddle. Help?
Bootstrap is not the solution to everything. You still have to write your own CSS at times. You can reduce your column widths for larger screens by using the appropriate classes, but that will not improve things much.
Instead, you are better off writing your own CSS. Style your elements to be inline-block, add some margin and padding. If you want to take it a step further you can write your own media queries to handle styles at reduced widths.
Look at line 260 in the variables file in Bootstrap.
#screen-xs: 480px;
#screen-xs-min: #screen-xs;
#screen-phone: #screen-xs-min;
You can use those variables to create viewport specific CSS.
#media (max-width: $screen-xs) {
// Change spans to block
span.my-field {
display: block;
margin-bottom: 10px;
}
}
If you are not using Sass or Less, you can hardcode the values of the variables. For example, 480px instead of $screen-xs.
You could wrap the columns in a smaller width col, such as col-sm-5 or col-sm-6..
<div class="row">
<div class="col-sm-4">
<div class="col-lg-2">From</div>
<div class="col-lg-2"><select><option>station</option></select></div>
<div class="col-lg-2">To</div>
<div class="col-lg-2"><select><option>station</option></select></div>
<div class="col-lg-2">at</div>
<div class="col-lg-2"><select><option>time</option></select></div>
</div>
</div>
Demo: http://www.bootply.com/116599
An alternate approach:
<span>From</span>
<br class="visible-xs visible-sm"/>
<span>...</span>
<br class="visible-xs visible-sm"/>
Looks nasty, but seems to work nice. I haven't found any issues yet.

Twitter Bootstrap: non-responsive row in responsive layout

I'm using a responsive fluid grid system on my site, and in most cases the responsive Bootstrap behaviour is what I want: on small screens, the grid columns become fluid and stack vertically.
However, using grid nesting, inside a nested row this is not always the desired behaviour. There are some rows that are not supposed to be stacked vertically, regardless how small the screen is. This is exactly the behaviour of the whole grid when I completely disable all responsive CSS code, but obviously this is no alternative if the responsive behaviour is required for the outer rows.
The relevant markup is:
<div class="container-fluid">
<div class="row-fluid">
<div class="span6">This column should be stacked on small devices.</div>
<div class="span6">
<div class="row-fluid">
<div class="span6">Nested row. This column should NOT be stacked on small devices.</div>
<div class="span6">Nested row. This column should NOT be stacked on small devices.</div>
</div>
</div>
</div>
</div>
See this jsfidde for clarification.
How would one best solve this problem? Is there a way to do it with the native bootstrap functions?
[class*="span"] .span6 { display: inline-block; width: 48.61878453038674%}
example:
http://jsfiddle.net/NfTQ7/1/
What I have done to solve issues like this is the following:
<div class="row-fluid">
<div id="remove-mobile" class="span6">Nested row. This column should NOT be stacked on small devices.</div>
<div id="remove-mobile" class="span6">Nested row. This column should NOT be stacked on small devices.</div>
</div>
#media only screen and (max-width: 480px) {
#remove-mobile {
display:none;
}
}
That way, you get rid of that whole mess on smaller devices, and you can add code specifically targeted towards mobile sizes by simply doing the opposite:
<div class="row-fluid">
<div id="show-mobile" class="span6">Your Beautiful Code For Mobile Only</div>
</div>
#media only screen and (min-width: 481px) {
#show-mobile {
display:none;
}
}
#media only screen and (max-width: 480px) {
#show-mobile {
display:block;
}
#remove-mobile {
display:none;
}
}
It's not the simplest of solutions but I've found it suits my needs
https://github.com/twitter/bootstrap/blob/master/less/mixins.less#L572
If you dive into the source for bootstraps grid, it's relatively easy to pull out the less code used to generate the span[1-12] system.
So I just pulled out the basics and put them in my own file with a different selector. So now, when I want to use span's that don't wrap I just use .naps[1-12] (Span spelt backwards).
The responsive CSS looks for .span[1-12] selectors so it ignores my .naps elements.
It's not elegant, and it's not particularly scalable. It does work though :-/

Multiple Spans In One Row with Twitter Bootstrap

Using Twitter's Bootstrap's standard 940px fluid grid responsive grid I'm trying to get multiple .span div's in one .row.
I want to show a max of 3 .span's on each internal line that grows with the page. So as more .span's are added they just get added to the .row.
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<div class="span4">1</span>
<div class="span4">2</span>
<div class="span4">3</span>
<div class="span4">4</span> <!-- wrap to a new line-->
<div class="span4">5</span>
</div>
</div>
</div>
The problem I'm facing is that the span4 which wraps to a new line has the inherited left margin. While I can fix this with nth-child() in modern browsers, it obviously still affects IE.
Any ideas how I can achieve this?
I decided to use the nth-child selector to remove the margin on certain .span's. So my final solution looked likes this:
One column of spans for 320px to 979px
Two columns of spans for 980px to 1409px
Three columns of spans for 1409px and up
#media (min-width: 320px) and (max-width:979px) {
/* one column */
.row-fluid .span4 {width:100%}
.row-fluid .span4 {margin-left:0;}
}
#media (min-width: 980px) and (max-width:1409px) {
/* two columns, remove margin off every third span */
.row-fluid .span4 {width:48.717948718%;}
.row-fluid .span4:nth-child(2n+3) {margin-left:0;}
}
#media (min-width: 1410px) {
/* three columns, .span4's natural width. remove margin off every 4th span */
.main .span4:nth-child(3n+4) {margin-left:0;}
}
For IE7 and 8 I set the width of each span to be 48.717948718% (so two per row) in the css - specifically targeting these versions by using html5 bolierplate .oldie html class. I then used Modernizr and a custom test for nthchild found at https://gist.github.com/1333330 and removed the margin for each even span, if the browser does not support the nth-child selector.
if (!Modernizr.nthchildn) {
$('.span4:even').addClass('margless');
}
Your question specifies that you want columns to automatically wrap to the next line, but in Bootstrap's grid system .spans are specifically engineered to work within a .row, that's the grid. You're not using any .rows at all in your code. So my suggestion, if you stay true to the grid, is to have your code look something like this:
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<div class="row">
<div class="span4">1</div>
<div class="span4">2</div>
<div class="span4">3</div>
<div class="span4">4</div> <!-- wrap to a new line-->
<div class="span4">5</div>
</div>
</div>
</div>
</div>
Here is a jsfiddle that shows the OP's example and another for clarity. http://jsfiddle.net/qJ55V/5/
You have to use .row (not .row-fluid) in order to get the inherited styles applied to each column (span). Yes, it's extra markup, but not using .row will unfortunately cause your columns to jumble up.
Probably not the most elegant solution, but I just define a new css class in my custom stylesheet such as:
.margless{
margin:0 !important;
}
Then I apply it to any element that I don't want to have margins. I ran into the same thing using bootstrap and couldn't find an alternative solution.

Resources