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 :-/
Related
So I have the following desktop layout (which I am completely satisfied with):
This is my attempt to make it mobile:
I like the horizontal scroll here, but I feel that the cards are too thin; I would like to stretch my card to be more box-like (square). Ideally, the card is big enough to fill the gap between the header and the footer without causing
HTML:
<div class="page-content">
<div class="card-deck" fxLayout.xs="row" style="overflow: scroll; height:100%">
<md-card style="width:10rem;" *ngFor="let make of filteredMakes" (click)="goToModels(make.niceName)"
class="page-card mat-card">
<img md-card-image="" src="assets/img/gallery/brands/256/{{make.name}}.png" class="mat-card-image" />
<md-card-subtitle class="mat-card-title text-center">{{ make.name }}</md-card-subtitle>
</md-card>
</div>
</div>
I've tried many css tricks and tried using flexbox, but there must be something I'm missing (media queries perhaps, and how to override them).
How can I make the following styles apply ONLY to mobile?
min-height: 375px;min-width: 278px;
If anyone has any direction on how to accomplish this design, it would be greatly appreciated.
In order to get a different style for mobile, we do this:
#media (max-width: 600px) {
md-card {
min-width:17rem;
}
}
I need to make a multirow column for desktop, and for mobile the layout of the grid will be different. please see the images below.
Desktop Layout
Mobile Layout.
In mobile element B will be first. but for desktop A will be on the right side, spanning two rows. I tried doing this by rearranging the desktop layout using col-md-push-#/col-md-pull-#, but i cant make B and C in the same column/different row and make A span the two rows.
I know i can achieve the desktop layout using nested grids but i cant rearrange the elements using push-pull anymore.
Bootstrap 4—which has support for flexboxes—would be nice but here's one way you could possibly do it without nesting but you'd need to create some custom classes. Here's a demo.
<div class="row">
<div class="pull-sm-right col-sm-6">
<p>B</p>
</div>
<div class="pull-sm-left col-sm-6">
<p>A</p>
</div>
<div class="pull-sm-right col-sm-6">
<p>C</p>
</div>
</div>
And the custom classes you would need are the .pull-*-<location> classes as such:
#media (min-width: 768px) {
.pull-sm-right {
float: right !important;
}
.pull-sm-left {
float: left !important;
}
}
You would need to configure the heights of the divs manually but Bootstrap's float based grid system never really matched the heights of the columns.
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
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.
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.