Automatic layout of block elements - css

I have layout similar to following one:
#first {
height: 100px;
float: left;
}
#second {
height: 200px;
float: left;
}
#third {
height: 100px;
float: left;
}
.column {
background: red;
width: 200px;
margin: 5px
}
<div id="parrent">
<div id="first" class="column">
FIRST
</div>
<div id="second" class="column">
SECOND
</div>
<div id="third" class="column">
THIRD
</div>
</div>
When we have enough space, it looks like that:
This is OK.
When we don't have enough space, it looks like that:
And this is not OK. I don't want this empty space between block 1 and 3.
I want to achieve something like this:
How can i do that?

This is not possible with your code alone - you need to specifiy at least one mediaquery for this:
#media (max-width: 480px) {
#second {
float: right;
}
}
You need to specify the max-width of the media-query according to your needs.

Using only CSS it is not possible to align the divs to take empty space.
If you do not want to leave any empty space then you should go for masonry layout that uses jQuery.
You can read more about it at:
http://masonry.desandro.com/layout.html
I think that's what you are looking for.
But, If you want to align your items in vertical columns then you can use Flexbox:
(This might not be the answer you are looking for but I still wanted to share that there is an option to align columns vertically using flexbox)
DEMO:
http://plnkr.co/edit/zjuveUTson3C6u45nVSH?p=preview
HTML:
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
</ul>
CSS:
ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 306px;
width: 200px;
}
li {
width: 100px;
height: 100px;
background:red;
color: white;
text-align: center;
font-size: 50px;
line-height: 100px;
font-weight: bold;
border: 1px solid white;
list-style: none;
}
DEMO:
http://plnkr.co/edit/zjuveUTson3C6u45nVSH?p=preview

Changes in your second style may it help you
#first {
height: 100px;
float: left;
}
#second {
float: right;
height: 200px;
margin-right: 190px;
}
#third {
height: 100px;
float: left;
}
.column {
background: red;
width: 200px;
margin: 5px
}
<div id="parrent">
<div id="first" class="column">
FIRST
</div>
<div id="second" class="column">
SECOND
</div>
<div id="third" class="column">
THIRD
</div>
</div>

Related

Use flexbox to wrap elements within flex elements to the next line

I have a flexbox which contains "product boxes", which themselves contain thumbnails of the product. Is there a way I can wrap the thumbnails to the next line if the product box runs out of space on that line? I might have 10+ thumbnails per product so it might even need to run to the next two lines if needed, but they should still be "inline" with the reset of the products and not line-break at their beginning and end.
I don't have to use flexboxes, but I assume they might be useful for something like this. However I cannot figure this one out. Thanks!
.products {
display: flex;
background: yellow;
}
.product {
flex: 1;
margin: 1em;
background: magenta;
}
.thumbnail {
display: inline-block;
margin: 1em;
width: 100px;
height: 40px;
background: blue;
}
<div class="products">
<div class="product">
<div class="thumbnail"></div>
<div class="thumbnail"></div>
<div class="thumbnail"></div>
</div>
<div class="product">
<div class="thumbnail"></div>
<div class="thumbnail"></div>
<div class="thumbnail"></div>
</div>
</div>
What happens:
What I would like to happen:
With a few smaller adjustments you can achieve that, where to not group the thumbnails and use a wrapper to compensate for the top margin.
.products {
background: yellow;
}
.wrapper {
display: inline-flex; /* avoid collapsed margin on parent element */
flex-wrap: wrap;
margin-top: -15px; /* so margin only affect second row */
}
.products a {
padding: 1em;
margin-top: 15px;
background: magenta;
}
.products a:nth-child(3n) { /* target every 3rd element with a right margin */
margin-right: 15px;
}
.thumbnail {
width: 100px;
height: 40px;
background: blue;
color: white;
}
<div class="products">
<div class="wrapper">
<div class="thumbnail">1</div>
<div class="thumbnail">2</div>
<div class="thumbnail">3</div>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<div class="thumbnail">6</div>
</div>
</div>
As you mentioned in a comment, where the amount of thumbnails is arbitrary, it might not be practical to use nth-child to create the gap between the elements to be viewed as a group.
Based on that fact, and assumed you generate these thumbnails dynamically, you can either use a space element, or like below, add the margin inline.
.products {
background: yellow;
}
.wrapper {
display: inline-flex; /* avoid collapsed margin on parent element */
flex-wrap: wrap;
margin-top: -15px; /* so margin only affect second row */
}
.products a {
padding: 1em;
margin-top: 15px;
background: magenta;
}
.thumbnail {
width: 100px;
height: 40px;
background: blue;
color: white;
}
<div class="products">
<div class="wrapper">
<div class="thumbnail">1</div>
<div class="thumbnail">2</div>
<a style="margin-right: 15px" href="#"><div class="thumbnail">3</div></a>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<a style="margin-right: 15px" href="#"><div class="thumbnail">6</div></a>
</div>
</div>
Removed the two .product
then wrapped each thumbnail in an inline-block
the inline-blocks have a -2.5px left and right margins so they appear to belong to the same container when inline.
the outer block is display:table
every 3rd thumbnail has a .5em right margin (as suggested by LGSon)
Demo
*,
*::after,
*::before {
margin: 0;
padding: 0;
border: 0;
}
main {
display: table;
table-layout:fixed;
padding: .5em;
background: yellow;
}
b {
display: inline-block;
padding: 8px;
margin: 10px -2.5px;
background: magenta
}
.thumbnail {
width: 100px;
height: 40px;
background: blue;
}
main>div>b:nth-of-type(3n) {
margin-right: .5em
}
<main>
<div class="products">
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
<b><div class="thumbnail"></div></b>
</div>
</main>

How to split a column in a responsive view using Bootstrap?

I'm using Bootstrap v4 alpha4
Currently I have:
.row
.col-xs-12.col-md-8
div A
.col-xs-12.col-md-4
div B
div C
For the xs layout, I'd like the div order to be:
Div B
Div A
Div C
I have no idea how to do this or how to even ask about it. I'm not a front-end dev so I don't know what things are called.
We can change the HTML to whatever we want. It does not have to stay like it is now.
Bootstrap does have column ordering classes, but in this case you can simply use the responsive float classes..
<div class="row">
<div class="col-md-4 pull-md-right">
b
</div>
<div class="col-md-8">
a
</div>
<div class="col-md-4">
c
</div>
</div>
http://www.codeply.com/go/XL5zJELyLD
So using the classes from bootstrap and some general style you can achieve that like I did in this pen.
http://codepen.io/TunderScripts/pen/PGadpr
The Html:
<div class="row">
<div class="col-xs-12 col-md-4 pull-right col1"></div>
<div class="col-xs-12 col-md-8 pull-left col2"></div>
<div class="col-xs-12 col-md-4 pull-right col3"></div>
</div>
the css:
.col1{
background: red;
height: 200px;
}
.col2{
background: blue;
height: 600px;
}
.col3{
background: green;
height: 200px;
}
You can change the default behavior by using their classes for floats(pull-left, pull-right).
Instead of flexbox, I used combination of float and position css properties to get the expected result. Assuming large width as 150px and small width as 100px.
Working Fiddle
.container {
width: 250px;
position: relative;
}
.blue {
width: 150px;
height: 300px;
background: blue;
position: absolute;
}
.pink {
width: 100px;
height: 100px;
background: pink;
float: right;
}
.green {
width: 100px;
height: 100px;
background: green;
clear: right;
float: right;
}
#media (max-width: 450px) {
.blue {
position: relative;
}
.green,
.pink {
float: none;
width: 150px;
}
}
<div class="container">
<div class="pink"></div>
<div class="blue"></div>
<div class="green"></div>
</div>
As promised, a simple draft
HTML
<div class="row">
<div class="col1">DIV A</div>
<div class="col2">DIV B</div>
<div class="col3">DIV C</div>
</div>
CSS
.row {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
width: 400px;
margin: 0 auto;
}
.col1 {
width: 200px;
height: 400px;
background-color: #86a0ff;
}
.col2 {
width: 150px;
height: 150px;
background-color: #ff6cde;
}
.col3 {
margin-top: -200px;
margin-left: auto;
width: 150px;
height: 150px;
background-color: #35af6d;
}
#media (max-width: 768px) {
.row {
justify-content: center;
flex-direction: column;
}
.col1 {
order: 2;
width: 200px;
margin-top: 50px;
}
.col2 {
order: 1;
width: 200px;
}
.col3 {
order: 3;
width: 200px;
margin-top: 50px;
margin-left: 0;
}
}
As for explanation, here is a great guide to flexbox. The main idea in my example is that by using order property you can manipulate the order in which blocks are displaying. The main plus of using flexbox is that you won't need to load any library(such as Bootstrap) to achieve the desired result, such as responsiveness. And it also has a good browser support, unless you need to support older versions of browsers. I hope my answer will be helpful for you!

Sidebar on the left of the content but after in the dom tree

I need to put a sidebar on the left of the content.
I had this html:
<div class="sidebar"></div>
<div class="content"></div>
and I solved using:
.sidebar{
width: 280px;
float: left
}
.sidebar + .content{
margin-left: 300px
}
For this example: https://jsfiddle.net/VixedS/fcx2aLLa/
But now my that .content comes before the .sidebar,
<div class="content"></div>
<div class="sidebar"></div>
how can I obtain the same result just using css?
I don't want to loose the remaining space of the body for the width of .content with or without .sidebar.
So please remember that before saying to float the .content to right. Also, I don't know which page has a .sidebar.
This solution is very powerfull. Works for every browser, any device. Also a great way for responsive design and for a third column.
Update:
.container {
overflow:auto;
}
.sidebar {
width: 280px;
float: left;
background: #EEE;
margin-left: -100%;
}
.content {
float: left;
width: 100%;
}
.center {
margin-left: 280px;
}
.container > div:only-child > div.center {
margin-left: 0;
}
<div class="container">
<div class="content">
<div class="center">
Spaghetti
</div>
</div>
<div class="sidebar">
Pizza
<br /> Hobby
</div>
</div>
Do following way. Use float:right to sidebar and display:table to it's parent.
body {
display: table;
}
.content {
float: right;
}
.sidebar{
width: 280px;
float: left;
background:#EEE; // just for this example
}
.sidebar + .content{
margin-left: 300px
}
<div class="content">Spaghetti</div>
<div class="sidebar">Pizza <br /> Hobby</div>
Flexbox...means you don't have to use floats...and you can re-order the elements as you require.
Support is IE10 and up.
body {
display: flex;
}
.sidebar {
width: 280px;
background: #aaa; // just for this example
order: 0;
}
.content {
flex: 1;
order: 1;
background: plum;
}
<div class="content">
Spaghetti</div>
<div class="sidebar">Pizza
<br />Hobby</div>

CSS Divs not aligned correctly

I feel like this is such an idiotic question, and the little things in css always get me. Anyway, I have a design, and I'm trying to do 2 columns. One (which is a sidebar of 300px) which is at the right, and the other column should fill the remaining space.
As you can see the sidebar is put under the div on the left.
HTML:
<div class="wfix"><div class="col-fix">
<div class="col-lg">
<!--
<div id="block">
<bh>Homepage</bh>
<detail id="test">Loading...</detail>
</div>
-->
</div>
<div class="col-side">
</div>
</div></div>
CSS:
.wfix{ margin-left: 5em; margin-right: 5em; }
.col-fix {
display: table;
width: 100%;
table-layout: fixed;
}
.col-lg, .col-side {
color: #999;
margin: 0;
padding: 0;
}
.col-lg {
margin-left: 0;
margin-right: 300px;
padding-top: 0px;
display: block;
vertical-align: top;
background-color: blue;
min-height: 500px;
}
.col-side {
width: 300px;
float: right;
padding-top: 0px;
display: block;
vertical-align: top;
background-color: red;
min-height: 500px;
}
thanks for any help, Jake.
Floating elements should appear first in the html:
<div class="wfix">
<div class="col-fix">
<div class="col-side"></div>
<div class="col-lg"></div>
</div>
</div>
Demo

Two columns inside container

What I want to do is have a <div> with a container class and a fixed width, holding a <div> with the block class to prevent other content encroaching on any uneven blank space, then two columns (<div>'s) side-by-side inside the block, and to be 50% of the width of the block.
When I create this, I get what appears to be a margin after the first block, which I do not want. I want the block to pack up tight, no margins.
I have an example here of what I have so far, and here if the code:
<html>
<head>
<title>Columns</title>
<style>
div {
margin: 0;
padding: 0;
}
.container {
background: #DDD;
width: 1200px;
margin: 0 auto;
padding: 2% 0;
}
.block {
background: #555;
width: 100%;
display: block;
}
.col {
width: 49%;
display: inline-block;
background: #333;
}
</style>
</head>
<body>
<div class="container">
<div class="block">
<div class="col left">
<h1>Left</h1>
</div>
<div class="col right">
<h1>Right</h1>
</div>
</div>
</div>
</body>
</html>
Your problem is being causes by inline-block, using this makes a space appear inbetween.
Try using float:left to get around this:
See on jsFiddle
.col {
width: 50%;
float: left;
box-sizing: border-box;
background: #333;
}
Note that I added, box-sizing:border-box; this means when you use padding it will be included in the width, not on top of it. Effectively enabling the use of it without an extra inner div.
Remember to include a clear fix afterwards also to "clear" the floats.
CSS
.clear {
clear:both;
}
HTML
<div class="block">
<div class="col left">
<h1>Left</h1>
</div>
<div class="col right">
<h1>Right</h1>
</div>
<div class="clear"></div>
</div>
Try replacing these classes:
.block {
background: none repeat scroll 0 0 #555555;
display: block;
overflow: auto;
width: 100%;
}
.col {
width: 49%;
float: left;
background: #333;
}
.container {
background: #DDD;
width: 900px;
margin: 0 auto;
padding: 30px 30px 30px 30px;
}
.block {
background: #555;
width: 100%;
display: block;
}
.block:after {
content: "";
display: table;
clear: both;
}
.col {
width: 50%;
float: left;
background: #333;
}

Resources