dynamically created bootstrap columns with different heights, float to left - css

Consider an unknown number of divs being created dynamically and styled using the bootstrap grid system. In this example, I'm using col-sm-4 so after every third block, we move to a new row. The blocks (divs) can be different heights, which is determined by the content within.
This is where I run into the layout problem. When moving to a new row, I want the fourth block to float to the left. This only happens when the left most div in the row above is also the shortest. I have pictures to illustrate.
Real Life:
The Dream:
The "correct" way to do this would be to wrap every three in a row class I beleive, but I'm not sure how to do this with dynamic content (could probably hack it) or if there's an easy css solution.
HTML:
<div class="row">
<div class="col-sm-12">
<div class="col-sm-4 block">
<div class="inner-block"></div>
</div>
<div class="col-sm-4 block">
<div class="inner-block"></div>
</div>
<div class="col-sm-4 block">
<div class="inner-block" style="height:150px"></div>
</div>
<div class="col-sm-4 block">
<div class="inner-block"></div>
</div>
</div>
</div>
CSS:
.block {
padding: 5px;
}
.inner-block {
height: 200px;
background-color: blue;
}
Plunker Example (expand preview to proper size)

If your system is unable to add first/last classes on every nth div, then you can use the nth-child css pseudo selector.
#media (min-width: 768px) {// For medium displays and above
.col-sm-4:nth-child(3n+1) { // We target every 3rd div but offset the count by 1 so that that 1st, 4th 7th etc divs are cleared
clear:both; // Clear the float
}
}

Related

Why negative margin in .row?

In the Flexboxgrid framework I see a margin of -1rem on the .row class. In small viewports this creates a small horizontal scroll of the container.
Since I've seen this negative margin on other frameworks, what is its purpose? Inner columns have a padding of the same qty, reversed.
In the picture, red line is .container, dashed line is .row. Btw the margin is visible only on the right.
Because you're supposed to use them in combination with columns.
Columns generally have a padding to push the contents of them away from the border, in order to make it look nicer. However, when you are nesting columns within columns, the content keeps getting pushed inwards, which is mostly not a desired effect. To keep this from happening the rows have a negative margin, which pulls the columns back. In your case, it looks like you need to add a col-xs-12 around the column groups within the rows . This will prevent the content from being pulled too far.
Take a look here for a nicely explained introduction.
Here's a demonstration of how the .row class works:
.col1 {
background: red;
}
.col2 {
background: green;
}
body {
font-family: sans-serif;
}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" type="text/css">
<div class="row">
<div class="col-xs-12
col1">
<div class="col-xs-12
col2">
<div class="box">Without a row</div>
</div>
</div>
</div>
<br>
<div class="row">
<div class="col-xs-12
col1">
<div class="row">
<div class="col-xs-12
col2">
<div class="box">With a row</div>
</div>
</div>
</div>
</div>
In general row is placed in container. container has padding of 15 and row has margin of -15

Auto page-break in Bootstrap columns

I am working on a print stylesheet for a web application. The application uses bootstrap. Every page should be printable and as much whitespace should be removed as possible.
My problem involves the following HTML code:
<div class="row">
<div class="col-xs-6">
<div class="line">...</div>
<div class="line">...</div>
<div class="line">...</div>
</div>
<div class="col-xs-6">
<div class="line">...</div>
<div class="line">...</div>
<div class="line">...</div>
</div>
</div>
I have a two column layout and each column features several lines. Is there a way to enable page-break between lines in the columns?
The columns can have a lot of lines and I want to avoid that the whole div is shifted to a new page. Instead I want to have a page-break between the lines of the div.
I think the main problem I am facing is that I have table that is constructed column by column and not row by row like a normal HTML table.
You're right: because this is structured as css columns instead of as a <table>, you won't be able to do this without using a script to heavily modify the DOM.
But the solution isn't too tricky. Let's think about what you want: a grid that #media screen has three rows and on #media print puts each row on its own page. If each row was grouped in a single element, you could use the page-break-after and/or page-break-before CSS properties to put each row on its own page. In your markup each row is
.row .col-x .line
which both gets in the way of your print formatting and isn't semantic. Let's make each row a .row!
#import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
#media print {
.rows-print-as-pages .row {
page-break-before: always;
}
/* include this style if you want the first row to be on the same page as whatever precedes it */
/*
.rows-print-as-pages .row:first-child {
page-break-before: avoid;
}
*/
}
<div class="container rows-print-as-pages">
<div class="row">
<div class="col-xs-6">first row left</div>
<div class="col-xs-6">first row right</div>
</div>
<div class="row">
<div class="col-xs-6">second row left</div>
<div class="col-xs-6">second row right</div>
</div>
<div class="row">
<div class="col-xs-6">third row left</div>
<div class="col-xs-6">third row right</div>
</div>
</div>
(Here the breaks don't go in the right place without a .container. Depending on the rest of you page, the .container may not be necessary.)
Checking #media print styles is a little inconvenient, but you can do it by making a demo in codepen, selecting the "debug" view, and then looking at the print preview or saving as a pdf. Here's a link to the codepen debug view of the above snippet

Bootstrap 3 - Remove guttering

Is it possible to remove the padding from one particular grid within Boostrap 3 -
I need to layout images responsively but the design requires no gaps between columns.
Bootstrap 3 introduced row-no-gutters in v3.4.0
https://getbootstrap.com/docs/3.4/css/#grid-remove-gutters
Yep you can do it by creating a custom style sheet and adding a additional css selector to the col class. [http://www.bootply.com/FtnGzu0dea][1]
/* CSS used here will be applied after bootstrap.css */
.thumbnails {
padding: 0;
}
<div class="wrapper">
<div class="container">
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
</div>
</div>
[1]: http://www.bootp
ly.com/FtnGzu0dea
My suggestion is to add a class for removing the padding at a certain media query width. Here is a test case that uses a header image that should respect the padding at all but the small size. At that point it has no padding and fits the full width of the viewport. I highly recommend using #screen-xs-max if you are compiling LESS source files. It avoids the one pixel jump for media queries that use max-width.
http://jsfiddle.net/jmarikle/htmn5Lov/
CSS
#media (max-width: 767px) { /* replaced with #screen-xs-max if using LESS */
.sm-no-padding [class*=col-] {
padding: 0;
}
}
HTML
<div class="row sm-no-padding">
<div class="col-sm-12">
<img class="img-responsive" src="//placehold.it/2000x1000"/>
Image and/or content in a row where we remove the padding for small screens
</div>
</div>
If you want more granular control with columns rather than at the row level, just apply the class to the columns and change your selector to [class*=col-].sm-no-padding
You can also create a new CSS class and add the following code into your stylesheet.
Custom CSS:
.no-padding > [class*='col-'] {
padding-right:0;
padding-left:0;
}
new CSS to use into your HTML div
.no-padding

On a 768px breakpoint moving the order of right column first and then the left column below

I was able to do the Source Ordering using push and pull method. But what the whole right column comes on top of the left column. What i want to achieve is shown in the attached screenshot. Please guide me if there is a work around where i want the order after a 768px breakpoint
If there is a knonwn height on large-4 , you could use a floatting method and a pseudo element, to push dow the first element in order to leave room for second element.
DEMO:
#media only screen and (max-width: 767px) {
.row:before {
content:'';
float:right;
height:1.2em;
width:0;
margin-left:-0.25em;
}
.large-8 {
clear:right;
float:right;
}
.large-4 {
float:none!important;
}
}
You have the natural flex method if you do not mind leaving aside older browsers: DEMO
#media only screen and (max-width: 767px) {
.row{
display:flex;
flex-direction:column;
}
.large-8 {
order:2;
}
}
Add push/pull classes to reorder the source: http://foundation.zurb.com/docs/components/grid.html? Look under source ordering, in that section there is a good example for what you want to do.
Check the foundation documentation
You should read about source ordering.
Source Ordering
Using these source ordering classes, you can shift columns around between our breakpoints. This means if you place sub-navigation below main content on small displays, you have the option to position the sub-navigation on either the left or right of the page for large displays. Prefix push/pull with the size of the device you want to apply the styles to. medium-push-#, large-push-# is the syntax you'll use. Use large-reset-order to reset pushed or pulled columns to their original position on large screens.
Example:
<div class="row">
<div class="small-10 small-push-2 columns">10</div>
<div class="small-2 small-pull-10 columns">2, last</div>
</div>
<div class="row">
<div class="large-9 large-push-3 columns">9</div>
<div class="large-3 large-pull-9 columns">3, last</div>
</div>
<div class="row">
<div class="large-8 large-push-4 columns">8</div>
<div class="large-4 large-pull-8 columns">4, last</div>
</div>
<div class="row">
<div class="medium-7 small-5 small-push-7 medium-push-5 columns">7</div>
<div class="medium-5 small-7 small-pull-5 medium-pull-7 columns">5, last</div>
</div>
<div class="row">
<div class="medium-6 medium-push-6 columns">6</div>
<div class="medium-6 medium-pull-6 columns">6, last</div>
</div>
Try it in your code, you will see, that columns with "last" named comes first.

Create a user-defined gap between two Bootstrap columns

I want to create little panels/dashboard for my interface. In my case I want to have two panels like so
+-------------------------------+ +-------------------------------+
| | | |
| | | |
+-------------------------------+ +-------------------------------+
Generally it is easy with Bootstrap 3.
<div class="row">
<div class="col-md-5">
</div>
<div class="col-md-5 pull-right">
</div>
</div>
The problem is, the gap of col-md-2, as it is the case here, is way too big. I cannot use a col-md-1 gap, because then both sides do not have an equal size.
I also tried to add padding right and left, but that had not effect, too. What can I do here?
You could add a class which modifies the width of col-md-6. The width of this class is set to 50%. A smaller gap is achieved by reducing the width like so:
.dashboard-panel-6 {
width: 45%;
}
Add this to your div elements. This way the width rule of col-md-6 gets overriden.
<div class="row">
<div class="col-md-6 dashboard-panel-6">...</div>
<div class="col-md-6 dashboard-panel-6">...</div>
</div>
You can use another div inside and give padding to that.
<div class="row">
<div class="col-md-6">
<div class="inner-div">
</div>
</div>
<div class="col-md-6 pull-right">
<div class="inner-div">
</div>
</div>
</div>
.inner-div{
padding: 5px;
}
I posted this here already but it is still relevant the original question.
I have had similar issues with space between columns. The root problem is that columns in bootstrap 3 and 4 use padding instead of margin. So background colors for two adjacent columns touch each other.
I found a solution that fit our problem and will most likely work for most people trying to space columns and maintain the same gutter widths as the rest of the grid system.
This was the end result we were going for
Having the gap with a drop shadow between columns was problematic. We did not want extra space between columns. We just wanted the gutters to be "transparent" so the background color of the site would appear between two white columns.
this is the markup for the two columns
<div class="row">
<div class="col-sm-7">
<div class="raised-block">
<h3>Facebook</h3>
</div>
</div>
<div class="col-sm-5">
<div class="raised-block">
<h3>Tweets</h3>
</div>
</div>
</div>
CSS
.raised-block {
background-color: #fff;
margin-bottom: 10px;
margin-left: 0;
margin-right: -0.625rem; // for us 0.625rem == 10px
padding-left: 0.625rem;
padding-right: 0.625rem;
}
#media (max-width: 33.9em){ // this is for our mobile layout where columns stack
.raised-block {
margin-left: -0.625rem;
}
}
.row [class^="col-"]:first-child>.raised-block {
// this is so the first column has no margin so it will not be "indented"
margin-left: -0.625rem;
}
This approach does require an inner div with negative margins just like the "row" class bootstrap uses. And this div, we called it "raised-block", must be the direct sibling of a column
This way you still get proper padding inside your columns. I have seen solutions that appear to work by creating space, but unfortunately the columns they create have extra padding on either side of the row so it ends up making the row thinner that the grid layout was designed for. If you look at the image for the desired look, this would mean the two columns together would be smaller than the one larger one on top which breaks the natural structure of the grid.
The major drawback to this approach is that it requires extra markup wrapping the content of each columns. For us this works because only specific columns needed space between them to achieve the desired look.
Hope this helps
Here's another possibility:
Live view
Edit view
You will see that it uses 2 col-md-6, each with a nested col-md-11, and you position the nested row in the second div to the right.
The suggestion from Ken has clean HTML which I like. If your left and right panels use elements with widths defined by Bootstrap though (eg wells or form elements) the column padding could cause hassles and break the layout. This nested approach might be easier in this situation.
HTML
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-11">nested row col-md-11</div>
</div><!-- end nested row -->
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-11 col-md-offset-1">nested row col-md-11</div>
</div><!-- end nested row -->
</div>
</div>
</div>
Good luck!

Resources