Flexbox - align items baseline in multiple columns - html

is there a way to achieve, that rows in columns side by side are aligned to baseline?
In the example, only "A" is aligned correctly. What I want is to make align baseline also "B" and "C" with the same html structure.
https://jsfiddle.net/hxzuar7f/
I know that something like this will work
<div class="row">
<div class="column">A</div>
<div class="column">A</div>
<div class="column">A</div>
</div>
<div class="row">
<div class="column">B</div>
<div class="column">B</div>
<div class="column">B</div>
</div>
But I want to work this
<div class="container">
<div class="element">
<div class="row">
<h1>A</h1>
</div>
<div class="row">
<div>B</div>
</div>
<div class="row">
<div>C</div>
</div>
</div>
<div class="element">
<div class="row">
<div>A</div>
</div>
<div class="row">
<div>B</div>
</div>
</div>
</div>
(green lines are correct, red lines are wrong)
this is what I want to achieve with CSS:
this is what I got now:

Solution 1 : column → row
That's because your element are in column instead of inline. The align-items: baseline attribut works when elements are horizontaly align. So the best way to acheive what's on your image is with flex-direction: row like this:
h1, h3, div {
display: flex;
align-items: baseline;
flex-direction: row;
box-sizing: border-box;
}
.element {
display: flex;
padding: 20px;
width: 200px;
justify-content: space-between;
}
.container {
width: 100%;
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
<div class="container">
<div class="element">
<div class="row">
<h1>A</h1>
</div>
<div class="row">
<div>B</div>
</div>
<div class="row">
<div>C</div>
</div>
</div>
<div class="element">
<div class="row">
<div>A</div>
</div>
<div class="row">
<div>B</div>
</div>
</div>
<div class="element">
<div class="row">
<div>A</div>
</div>
<div class="row">
<h3>B</h3>
</div>
<div class="row">
<div>C</div>
</div>
</div>
</div>
Solution 2 : add a margin-bottom
If you really want to keep element in column, you need to add a margin-bottom to each row element. But remove some padding of h1and h2. Like this:
h1, h3, div {
display: flex;
align-items: baseline;
flex-direction: row;
box-sizing: border-box;
margin:0;
}
.element {
display: flex;
padding: 20px;
width: 200px;
flex-direction: column;
}
.container {
flex-direction: row;
}
.row {
margin-bottom: 40px;
display: flex;
}
<div class="container">
<div class="element">
<div class="row">
<h1>A</h1>
</div>
<div class="row">
<div>B</div>
</div>
<div class="row">
<div>C</div>
</div>
</div>
<div class="element">
<div class="row">
<div>A</div>
</div>
<div class="row">
<div>B</div>
</div>
</div>
<div class="element">
<div class="row">
<div>A</div>
</div>
<div class="row">
<h3>B</h3>
</div>
<div class="row">
<div>C</div>
</div>
</div>
</div>

Related

Different flex containers side by side

I'm trying to make it such that I have two half-width wrappers side by side. Currently the wrappers do take half the space but don't appear side to side. The display:flex seems to be taking the whole width and leaving the unused space on the side as margin.
.wrapper {
display: flex;
flex-direction: column;
width: 40%;
border: 1px solid black;
}
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
I also tried adding another div outside wrapper with width 50% but it didn't help. Any ideas?
Instead of display: flex, use display: inline-flex.
The first is a block-level element which, by default, takes the full width of the parent.
The second is an inline-level element, which can co-exist with other elements on the same line.
.wrapper {
display: inline-flex;
flex-direction: column;
width: 40%;
border: 1px solid black;
}
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
Alternatively, set the parent element to display: flex which, by default, forces the children to exist in the same row.
Add this to your code: body { display: flex }.
.wrapper {
display: flex;
flex-direction: column;
width: 40%;
border: 1px solid black;
}
body {
display: flex;
}
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
I believe display: flex is similar to display: block if it's a top level element. The difference being; the children of the flex container will be able to utilize the flex behavior. What you need to do is something like this:
body {
margin: 0;
}
.parent {
display: flex;
height: 100vh;
background: #eee;
}
.child {
display: flex;
flex-direction: column;
flex: 1;
border: 1px dashed #ccc;
}
<div class='parent'>
<div class='child column'>child 1</div>
<div class='child column'>child 2</div>
</div>
Wrap the wrappers with div and then display: flex.
.main-wrapper {
display: flex;
}
.wrapper {
display: flex;
flex-direction: column;
width: 50%;
border: 1px solid black;
}
<div class="main-wrapper">
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
<div class="wrapper">
<div class="title">Test Title</div>
<div class="info">
<div class="column">
<b>1</b>
<span>One</span>
</div>
<div class="column">
<b>2</b>
<span>Two</span>
</div>
</div>
</div>
</div>

Make a grid responsive to its parent width

I have an HTML structure like this:
<div class="row">
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
</div>
where class 'row' has width: 100% of its parent and the parent width will change over time.
My goal is that the two divs with a "half-row" class must be in-line and occupy 50% of the "row" div. If the size of the "row" div goes below 640px (so the half-row will be < 320px) the two half-row class divs have to stack and each of them occupies 100% of the available space.
In both cases, the internal div ("cell" class) must equally divide the available space.
Every suggestion is welcome. Thank you
#S.C. is right, flexbox is the way to go and I would also recommend reading the CSS-tricks article! In fact I have used this very same article to construct this alternative example, that's independent of the screen-width:
.row, .half-row {
display: flex;
}
.row {
width: 100%;
flex-direction: row;
flex-wrap: wrap;
}
.half-row {
width: 320px;
flex-grow: 1;
justify-content: space-around;
/* for seeing better what's going on */
background-color: #aaa;
border: 1px solid #333;
}
<div class="row">
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
</div>
You can use flexbox for that.
See excellent article from Css-tricks about Flexbox
If you want to tell us more about the cell class who need to divide the available space "equally" (Horizontally ? Vertically ? both ? Squared ? etc.) I'll update my code to fit with your needs.
I Hope this could help you.
.row {
display: flex;
width: 100%;
flex-flow: row wrap;
}
.half-row {
display: flex;
flex-flow: row; /* or column */
flex-basis: 100%;
/* remove after tests */
background-color: red;
height: 500px;
}
.cell {
flex-basis: 100%;
/* remove after tests */
background-color: blue;
}
#media screen and (min-width: 640px) {
.half-row { flex-basis: 50%; }
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="row">
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
<div class="half-row">
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
<div class="cell">
..content..
</div>
</div>
</div>
</body>
</html>

How can I reduce the horizontal space between col-md-4 divs?

HTML
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="content">1x1</div>
</div>
<div class="col-md-4">
<div class="content">1x2</div>
</div>
<div class="col-md-4">
<div class="content">1x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="content">2x1</div>
</div>
<div class="col-md-4">
<div class="content">2x2</div>
</div>
<div class="col-md-4">
<div class="content">2x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="content">3x1</div>
</div>
<div class="col-md-4">
<div class="content">3x2</div>
</div>
<div class="col-md-4">
<div class="content">3x3</div>
</div>
</div>
</div>
CSS
.container {
text-align: center;
display: flex;
flex-direction: column;
}
.content {
background-color: #1A1919;
color: white;
height: 400px;
width: 300px;
}
.row{
padding: 5px;
}
I have managed to make vertical spaces between the columns by adding padding to the rows. But now the horizontal spaces between the contents are ways too much. How can I configure the spacing between them?
That large horizontal space is because of the fixed width of the content class if you remove that, you'll see it grow.
You can set the width of the content in % or add a margin to the content class.
.container {
text-align: center;
}
.content {
background-color: #1A1919;
color: white;
height: 400px;
}
.row{
padding:15px;
}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-4 col4">
<div class="content">1x1</div>
</div>
<div class="col-md-4 col4">
<div class="content">1x2</div>
</div>
<div class="col-md-4 col4">
<div class="content">1x3</div>
</div>
</div>
<div class="row ">
<div class="col-md-4 col4">
<div class="content">2x1</div>
</div>
<div class="col-md-4 col4">
<div class="content">2x2</div>
</div>
<div class="col-md-4 col4">
<div class="content">2x3</div>
</div>
</div>
<div class="row col4 col4">
<div class="col-md-4 col4">
<div class="content">3x1</div>
</div>
<div class="col-md-4 col4">
<div class="content">3x2</div>
</div>
<div class="col-md-4">
<div class="content">3x3</div>
</div>
</div>
</div>
CSS Grid to achieve that layout you desire:
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-gap: 5px;
position:absolute;
left:50%;
transform:translateX(-50%);
width:80%;
}
.item {
background-color: gray;
text-align: center;
font-size: 30px;
min-height:100px;
max-width: 350px;
}
<div class="grid-container">
<div class="item">1x1</div>
<div class="item">1x2</div>
<div class="item">1x3</div>
<div class="item">2x1</div>
<div class="item">2x2</div>
<div class="item">2x3</div>
<div class="item">3x1</div>
<div class="item">3x2</div>
<div class="item">3x3</div>
</div>
Using flexbox:
.flex-container {
display: flex;
/*Generates a flexbox layout with default flex direction as row */
width: 100%;
/* Not really required */
align-items: center;
/*Aligns contents vertically */
justify-content: center;
/*Aligns contents horizontally */
text-align: center;
/*Aligns further text in the center */
}
.item {
background-color: gray;
text-align: center;
font-size: 30px;
min-height: 400px;
width: 300px;
margin: 5px;
}
<div class="flex-container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="flex-container">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="flex-container">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
Use float:left; with class content as below:
.container {
text-align: center;
display: flex;
flex-direction: column;
}
.content {
float: left;
background-color: #1A1919;
color: white;
height: 400px;
width: 300px;
}
.row{
padding: 5px;
}
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="content">1x1</div>
</div>
<div class="col-md-4">
<div class="content">1x2</div>
</div>
<div class="col-md-4">
<div class="content">1x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="content">2x1</div>
</div>
<div class="col-md-4">
<div class="content">2x2</div>
</div>
<div class="col-md-4">
<div class="content">2x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="content">3x1</div>
</div>
<div class="col-md-4">
<div class="content">3x2</div>
</div>
<div class="col-md-4">
<div class="content">3x3</div>
</div>
</div>
</div>
If I'm reading your request correctly, you are just asking how to make it look like the boxes are in the center of the page, and they are evenly spaced. see if this is what you're looking for:
.container {
text-align: center;
display: flex;
flex-direction: column;
}
.content {
background-color: #1A1919;
color: white;
height: 400px;
width: 300px;
}
.col-md-4 {
margin: 5px -10px 0px -4px;;
}
play with the numbers until you get the desired location.
Though I would strongly suggest that you add your own class in addition to col-md-4 to the boxes, which will prevent this new setting to col-md-4 from affecting any future use of this bootstrap class.
in other words . . .
CSS:
.container {
text-align: center;
display: flex;
flex-direction: column;
}
.content {
background-color: #1A1919;
color: white;
height: 400px;
width: 300px;
}
.box-move {
margin: 5px -10px 0px -4px;;
}
and HTML:
<div class="container">
<div class="row">
<div class="col-md-4 box-move">
<div class="content">1x1</div>
</div>
<div class="col-md-4 box-move">
<div class="content">1x2</div>
</div>
<div class="col-md-4 box-move">
<div class="content">1x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4 box-move">
<div class="content">2x1</div>
</div>
<div class="col-md-4 box-move">
<div class="content">2x2</div>
</div>
<div class="col-md-4 box-move">
<div class="content">2x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4 box-move">
<div class="content">3x1</div>
</div>
<div class="col-md-4 box-move">
<div class="content">3x2</div>
</div>
<div class="col-md-4 box-move">
<div class="content">3x3</div>
</div>
</div>
</div>
You can remove a lot of the stuff there and simplify it to make it responsive width a set margin:
.contents {
background-color: black;
color: white;
height: 500px;
margin: 20px 0px;
}
<div class="container-fluid text-center">
<div class="row">
<div class="col-md-4">
<div class="contents">1x1</div>
</div>
<div class="col-md-4">
<div class="contents">1x2</div>
</div>
<div class="col-md-4">
<div class="contents">1x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="contents">2x1</div>
</div>
<div class="col-md-4">
<div class="contents">2x2</div>
</div>
<div class="col-md-4">
<div class="contents">2x3</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="contents">3x1</div>
</div>
<div class="col-md-4">
<div class="contents">3x2</div>
</div>
<div class="col-md-4">
<div class="contents">3x3</div>
</div>
</div>
</div>
</div>

3x3 circle icon grid with caption

I am looking for ways to add in a 3x3 grid of circle icons to my website. Each icon needs to contain a caption text (including sub-caption text) and be spaced evenly apart. The center icons need to be in the center of the webpage.
I unfortunately have been stuck for the last couple of hours, and I have no idea on how to achieve this. I would appreciate any help.
Here is a mostly flexbox grid with square cells and centered content that will evenly space the circle/text.
* {
box-sizing: border-box; margin: 0; padding: 0;
}
.grid {
display: flex;
flex-wrap: wrap;
max-width: 960px;
width: 90%;
margin: auto;
background: #eee;
}
.cell {
flex-basis: 33.3%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #fff;
}
.cell:before {
padding-bottom: 100%;
display: block;
content: '';
}
.circle {
background: #ccc;
border-radius: 50%;
width: 100px;
height: 100px;
margin: 0 auto 1em;
}
.inner {
text-align: center;
}
<div class="grid">
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
<div class="cell">
<div class="inner">
<div class="circle"></div>
<div class="caption">
<h2>text</h2>
<h3>sub</h3>
</div>
</div>
</div>
</div>

Adjust the width of the container according children width when children are on multiline

I want some solution to adjust the width of the container according children width when children are on multiple lines. When children are on just single line then display:inline-block for the container element make what I need. But when they are on multiple lines, the container just behave the same like display:block.
Only two solutions what I know are:
1) Set container max-width as some multiplying of children width. But it is not a universal solution (I mean display on devices with lower resolution).
2) Use jQuery to compute the container width. but I'd rather like to use some pure HTML/CSS solution.
HTML:
<div id="wrapper1">
<div id="wrapper2">
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
</div>
</div>
<div id="wrapper2">
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
<div class="el">
</div>
</div>
</div>
CSS:
#wrapper1{
max-width:1200px;
margin:auto;
}
#wrapper2{
background: #FF0;
display:inline-block;
}
.el{
float:left;
margin:10px;
width:200px;
height:200px;
background:#00F;
}
Please test this:
#wrapper1{
display: -webkit-flex;
-webkit-flex-wrap: wrap; /* Safari 6.1+ */
display: flex;
flex-wrap: wrap;
justify-content: center;
-webkit-justify-content: center;
}
#wrapper2{
max-width:880px;
display: -webkit-flex;
-webkit-flex-wrap: wrap; /* Safari 6.1+ */
display: flex;
flex-wrap: wrap;
justify-content: space-between;
-webkit-justify-content: space-betweeen;
}
Here is a sample:
Sample
Click on start page and see the page after i think that is what you want.
#wrapper1{
width:1200px;
}
#wrapper2{
display:inline-block;
}
.el{
width:200px;
height:200px;
background:#00F;
}
.ul{
padding: 20px;
float:left;
width:200px;
height:200px;
background: #FF0;
}
<div id="wrapper1">
<div id="wrapper2">
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
<div class="ul">
<div class="el"></div>
</div>
</div>
</div>