CSS3 columns with one smaller - html

I want to separate my page into a few columns. Actually I need only three but I may need a few more later.
So I used this:
<style>
.container {
display: flex;
}
.column {
flex: 1;
/*for demo purposes only */
background: #f2f2f2;
/*border: 1px solid #e6e6e6;*/
box-sizing: border-box;
padding-left: 100px;
padding-right: 100px;
padding-top: 50px;
text-align: center;
}
.column-one {
order: 1;
}
.column-two {
order: 2;
}
.column-three {
order: 3;
}
</style>
So my page is perfectly separated in three distinct and equal columns. But I want the second smaller than the others (50%).
I already tried to reduce the width of .column-two class but it did not work.
Is it possible to do this with this king of code ?
I really like this structure because if I have to add one more column I do not have to change the whole CSS. That is why I want to keep this code.

.container {
display: flex;
min-height: 200px;
}
.column {
background: #f2f2f2;
border: 1px solid black;
margin: 3px;
}
.column-one {
flex: 1;
}
.column-two {
flex: 0.5;
}
.column-three {
flex: 1;
}
<div class="container">
<div class="column column-one"></div>
<div class="column column-two"></div>
<div class="column column-three"></div>
</div>
If You want to use four column later then.
.column-one {
flex: 1;
}
.column-two {
flex: 0.5;
}
.column-three {
flex: 0.5;
}
.column-four {
flex: 1;
}

If you add flex: 1 to column-two and flex: 2 to other two columns, column-two will be half width or 50% width of other two column. Also you don't need to use order if you are not going to change it.
.container {
display: flex;
min-height: 100vh;
flex-direction: row;
}
.column {
/*for demo purposes only */
background: #f2f2f2;
/*border: 1px solid #e6e6e6;*/
box-sizing: border-box;
padding-top: 50px;
text-align: center;
border: 1px solid black;
margin: 5px;
}
.column-one {
flex: 2;
}
.column-two {
flex: 1;
}
.column-three {
flex: 2;
}
<div class="container">
<div class="column column-one"></div>
<div class="column column-two"></div>
<div class="column column-three"></div>
</div>

Related

Align items 2/3rd through div?

I have the following code in react:
.alignHorizontally {
display: flex;
}
.firstTitle {
align-items: center;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
.secondTitle {
margin-left: 80px;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
/* added by editor for demonstration purpose */
.alignHorizontally > * {
box-sizing: border-box;
}
.firstTitle {
border: 2px dashed red;
}
.secondTitle {
border: 2px dashed blue;
}
<div class="alignHorizontally">
<div class="firstTitle">Title
</div>
<div class="secondTitle">
Second title
</div>
</div>
I want the first div(firstTitle) to be on the far left hand side and the second div (secondTitle) to be about 2/3rds of the way through the screen. I know I can force this by adding padding-left: 100px but it feels ugly. Is there a nice way of doing this?
You can also use justify-content: space-between in your alignHorizontally class or try any of the other justify-content parameters that most closely match the layout you want.
.alignHorizontally {
display: flex;
justify-content: space-between;
}
.firstTitle {
align-items: center;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
.secondTitle {
margin-left: 80px;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
/* added by editor for demonstration purpose */
.alignHorizontally > * {
box-sizing: border-box;
}
.firstTitle {
border: 2px dashed red;
}
.secondTitle {
border: 2px dashed blue;
}
<div class="alignHorizontally">
<div class="firstTitle">Title
</div>
<div class="secondTitle">
Second title
</div>
</div>
It's not in English but it was the best tutorial I've seen so far about aligning items with CSS grid.
Alura's example justify-content CSS grid
https://www.alura.com.br/artigos/css-guia-do-flexbox
Add .secondTitle { width: 33%; } to occupy 1/3 of the space which means it will occupy 1/3 of the space.
with margin-left: auto you can push it then to the right to occupy that 1/3 at the right space.
Alternativly you could give the first div a width of 66% directly.
/* original CSS */
.alignHorizontally {
display: flex;
}
.firstTitle {
align-items: center;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
.secondTitle {
margin-left: 80px;
display: flex;
margin-top: 16px;
word-spacing: 2px;
line-height: 1;
}
/* CSS Chanegs !!! */
.secondTitle {
width: 33%;
margin-left: auto;
}
/* added by editor for demonstration purpose */
.alignHorizontally > * {
box-sizing: border-box;
}
.firstTitle {
border: 2px dashed red;
}
.secondTitle {
border: 2px dashed blue;
}
<div class="alignHorizontally">
<div class="firstTitle">Title
</div>
<div class="secondTitle">
Second title
</div>
</div>
.grid-container {
display: grid;
grid-template-columns: auto auto auto; // setting three columns in our grid layout
}
.grid-item2 {
grid-column-start: 3; // setting second div to start and end in 3d column
grid-column-end: 3;
}
<div class="grid-container">
<div class="grid-item1">Title #1</div>
<div class="grid-item2">Title #2</div>
</div>

Display content in between two div elements via CSS [duplicate]

This question already has answers here:
Fill the remaining height or width in a flex container
(2 answers)
Closed 2 years ago.
I'd like to display some "dots" in between a label and a price, like this:
from..........£2,000.49
total........£20,000.00
However, the dots must "adapt/reduce/increase", if the length of the price increases. (Like in the example above), as the prices are dynamic and not static/hardcoded.
I thought I would try this with flex. I have a working example below, where I have two columns, in two rows.
There is no width on the .price-big class, so the width of these divs increases/decreases, with the length of the numbers.
I am then adding the dots to the label class. However, this then pushes my divs onto separate lines/stacked, like in the example below.
.label {
content: ".............................................";
}
Any ideas on how to achieve this, would be helpful as I'm kinda getting stuck on this one.
Thank you,
Reema
.main {
display: flex;
flex-wrap: wrap;
align-items: baseline;
border: 1px solid green;
width: 200px;
}
.label {
font-size: 14px;
/* flex: 0 50%; */
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
/* width: 100%; */
text-align: left;
font-size: 14px;
}
.label:after {
content: ".............................................";
}
.price-big {
flex-basis: 0;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: right;
font-size: 20px;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>
You may combine float and flex to modify the formating context layout of the non floatting element and use a pseudo to fill that empty space inside it:
your CSS code modified :
.main {
/*display: flex;
flex-wrap: wrap;
align-items: baseline;*/
border: 1px solid green;
width: 200px;
overflow:hidden; /* because of the float label */
}
.label {
font-size: 14px;
/* flex: 0 50%;
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1; */
border: 1px red solid;
/* width: 100%;
text-align: left;*/
font-size: 14px;
margin-top:0.4em;
float:left;
clear:left;
}
.price-big {
border: 1px red solid;
font-size: 20px;
display:flex;
}
.price-big:before {
content:'';
border-bottom:dotted;
margin-bottom:0.2em;
flex-grow:1;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>
Omg, I literally figured out the answer one minute after posting this. I added overflow: overlay; to the label class:
.label {
font-size: 14px;
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: left;
font-size: 14px;
overflow: overlay; <--- added this
}
.main {
display: flex;
flex-wrap: wrap;
align-items: baseline;
border: 1px solid green;
width: 200px;
}
.label {
font-size: 14px;
/* flex: 0 50%; */
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
/* width: 100%; */
text-align: left;
font-size: 14px;
overflow: overlay;
}
.label:after {
content: ".............................................";
}
.price-big {
flex-basis: 0;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: right;
font-size: 20px;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>

How to fix display flex with percent width columns 1px gap?

On specific width display flex columns with percent width leave one 1px gap
http://prntscr.com/gyhatt
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>
fiddle
I have already tried setting the grid-33 at 33.3334% and it does not work plus it is not useful since I am working with a framework and cant "nudge" specific columns to fix an actual layout issue. I was hoping that flex box dimensions would be like display table where px are rounded up but seems like that is not the case.
Any help is appreciated.
That issue is a bug (or rounding issue) that among other Chrome and Edge have, but not Firefox.
https://lists.webkit.org/pipermail/webkit-unassigned/2006-January/002684.html
http://cruft.io/posts/percentage-calculations-in-ie/
https://johnresig.com/blog/sub-pixel-problems-in-css/
I found 2 workarounds, one where you add justify-content: space-between; to the flex container (still it appears that at some screen width's Chrome still has that 1px issue)
Stack snippet
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>
And the other is to use flex: 1 1 0/flex: 2 2 0, where the flex-grow/flex-shrink is 1 of 3 and 2 of 3, so they both grow and shrink equally.
Note, is is important to use it like this, where its flex-basis is set to 0, or else the content will be taken into account before the available space will be distributed between the items.
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
flex: 1 1 0;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
flex: 2 2 0;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>
If you want you can leave the width attribute and go with flex-grow it's an attribute of flex:
In your case, I tried using -
.grid-33 {
flex-grow: 3;
-webkit-flex-grow: 3;
}
.grid-66 {
flex-grow: 7;
-webkit-flex-grow: 7;
}
and in my view, it looks same if there is any change you can adjust it with flex-grow value.
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
flex-grow: 3;
-webkit-flex-grow: 3;
}
.grid-50 {
width: 50%;
}
.grid-66 {
flex-grow: 7;
-webkit-flex-grow: 7;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>

flexbox displaying sub-div at the top

This is what I want to do:
I have the brown part separately at the top as a div. Then the other colors in a content div.
I don't understand how to bring the blue part at the top for < 768px since it is inside the content div .
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
margin: 0;
padding: 0;
}
.container{
display: flex;
flex-direction: column;
}
.aquablue{
padding: 50px;
background-color: #B0C4DE;
order: 1;
}
.brownC{
padding: 50px;
background-color: #663300;
}
.yellowC{
padding: 50px;
background-color: #FFCC00;
order: 3;
}
.greenC{
padding: 50px;
background-color: #00FF00;
order: 4;
}
.blueC{
padding: 50px;
background-color: #336699;
order: 5;
}
#media(min-width: 768px){
.container{
display: flex;
flex-direction: column;
}
.content{
display: flex;
order: 2;
}
.left{
display: flex;
flex-direction: column;
width: 50%;
}
.right{
display: flex;
flex-direction: column;
width: 50%;
}
.brownC{
padding: 50px;
background-color: #663300;
width: 100%;
order: 1;
}
.yellowC{
padding: 50px;
background-color: #FFCC00;
}
.greenC{
padding: 50px;
background-color: #00FF00;
}
.blueC{
padding: 50px;
background-color: #336699;
}
}
</style>
</head>
<body>
<div class="container">
<div class="brownC"></div>
<div class="content">
<div class="left">
<div class="aquablue"></div>
<div class="yellowC"></div>
</div>
<div class="right">
<div class="greenC"></div>
<div class="blueC"></div>
</div>
</div>
</div>
</body>
</html>
For pure css you can use this solution. What you do is to remove your "structual divs", on your .container is to add flex: row; and flex-wrap: wrap, then give your elements the width they should be, as in this case was width: 100%; for .brownC and width: 50%; for the rest. Does it make sense?
Check the JSFIDDLE
css
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
}
.aquablue {
padding: 50px;
background-color: #B0C4DE;
order: 1;
}
.brownC {
padding: 50px;
background-color: #663300;
order: 2;
}
.yellowC {
padding: 50px;
background-color: #FFCC00;
order: 3;
}
.greenC {
padding: 50px;
background-color: #00FF00;
order: 4;
}
.blueC {
padding: 50px;
background-color: #336699;
order: 5;
}
#media(min-width: 768px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.brownC {
width: 100%;
order: 1;
}
.aquablue {
order: 2;
width: 50%;
}
.yellowC {
order: 4;
width: 50%;
}
.greenC {
order: 3;
width: 50%;
}
.blueC {
order: 5;
width: 50%;
}
}
html
<div class="container">
<div class="brownC">
</div>
<div class="aquablue">
</div>
<div class="yellowC">
</div>
<div class="greenC">
</div>
<div class="blueC">
</div>
</div>
You can use the move the elements using jQuery on window resize event.
JS FIDDLE : https://jsfiddle.net/tejashsoni111/pdr8qyut/
$(document).ready(function(){
$(window).resize(function(){
if($(window).width() <= 768){
jQuery(".aquablue").after(jQuery(".brownC"));
}else{
jQuery(".content").before(jQuery(".brownC"));
}
})
})

Add a row to a nested flex container on media query

I have one primary container that holds all the divs using a flex-direction of row.
A second container that is nested holds two divs that have a flex-direction of column, to stack up two divs in one row in the outer container.
Using flex-box and media query, I was attempting to change the existing two row column div 'smaller-container' into a three row column div once the browser width is less than 1000px.
I tried doing this by creating a third empty div within smaller-container and swapping its order with a div outside the smaller-container once the browser width is less than 1000px.
It didn't work. I think this is because the two divs in question (the empty div and the outer div) are at a different nesting level.
It would be great if someone can find a solution to turn the two row in one column to three row in one column.
Even better if that solution has no need of a nested container. Javascript solution is also welcome if it doesn't require a plugin.
Image of how it should look:
/*Basic Reset*/
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
max-width: 1366px;
margin: auto;
width: 100%;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.box-1 {
order: 1;
background-color: red;
height: 150px;
width: 50%;
}
.smaller-container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
width: 50%;
order: 2;
}
.box-2 {
order: 3;
background-color: blue;
height: 75px;
width: 100%;
}
.box-3 {
order: 4;
background-color: green;
height: 75px;
width: 100%;
}
.box-4 {
order: 5;
width: 100%;
}
.box-5 {
order: 6;
background-color: orange;
height: 150px;
width: 100%;
}
#media screen and (max-width: 1000px) {
.box-2 {
height: 50px;
}
.box-3 {
height: 50px;
}
/******* Here we swap the empty div that hasbeen existing in the smaller container
with an outer div ********/
.box-5 {
order: 5;
height: 50px;
}
.box-4 {
order: 6;
background-color: purple;
height: 150px;
}
}
[image of desired solution][1] [1]:http://i.stack.imgur.com/vlvlx.png
<div class="container">
<div class="box-1"></div>
<div class="smaller-container">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
</div>
<div class="box-5"></div>
</div>
https://jsfiddle.net/lukindo/nuv603h9/1/
Well, you're right that the order property doesn't work at different nesting levels. It only works among siblings.
Scripting is one option you can pursue. Another, a bit hackish, is to duplicate an HTML element. Specifically, place the orange box element (.box-5) in both the primary and nested container.
Then use display: none on both orange and purple boxes per your media query.
Here's an example:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
max-width: 1366px;
margin: auto;
width: 100%;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.box-1 {
order: 1;
background-color: red;
height: 150px;
width: 50%;
}
.smaller-container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 50%;
order: 2;
}
.box-2 {
order: 3;
background-color: blue;
height: 75px;
width: 100%;
}
.box-3 {
order: 4;
background-color: green;
height: 75px;
width: 100%;
}
.smaller-container > .box5 {
display: none;
}
.container > .box-5 {
order: 6;
background-color: orange;
height: 150px;
width: 100%;
}
#media screen and (max-width: 1000px) {
.box-2 {
height: 50px;
}
.box-3 {
height: 50px;
}
.container > .box-4 {
order: 6;
background-color: purple;
height: 150px;
width: 100%;
}
.smaller-container > .box-5 {
display: block;
height: 50px;
background-color: orange;
width: 100%;
order: 6;
}
.container > .box-5 {
display: none;
}
}
<div class="container">
<div class="box-1"></div>
<div class="smaller-container">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-5"></div>
</div>
<div class="box-4"></div>
<div class="box-5"></div>
</div>
Revised Fiddle