I'm building a layout using Bootstrap 3 grids that should stack as follows:
Desktop:
1 | 2
1 | 2
- | 2
3 | 2
Mobile:
1
1
-
2
2
2
2
-
3
On another post I found a solution that floats the box2 to the right so that the grids stack correctly on the desktop. However, that only works when box2 is higher than box1. If it is not, box3 will show below box2 instead of box1. Is there any other way to stack these boxes as visualized above? All three boxes can have different heights and contain any number of lines of text, images, tables, etc.
http://jsfiddle.net/G9WPv/
This is very possible with CSS, and you can do this with Bootstrap's grid layout. In terms of solving this, you need to exploit the properties of right vs left float.
Demo: http://www.bootply.com/l0Flnma2Im
Consider the following sample. You'd expect this to show up 100% as intended on xs viewports, because each would be 100% width in the order you want. And, you'd expect it to show up as intended on md/lg browsers as well with the 1/3 on the left, but 2 on the right.
<div class="col-xs-12 col-md-6">
<div>1<br>1</div>
</div>
<div class="col-xs-12 col-md-6 pull-right">
<div>2<br>2<br>2<br>2<br>2</div>
</div>
<div class="col-xs-12 col-md-6">
<div>3</div>
</div>
Now, the only issue that arises is when the "1" block expands larger than the "2" block. When this happens, 3 appears on the right. Why is this happening? It happens because the float is simply trying to fill in the empty gap on the right. However, we can force it to always be on the left by using clear: left; to ensure nothing appears to the left of it.
.always-left {
clear: left;
}
The code now becomes:
<div class="col-xs-12 col-md-6">
<div>1<br>1</div>
</div>
<div class="col-xs-12 col-md-6 pull-right">
<div>2<br>2<br>2<br>2<br>2</div>
</div>
<div class="col-xs-12 col-md-6 always-left">
<div>3</div>
</div>
This is very possible to do using just media queries and some absolute positioning.
Look at this fiddle
You need to wrap your 3 divs inside a container.
essentially your css will look something like this.
.container {
width: 100%;
position: relative;
}
#box1 {
background-color: #d7d7d7;
width: 100%;
}
#box2 {
background-color: #e7e7e7;
width: 100%;
position: relative;
}
#box3 {
background-color: #f7f7f7;
width: 100%;
}
#media screen and (min-width: 700px) {
#box1, #box3 {
width: 40%;
}
#box2 {
width: 60%;
position: absolute;
top: 0;
right: 0;
}
}
The boxes can be of any size and on a mobile size screen they will stack in the correct order.
of course with the bootstrap gird system there might be a little tweaking involved to get it just right... but this is the essence of it.
Peace.
Related
THE ISSUE
I need to do something I thought would be fairly common, yet I've been unable to find any definitive answers on how to go about it. It might be that I don't know the correct terms to search for, such as what one calls it when rows in a column "stack" under each other responsively.
WHAT I WANT TO ACHIEVE
Have a row with four columns with min widths of say 200px, and width of 25% of parent container. The end result should always be horizontally centered (which I can't really show in my below examples, but I trust it's easy enough to imagine).
|| COL-1 | COL-2 | COL-3 | COL-4 ||
Once the parent container is less than 991px, I want the columns to stack, in pairs. However, in most coding examples I've found online, typically what happens is this:
|| COL-1 | COL-2 | COL-3 |
| COL-4 ||
What I need is that there's always an even number of rows, and the image inside each cell resize as the cells resize.
Such as:
COL-1 COL-2 COL-3 COL-4
or break-point 1 (contents centered)
COL-1 COL-2
COL-3 COL-4
or break-point 2 (contents centered)
COL-1
COL-2
COL-3
COL-4
WHAT I'VE DONE SO FAR
After much searching (had to get my search terms right!) I found an example of what I want to do, but there was only text in the boxes. Once I throw an image into the mix (one image per cell), two issues occur. 1) The images are not responsive in their size, and they should be. 2) Before the stacking goes to 2x2 it first goes to 1x3 + 1x1 (the same issue I show in my ascii layouts above).
I've set up a CodePen of the original code here. It works just as I require, but not with images.
And there's a CodePen of my attempt to add in images here.
My attempted code is:
:root {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
/* mobile phone */
.flex-container {
display: flex;
flex-wrap: wrap;
max-width: 1400px;
margin: 0 auto;
border: 1px solid red;
padding: 1em;
}
.flex-item-1 {
background: indianred;
}
.flex-item-2 {
background: blue;
}
.flex-item-3 {
background: tomato;
}
.flex-item-4 {
background: coral;
}
.flex-item {
flex: 100%;
height: auto;
text-align: center;
}
/* tablet */
#media screen and (min-width: 675px) and (max-width: 960px) {
.flex-item {
flex: 1 0 19em;
}
.flex-item:nth-child(2n) {
margin-left: 1em;
}
}
/* desktop */
#media screen and (min-width: 960px) {
.flex-item {
flex: 1 0;
}
.flex-container > * + * {
margin-left: 1em;
}
}
<body>
<div class="flex-container">
<div class="flex-item flex-item-1">
<img src="https://picsum.photos/300/300">
</div>
<div class="flex-item flex-item-2">
<img src="https://picsum.photos/300/300">
</div>
<div class="flex-item flex-item-3">
<img src="https://picsum.photos/300/300">
</div>
<div class="flex-item flex-item-4">
<img src="https://picsum.photos/300/300">
</div>
</div>
</body>
(I can't figure out how to make the RESULT panel in Stackoverflow "Code Snippets" wide enough to see the stacking effect of this code, so the Codepen examples would need to be viewed to see that).
MY QUESTION
How can I get the intended outcome, of the image sizes also being responsive, down to a specified min-width limit (e.g., 200px), and the columns still stacking evening just as they do before the images were introduced into the code?
I want to make a table with space between columns, on a background, like this :
And when I resize my page the text should not exit from box
#banner {
background-color: red;
margin-top: 70px;
background-size: cover;
height: 455px;
margin-left: 35px;
margin-right: 35px;
overflow: hidden;
}
.r1c1 {
float: left;
overflow: hidden;
width: 90%;
}
.r2c1 {
float: left;
overflow: hidden;
}
<div id="banner">
<div class="r1c1">
<h2>Once you've experienced the pleasure and comfort of hydronic heating, there's no going back.</h2>
</div>
<div class="r2c1">
<img class="voucher1" src="voucher1.png">
</div>
</div>
If you actually want to use a table, I would suggest using the <table> element directly. If instead you're making something like the display in your attached image, I have a few suggestions:
try using margins to keep the table cells separated
try placing a container div around your text and controlling its size to create the appearance that the cells have spaces between them.
try using Twitter Bootstrap. It's open source and fantastic and very easy to use. It has presets for a ton of different elements. Making what you want would be as simple as:
<div class="col-lg-5 col-md-5" id="r1c1"><div>
<div class="col-lg-2 col-md-2" id="spacer"><div>
<div class="col-lg-5 col-md-5" id="r2c1"><div>
Without having to further define the col-lg and col-md classes, you've taken advantage of bootstraps grid system and created a scalable table. Hope that helps!
I'm creating an image gallery for a website. The images appear as a grid : there are 3 images on every line when I open the page on my computer, but I may get more or less depending on the width of the window. This doesn't look bad at all, but I would like to improve it, so that it shows only two images, or just one per row, depending on the screen size. I could use media queries, but I only have bad memories about them and I would like to avoid using them if possible. Here is what my HTML looks like :
<div id="image_container">
<div style="background: url("image 1 url") center center no-repeat"></div>
<div style="background: url("image 2 url") center center no-repeat"></div>
(....)
<div style="background: url("image x url") center center no-repeat"></div>
<span style="display:block; clear: both;"></span>
</div>
and the CSS :
#image_container{
width: 95%;
margin: 5% auto;
border-radius: 10px;
border: 1px solid grey;
}
#image_container>div{
float: left;
width: 290px;
height: 164px;
margin: 2px;
overflow: hidden;
border-radius: 5px;
}
Thanks
The cheap way to do it is to change this in #image_container>div:
width: 100%;
max-width: 290px;
This trick will ensure that on too-small screens, the image will only take up the screen width and not the specified 290px.
Now you need to keep the aspect ratio. To do that, first calculate it: 164/290 = 56.55%. Take this value, remove the height from your styles, and add this:
#image_container>div:before {
display: block;
content: '';
padding-top: 56.55%;
}
This will give aspect ratio to your box, due to the clever trick that padding-top is a percentage of the parent element's width (and pseudo-elements are children of their main element).
With these combined, your boxes will stay the same shape but just get smaller if there isn't enough room.
That said, two points for you:
Media queries aren't all bad. Maybe you were just doing something not quite right with them. I would suggest looking into them again, as they are very powerful.
Generally the smallest width you need to worry about is 320px, the width of an iPhone. I haven't yet encountered a smaller screen than that, so your 290px boxes should be fine anyway.
If you're willing to use a framework like Bootstrap, you could use its grid system to get pretty much what you're looking for without doing the media queries yourself. You would just need markup like this:
<div id="image_container">
<div class="col-sm-6 col-md-4 col-lg-3"><!-- Image --></div>
<div class="col-sm-6 col-md-4 col-lg-3"><!-- Image --></div>
<div class="col-sm-6 col-md-4 col-lg-3"><!-- Image --></div>
<div class="col-sm-6 col-md-4 col-lg-3"><!-- Image --></div>
</div>
As long as the number of images displayed on each row is a factor of 12 (1, 2, 3, 4 or 6), then you'll always have complete rows.
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.
I'm making a website and want it to appear as a grid of boxes and rectangles.
I have a 6x6 grid of relatively-alined left-float divs. They work fine and fit neatly in a 900 width wrapper div. If i want a horizontal rectangle, i simply make one of these squares twice as wide (accounting for margins between, but that's irrelevant) and delete the one next to it. No problem.
The issue I have comes in when I want to make a rectangle twice as TALL. it ends up bumping everything left of it in the same row as it a line down. The same happens with a square twice as large (2x2 grid units).
Here's the code in jsfiddle:
http://jsfiddle.net/zucw9/
Essentially, how can I get either 8,9, and 10 to shift up one space, or for 6,7, and 8 to move into that gap, leaving 9 and 10 where 6 and 7 are right now?
http://jsfiddle.net/zucw9/10/
This solution isn't a very good solution but it works.
(I changed some of the names so i could read it better. (.grid_rect_tall became .grid_tall etc. margin-left:10px; margin-right: 0px etc.. became margin: 5px;)
basically you specify a -ve margin-bottom for the tall one and an extra margin so the other elements don't overlap.
.grid_square, .grid_long, .grid_tall
{
float: left;
margin: 5px;
background: #6CC;
}
#main{
position: relative;
width: 905px;
overflow: hidden;
border: 1px solid black;
padding: 5px;
}
.grid_square{
width: 140px;
height: 140px;
}
.grid_long{
width: 290px;
height: 140px;
}
.grid_tall{
width: 140px;
height: 290px;
margin-bottom: -150px;
}
.rbuffer
{
margin-right: 155px;
}
.lbuffer
{
margin-left: 155px;
}
I'd still go with my comment though and use either: http://960.gs or css3 grid layout: http://w3.org/TR/css3-grid-layout
EDIT:- I thought i better put a why to my comment earlier that this is not a good solution. Simply put: if you want to change the layout of the page you will have to change the classes on the items as well as having to change the css.
Also created one with even more elements to show the possibilities: http://jsfiddle.net/zucw9/11/ (or in em instead of px because i was bored. http://jsfiddle.net/zucw9/15/)
The layout is standard, how it should be displayed. I would recommend to use another div which wraps up the dives that appear before the taller div. This is not a very flexible solution though.
Edit: Move
<div class="grid_square">8</div>
<div class="grid_square">9</div>
<div class="grid_square">10</div>
higher in hierarchy after
<div class="grid_square">2</div>
should fix it.
i hope your thinking like below
code:
<div id="main">
<div class="grid_square">1</div>
<div class="grid_rect_long">2</div>
<div class="grid_rect_tall">3</div>
<div class="grid_square">4</div>
<div class="grid_square">5</div>
<div style="clear:both"></div>
<div>
<div class="grid_square">6</div>
<div class="grid_square">7</div>
<div class="grid_square">8</div>
<div class="grid_square">9</div>
<div class="grid_square">10</div>
</div>
</div>