Explanation about column gutter in Twitter Bootstrap - html

Can anyone explain in detail what this statement about?
Columns create gutters (gaps between column content) via padding. That
padding is offset in rows for the first and last column via negative
margin on .rows.
- http://getbootstrap.com/css/#grid-intro
I need to understand how the gutter calculation working.
Thanks you ^^

Basically, each column's gutter is defined by padding. So, consider the following example:
<div class="row">
<div class="col1"></div>
<div class="col1"></div>
<div class="col1"></div>
</div>
If I wanted a 20 pixels gutter on each column, I could define:
.col1 {
float: left;
width: 200px;
padding-left: 20px;
}
This works well, except my first column will also have a 20 pixel gutter, which I don't want. As a result, I could specify .col1:first-child, but it's much easier to define a negative left margin on the row, thus cancelling the first column's gutter measurement:
.row {
float: left;
margin-left: -20px;
}

Related

Responsive grid with fixed column width

I guess I have the simplest problem ever and cannot find a ready solution.
I need to make a grid with fixed widths and fixed distance between them.
I need x columns a 400px (x = total width/400), and during browser resizing I would need this grid to shrink, column by column (columns must always keep their width size and distance between them).
The content flows over all columns and should spread out over all columns.
That's why I don't like any open source grid system (Boostrap, Skeleton, etc.) they all use %width, and columns always change width on resizing.
What would be the simplest way?
Edit/Clarification:
This is how it looks without columns: http://jsfiddle.net/xjrt8qrm/16/show/
<div>See the fiddle</div>
I want it to have x columns. x is the maximum possible amount of 400px columns, depending on the users resolution. I want only one row of columns, so the content spreads like on a newspaper from top to bottom.
So it will look somehow like this on a PC: http://i.imgur.com/kmd620p.png (You can ignore the text/comments there).
It's pretty simple. The container holds the contents together. Float left will cause them to line up left to right. When the container runs out of space to hold them, they'll drop from the right to a row below one at a time. The clear div clears out the float so that it doesn't propagate to other nearby classes. Obviously, you'll have to handle padding, margins, etc as your style dictates.
If you needed newspaper like vertical layout, you could try a solution like this one
You could use media queries in this manner or even overflow:none to hide columns that didn't fit if that was your desired behavior.
Here's a simple solution:
HTML:
<div class="container">
<div class="fourhundred">
Div 1
</div>
<div class="fourhundred">
Div 2
</div>
<div class="fourhundred">
Div 3
</div>
<div class="clear"></div>
</div>
CSS:
.fourhundred {
width: 400px;
margin: 10px;
float: left;
}
.clear { clear:left }
.container { width: 100% }
This is why flexbox have been designed. Add to your container:
.container {
display: flex;
justify-content: space-between;
align-content: space-between;
width:100%;
}
as in this Fiddle
Simply used width: calc(100% / 3); you can use any value instead of 3. Divided the whole width into 3.
here is the Fiddle Demo
<div id = "main">
<div id ="sub">One
</div>
<div id ="sub">Two
</div>
<div id ="sub">Three
</div>
</div>
CSS Part
#main{
border: 2px solid black;
height:100px;
width:100%;
position: relative;
display:flex;
}
#sub{
border:1px solid red;
width: calc(100% / 3);
height: calc(100% - 40px);
padding:10px;
margin : 5px;
display:inline-block;
}

Do rows need an immediate parent in Bootstrap?

The Bootstrap 3 docs say:
Rows must be placed within a .container for proper alignment and padding.
Does this mean that one of their ancestors should be a container or that their immediate parent should be a container?
Having looked at the examples, I think the former interpretation is correct as containers have fixed widths for specific display sizes:
#media (min-width: 1200px) {
.container {
width: 1170px;
}
...
}
And as such they cannot be placed inside other components (e.g. .panel-bodys).
In other words, is the following correct markup in Bootstrap 3?
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Title</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-6">
Col 1
</div>
<div class="col-xs-6">
Col 2
</div>
</div>
</div>
</div>
It means that one of their ancestors should be a .container.
And your code is correct, as the docs mention:
Note that, due to padding and fixed widths, containers are not
nestable by default.
Some info on why rows need to be inside .container.
Rows have margin-left: -15px; margin-right: -15px. That's because rows should only contain columns, e.g. col-md-12, and those columns have padding-left: 15px; padding-right: 15px. So that negative margin on the row will mean that effectively columns will line up 'flush' with the edges of the grid.
Because of that negative margin, you need to have the .container because it has padding-left: 15px; padding-right: 15px;. Without that, your rows would go off the page.
Full width designs
Of course, if you do wrap everything in .container then you'll have a fixed width which is not right for everyone. So, if you don't want that, you can go against Bootstrap's rules and place your rows inside a parent that has padding: 0 15px to offset the negative margin on rows (the would cause container to go off the screen and cause a scrollbar).
This demo shows both situations described above.
The .container class is responsible for the padding and margins of its children. Hence, whatever content you put inside the containers inherhits those properties unless overridden. There's nothing unusual going on here.
Take a look at the source for further information:
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}

Prevent DIVs from wrapping within parent

I run in to this problem quite often, and it usually results in me spending additional time to try and address the problem. Essentially it is a straightforward layout as follows:
HTML:
<div id="container">
<div id="items">
<div class="item">
(data here)
</div>
<div class="item">
(data here)
</div>
<div class="item">
(data here)
</div>
<div class="item">
(data here)
</div>
-- repeats --
</div>
</div> <-- end container -->
CSS
#container {
margin: 0 auto;
width: 980px;
overflow: hidden;
}
#items {
float: left;
width: 980px;
min-height: 1000px;
}
#items .item {
float: left;
width: 230px;
height: 230px;
margin-right: 20px;
margin-bottom: 20px;
}
My intended result is to have a 4 x 4 grid displaying items. As you can see from my CSS above, I am adding a right margin to each item in order to space them out. The only problem with this is that the fourth item in each row drops down to the next row (which is obviously being caused due to the right margin on the item):
(230 x 4) = 920 + (20 x 4) = 80 = 1000 (but the container width is 980). So instead of 4 items on each row I get three.
If the right margin on every fourth item isn't included then all four items fit perfectly within the constraints of the parent DIV. I know I can just add a separate class for the fourth item and set it's right margin to 0px but this means I have to add additional checks in my scripting when displaying products dynamically.
Ideally what I would like is a pure CSS solution that works well in all major browsers AND IE7. Does anybody know of any?
You could try using percentages rather than fixed widths for your items.
#items .item {
float: left;
width: 23%;
height: 230px;
margin-right: 2%;
margin-bottom: 20px;
}
Fiddle: http://jsfiddle.net/kboucher/Mv7sh/
To target every fourth child of an element you can use :nth-child(x), but that is not supported in IE8 and earlier. w3schools doc
:last-child won't really do it because you would have to wrap every group of four.
However, depending on your design, a width and height of 225 instead of 230 would even out at 980 with the margins.
And unless you have a specific reason to only have margin-right, you could split it into margin-right and margin-left with a value of 10.

How can I have a 2 column layout with one of the columns with a fixed width and the other with the remaining width?

I have a 2 column layout. The left column has a width of 300px. I would like the right column to take up the full width of the remaining monitor space. But I just can't figure out how this mixture of px and % can be made to work? Anyone have any ideas?
I guess at worse I can use js to get the user's viewport width and add some inline styles dynamically but then I would have to perform that on every window resize, etc. So I would much rather have a pure css solution.
I would prefer thirtydot's answer:
Demo fiddle.
Minimum CSS requirement:
#sideBar {
width: 300px;
float: left;
}
#mainContent {
overflow: hidden;
}
One approach is to float the fixed width column over to the left and then use a margin to simulate your other column. Something like this:
<div id="sidebar">
<!-- ... -->
</div>
<div id="content">
<!-- ... -->
</div>
And some CSS:
#sidebar {
float: left;
width: 300px;
}
#content {
margin-left: 300px;
}
A <div> with its default display:block will naturally take up all the available width. The 300px left margin leaves an open space for the fixed width column.
Example: http://jsfiddle.net/ambiguous/wdsbu/
Here is a possible method for you: http://jsfiddle.net/mqchen/RDLMm/

How to make a stable two column layout in HTML/CSS

I want a container with two columns. Details:
The container
Width should adjust to 100% of its parent element (easily accomplished).
Height must adjust to contain both columns (i.e. its height should be exactly equal to the larger height of the two columns, so there is no overflow and scrollbars never show)
Should have a minimum size equal to double the width of the left column.
The columns in general
Should be of variable height, adjusting to the height of their content.
Should be side-by-side, such that their top edges are in line.
Should not break the layout or wrap under each other if even a single pixel of border, padding, or margin is applied to either one, because that would be extremely unstable and unfortunate.
The left column specifically
Must have a fixed, absolute width in pixel units.
The right column specifically
Width must fill the remaining space in the container. In other words...
Width must equal the container width minus the width of the left column, such that if I place a DIV block element inside this column, set its width to 100%, give it a height of something like 10px, and give it a background color, I will see a 10px high colored strip that goes from the right edge of the left column to the right edge of the container (i.e. it fills the right column's width).
Required stability
The container should be able to resize (by resizing the browser window) down to its minimum width (specified earlier) or to a much larger width without breaking the layout. "Breaking" would include the left column changing size at all (remember it's supposed to have a fixed pixel width), the right column wrapping under the left one, scrollbars appearing, block elements in the right column failing to take up the entire column width, and in general any of the aforementioned specifications failing to remain true.
Background
If floating elements are used, there should be no chance that the right column will wrap under the left one, that the container will fail to contain both columns (by clipping any part of the column or allowing any part of the columns to overflow its boundary), or that scrollbars will appear (so I'd be weary of suggesting the use of anything other than overflow:hidden to trigger floating-element containment). Applying borders to the columns should not break the layout. The content of the columns, especially of the right column, should not break the layout.
There seems to be a simple table-based solution to this, but under every circumstance it fails miserably. For example, in Safari, my fixed-width left column will shrink if the container gets too small, rather than maintaining the width I specified. It also seems to be the case that CSS width, when applied to a TD element refers to a minimum width, such that if something larger is placed inside it, it will expand. I've tried using table-layout:fixed; doesn't help. I've also seen the case where the TD element representing the right column will not expand to fill the remaining area, or it will appear to (for example a third column 1px wide will be pushed all the way to the right side), but putting a border around the right column will show that it's only as wide as its inline content, and block-level elements with their width set to 100% do not fill the width of the column, but rather match the width of the inline-content (i.e. the width of the TD seems to be completely dependent on the content).
One potential solution I have seen is too complex; the solution needs to work in IE8, Firefox 4, and Safari 5.
Here you go:
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
.clear {
clear: both;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>
See it in action here: http://jsfiddle.net/FVLMX/
Try this: Live Demo
display: table is surprisingly good. Once you don't care about IE7, you're free to use it. It doesn't really have any of the usual downsides of <table>.
CSS:
#container {
background: #ccc;
display: table
}
#left, #right {
display: table-cell
}
#left {
width: 150px;
background: #f0f;
border: 5px dotted blue;
}
#right {
background: #aaa;
border: 3px solid #000
}
Piece of cake.
Use 960Grids Go to the automatic layout builder and make a two column, fluid design. Build a left column to the width of grids that works....this is the only challenge using grids and it's very easy once you read a tutorial. In a nutshell, each column in a grid is a certain width, and you set the amount of columns you want to use. To get a column that's exactly a certain width, you have to adjust your math so that your column width is exact. Not too tough.
No chance of wrapping because others have already fought that battle for you. Compatibility back as far as you likely will ever need to go. Quick and easy....Now, download, customize and deploy.
Voila. Grids FTW.
Over 11 years later. Apply display:grid to the container and divide the available space by grid-template-columns: 100px 1fr. Where 1fr represents a fraction of 100% of the remaining space.
<html>
<head>
<title>Cols</title>
<style>
#container {
display: grid;
grid-template-columns: 100px 1fr;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
As suggested by mtmurdock it is possible to remove the .clear rule and move it to the pseudo-element #container::after.
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
#container::after {
clear : left;
display: block;
content: '';
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
Another idea is to include the left div in the right div,
which in turn coincides with the line container:
[right][left] ... [/left] ..... [/right]
x { border: thick solid navy; padding: 2px; }
.lineContainer, .container > p {
padding-left: 100px;
margin: 0;
line-height: 1.5;
}
.left, em {
margin-left: -100px;
display:inline-block; box-sizing: border-box; width: 100px;
vertical-align: top;
}
.div-in-div {
display:inline-block; box-sizing: border-box; width: 100%;
vertical-align: top;
}
<h3>Layout: div-left is contained within the right-div / lineContainer</h3>
<pre>
[right][left] … [/left] … [/right]
</pre>
<div class="lineContainer" style="background:floralwhite; "><div class="left">Hello</div>Hello there</div>
<p>Using the above scheme,
we can make old-fashioned typewriter tab stops as shown here.</p>
<h3>The Capital Cities of the UK</h3>
<div class="container" style="background-color: floralwhite; ">
<p><em>England</em> - The capital is London.</p>
<p><em>Scotland</em> - The capital is Edinburgh.</p>
<p><em>Wales</em> - The capital is Cardiff.</p>
<p><em>Northern Ireland</em> - The capital is Belfast.</p>
<p><em>The capital of the UK is</em> - London.</p>
<p><em>Source</em>- Project Britain, capitals.</p>
</div>
<h3>Div in div</h3>
<div class="lineContainer" style="background:floralwhite; ">
<div class="left">Div in container</div><!--No white space here
--><p class="div-in-div" style="background: red; font-size: x-large; margin: auto 0; ">Hello there</p>
</div>