I am trying to learn Flexbox but having trouble getting what I want.
What I want:
1 box which will have 2 labels (a number over top a label)
second box will have 4 labels (1 in top left, 1 in top right, 1 in center and 1 in bottom middle)
.flex-container {
display: flex;
background-color: lightgrey;
flex-direction: row;
align-items: stretch;
align-content: stretch;
}
.flex-item {
display: flex;
background-color: cornflowerblue;
margin: 10pt;
}
.flex-item-2 {
display: flex;
background-color: cornflowerblue;
margin: 10pt;
flex: 2 0 0;
}
.flex-qty-container {
font-size: 27pt;
margin: 0;
}
.flex-sub-container {
display: flex;
background-color: yellow;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-start;
flex: 2 0 0;
}
.flex-item-left-corner {
background-color: red;
}
.flex-item-right-corner {
background-color: red;
align-self: flex-end;
font-size: 10pt;
}
.flex-item-center {
background-color: red;
font-size: 12pt;
}
.flex-item-bottom-middle {
background-color: red;
}
<div class="flex-container">
<div class="flex-item">
<div class="">
<p class="flex-qty-container">7</p>
<p class="flex-qty-label">Label</p>
</div>
</div>
<div class="flex-item-2">
<div class="flex-sub-container">
<p class="flex-item-left-corner">top left corner</p>
<p class="flex-item-right-corner">top right corner</p>
<p class="flex-item-center">Center of box</p>
<p class="flex-item-bottom-middle">Bottom middle</p>
</div>
</div>
</div>
1 box which will have 2 labels (a number over top a label)
This part you seem to have done already. I didn't change anything there.
second box will have 4 labels (1 in top left, 1 in top right, 1 in center and 1 in bottom middle)
This layout can be achieved with a properly nested flex container.
In your code, .flex-item-2 has one flex item: .flex-sub-container. This flex item doubles as a flex container and has four flex items (your labels).
<div class="flex-item-2">
<div class="flex-sub-container">
<p class="flex-item-left-corner">top left corner</p>
<p class="flex-item-right-corner">top right corner</p>
<p class="flex-item-center">Center of box</p>
<p class="flex-item-bottom-middle">Bottom middle</p>
</div>
</div>
Instead of having .flex-sub-container wrap all four labels, have it wrap only the first two. Then apply justify-content: space-between and the top left and top right labels are aligned as intended.
<div class="flex-item-2">
<div class="flex-sub-container">
<p class="flex-item-left-corner">top left corner</p>
<p class="flex-item-right-corner">top right corner</p>
</div><!-- END .flex-sub-container -->
<p class="flex-item-center">Center of box</p>
<p class="flex-item-bottom-middle">Bottom middle</p>
</div>
.flex-item-2 {
display: flex;
flex-direction: column;
}
.flex-sub-container {
display: flex;
justify-content: space-between;
}
With .flex-item-2 now a column-direction flex container, the cross axis is now horizontal and the align-self property can be used to center the lower labels.
.flex-item-center {
align-self: center;
}
.flex-item-bottom-middle {
align-self: center;
}
DEMO
I'm not exactly sure how much of your example is specifically needed, so I put some examples in to show you what your options are, and basically solves what you're asking for. More nesting would support more specifics, etc:
https://jsfiddle.net/1z4unyc2/
HTML:
<div class="flex-container">
<div class="flex-item">
<p class="flex-qty-container">7</p>
<p class="flex-qty-label">Label</p>
</div>
<div class="flex-item-2">
<p class="flex-item-left-corner">top left corner</p>
<div class="flex-item">
<p class="flex-item-center">Center of box</p>
<p class="flex-item-bottom-middle">Bottom middle</p>
</div>
<p class="flex-item-right-corner">top right corner</p>
</div>
</div>
CSS:
.flex-container {
display: flex;
background-color: lightgrey;
flex-direction: row;
}
.flex-item {
display: flex;
background-color: cornflowerblue;
margin: 10pt;
flex-direction: column;
justify-content: center;
align-items: center;
}
.flex-item-2 {
display: flex;
background-color: cornflowerblue;
margin: 10pt;
flex-direction: row;
justify-content: center;
align-items: center;
}
.flex-qty-container {
font-size: 27pt;
}
.flex-item-left-corner {
background-color: red;
align-self: flex-start;
}
.flex-item-right-corner {
background-color: red;
align-self: flex-start;;
font-size: 10pt;
}
.flex-item-center {
background-color: red;
font-size: 12pt;
align-self: center;
}
.flex-item-bottom-middle {
background-color: red;
align-self: flex-end;
}
Related
A short JSfiddle to demonstrate my problem JSFIDDLE.
My objectives are:
The date should be centered both horizontally and vertically in its rectangle.
The subtitle should be below the title.
li {
display: flex;
align-items: center;
background-color: pink;
}
.date {
background-color: orange;
width: 50px;
height: 50px;
text-align: center;
margin-right: 5px;
}
ol {
list-style: none;
}
<ol>
<li>
<div class="date">Apr<br>01</div>
<h3>
Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</li>
<li>
<div class="date">Mar<br>01</div>
<h3>
Another Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</li>
</ol>
I use flexbox a lot but with divs mostly. Using other HTML elements is valuable for me, when there are preset styles for them for the whole application, then it is easier :)
Here is how I would do this (CSS explained under snippet):
.container {
display: inline-flex;
width: 100%;
background-color: pink;
}
.date {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 50px;
width: 50px;
background-color: orange;
margin-right: 5px;
}
.info {
display: flex;
flex-direction: column;
justify-content: center;
}
.title {
font-weight: bold;
font-size: 20px;
}
<div class="container">
<div class="date">
<div>Apr</div>
<div>01</div>
</div>
<div class="info">
<div class="title">Another Blog Title</div>
<div>Subtitle - should be below title</div>
</div>
</div>
1) .container
display: inline-flex -> date and info text items are inline
width: 100% -> fit parent width.. can be set fixed to 300px for example
2) .date & .info
display: flex -> using flexbox, not inline. Make other flexbox CSS properties works and adds own adjustments
flex-direction: column -> this makes children align under each other (into column)
align-items: center -> when flex-direction is active this will align children horizontaly, otherwise vertically
justify-content: center -> when flex-direction is active, this will align children vertically, otherwise horizontally
As for your snippet, just adjust it this way:
li {
display: flex;
align-items: center;
background-color: pink;
}
.date {
display: flex;
justify-content: center;
align-items: center;
background-color: orange;
width: 50px;
height: 50px;
text-align: center;
margin-right: 5px;
}
.info {
display: flex;
flex-direction: column;
}
h3 {
margin: 0px;
}
p {
margin: 0px;
}
ol {
list-style: none;
}
<ol>
<li>
<div class="date">Apr<br>01</div>
<div class="info">
<h3>
Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
<li>
<div class="date">Mar<br>01</div>
<div class="info">
<h3>
Another Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
</ol>
Explanation of this CSS is under the first snippet. I just removed margins from h3 and p elements, so it does not break layout :)
Hope it helps you.
I learned a lot of flexbox from this article -> https://css-tricks.com/snippets/css/a-guide-to-flexbox
Give it a try and GL ;)
The date should be centred both horizontally and vertically in its rectangle.
.date {
background-color: orange;
width: 70px;
height: 70px;
text-align: center;
display: flex;
justify-content: center; /* align horizontal */
align-items: center; /* align vertical */
}
Using Flexbox, you can just add justify-content: center for horizontal and align-items: center for vertical alignments. But you'd need to set the display:flex first.
The subtitle should be below the title.
For this, you can set the display to flex and use the flex-direction on the main container, in this case it'll be your ordered list <ol> element. Then update the <li> element to also use flex and
ol {
display: flex;
flex-direction: column;
}
li {
flex: 1;
flex: wrap;
align-items: center;
background-color: pink;
}
To center contents of .date on both directions you can use flexbox:
.date {
display:flex;
align-items: center; /* centers vertically */
justify-content: center; /* centers horizontally */
}
To display the <h3> above the <p> you could give them a wrapper with:
.date + div {
display: flex;
flex-direction: column;
align-items: flex-start; /* align children to left side */
justify-content: center; /* center vertically */
}
You might also want to remove the margins on the <h3>s and <p>s;
.date + div > * {
margin: 0;
}
li {
display: flex;
align-items: center;
background-color: pink;
}
.date {
background-color: orange;
width: 50px;
height: 50px;
margin-right: 5px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.date + div {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.date + div > * {
margin: 0;
}
ol {
list-style: none;
}
<ol>
<li>
<div class="date">Apr<br>01</div>
<div>
<h3>
Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
<li>
<div class="date">Mar<br>01</div>
<div>
<h3>
Another Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
</ol>
Important note: You might notice align-items and justify-contents refer to different directions when used on first, respectively the second child of your <li>s. That's because they're dependent on the flex-direction, as follows:
justify-content controls alignment on the direction of flex-direction
align-items controls alignment on the direction perpendicular on flex-direction
default flex-direction value is row
Please see below. I documented the changes in the source.
li {
display: flex;
align-items: center;
background-color: pink;
}
.date {
background-color: orange;
width: 50px;
height: 50px;
text-align: center;
margin-right: 5px;
display: flex; /* Added */
align-items: center; /* Added */
justify-content: center; /* Added */
}
ol {
list-style: none;
}
/* Added */
.titles h3 {
margin: 0.5rem 0 0 0;
}
/* Added */
.titles p {
margin: 0.5rem 0 0 0;
}
<ol>
<li>
<div class="date">Apr<br>01</div>
<!-- Extra wrapper added -->
<div class="titles">
<h3>
Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
<li>
<div class="date">Mar<br>01</div>
<!-- Extra wrapper added -->
<div class="titles">
<h3>
Another Blog Title
</h3>
<p>
Subtitle - should be below title
</p>
</div>
</li>
</ol>
You should use ol/ul li elements when you want to define an ordered/unordered list of elements, for example a navigation bar. What you are doing now is not semantically correct.
Take a look at: float and clear properties.
I rewrited your code using float and clear properties. In order to center the date, since it is a static content, just remove the height property and add a padding for create your margins. At last, instead of using float: right for your content, I used display flex properties.
.group:after {
content: "";
display: table;
clear: both;
}
#preview {
background-color: pink;
}
#preview .group {
display: flex;
}
.date {
float: left;
background-color: orange;
width: 50px;
text-align: center;
padding: 8px 5px;
}
.content {
flex: 1;
margin-left: 5px;
}
.content h3 {
margin: 0;
}
.content p {
margin: 0;
}
<div id="preview">
<div class="group">
<div class="date">Apr<br>01</div>
<div class="content">
<h3>Blog title</h3>
<p>Subtitle - should be below title</p>
</div>
</div>
<div class="group">
<div class="date">Mar<br>01</div>
<div class="content">
<h3>Another Blog title</h3>
<p>Subtitle - should be below title</p>
</div>
</div>
</div>
I have aligned two divs side-by-side using Flexbox and I want the text in both the divs to be pushed to the bottom of the divs at equal levels but there seems to be different level of spacing underneath the individual texts.
.wrapper {
display: flex;
flex-direction: row;
}
.block1 {
font-weight: bold;
font-size: 2em;
color: red;
border: 1px solid;
display: flex;
align-items: flex-end;
}
.block2 {
font-size: 1em;
color: grey;
border: 1px solid;
display: flex;
align-items: flex-end;
}
.block1.hack-fix {
line-height: 29px; /* HACK */
}
<h2>Current:</h2>
<div class="wrapper">
<span class="block1">
23
</span>
<span class="block2">
Quote
</span>
</div>
<hr/>
<h2>Needed:</h2>
<div class="wrapper">
<span class="block1 hack-fix">
23
</span>
<span class="block2">
Quote
</span>
</div>
Thanks for the help!
What you're looking for is called baseline alignment.
To achieve this in flexbox use align-items: baseline.
Here's a more complete explanation:
What's the difference between flex-start and baseline?
.wrapper {
display: flex;
flex-direction: row;
align-items: baseline; /* NEW */
}
.block1 {
font-weight: bold;
font-size: 2em;
color: red;
}
.block2 {
font-size: 1em;
color: grey;
}
<div class="wrapper">
<span class="block1">23</span>
<span class="block2">Quote</span>
</div>
Parents :
display: flex;
Children:
flex: 1;
I'm trying to create this top header using flexbox.
Basically I would like to center the <div class="header-title"> (Institution institution 1) on the line with the 3 other elements you see. (Institutioner, Ledere and Log ud) like you see on the image.
.nav {
background: #e1e1e1;
}
ol, ul {
list-style: none;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.header-title {
justify-content: center;
align-self: center;
display: flex;
}
.nav ul li.logout {
margin-left: auto;
}
.nav ul li a {
text-decoration: none;
padding: 0px 20px;
font-weight: 600;
}
<div class="nav mobilenav">
<div class="header-title">
Institution institution 1
</div>
<ul>
<li>Institutioner</li>
<li>
Ledere
</li>
<li class="logout">
<a class="button-dark" href="/user/logout">Log ud</a>
</li>
</ul>
</div>
Demo - JSFiddle
Use nested flex containers and flex-grow: 1.
This allows you to create three equal-width sections on the nav bar.
Then each section becomes a (nested) flex container which allows you to vertically and horizontally align the links using flex properties.
Now the left and right items are pinned to the edges of the container and the middle item is perfectly centered (even though the left and right items are different widths).
.nav {
display: flex;
height: 50px; /* optional; just for demo */
background: white;
}
.links {
flex: 1; /* shorthand for: flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
display: flex;
justify-content: flex-start;
align-items: center;
border: 1px dashed red;
}
.header-title {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed red;
}
.logout {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
border: 1px dashed red;
}
.links a {
margin: 0 5px;
text-decoration: none;
}
<div class="nav mobilenav">
<div class="links">
Institutioner
Ledere
</div>
<div class="header-title">Institution institution 1</div>
<div class="logout"><a class="button-dark" href="/user/logout">Log ud</a></div>
</div>
jsFiddle
Use justify-content: space-between; like this:
.container {
display: flex;
justify-content: space-between;
}
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Css grid will do this better than flexbox.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
}
button {
display: inline-block;
}
.short-content {
margin-left: auto;
}
<div class="grid">
<div class="long-content">
This has content that is fairly long
</div>
<button>CTA Button</button>
<div class="short-content">
Small Text
</div>
</div>
Here is a Flex solution that aligns the right and left containers while centering the middle container correctly.
.header-box {
width: 100%;
display: flex;
flex-flow: row wrap;
padding-top: 50px;
}
.left-header, .center-header, .right-header {
flex: 100px; /* adjust width if needed */
}
.header-box div:nth-of-type(1) {
text-align: left;
}
.header-box div:nth-of-type(2) {
align-self: center;
text-align: center;
}
.header-box div:nth-of-type(3) {
text-align: right;
}
<div class="header-box">
<div class="left-header">Left<br>header<br>content</div>
<div class="center-header">Center<br>header<br>content</div>
<div class="right-header">Right<br>header<br>content</div>
</div>
If you are open to changing your html, you need to put all the items in your header on the same level in the DOM.
Here's a working example
.nav {
background: #e1e1e1;
list-style: none;
display: flex;
align-items: center;
justify-content: space-between;
height: 60px;
}
.nav > div {
min-width: 0;
white-space: nowrap;
}
.header-title {
flex-basis: 80%;
text-align: center;
}
.nav div a {
text-decoration: none;
padding: 0px 20px;
font-weight: 600;
}
<div class="nav mobilenav">
<div>Institutioner</div>
<div>Ledere</div>
<div class="header-title">
Institution institution 1
</div>
<div class="logout">
<a class="button-dark" href="/user/logout">Log ud</a>
</div>
</div>
How can I make my flexbox with column direction children be same width.
JSFiddle Example:
https://jsfiddle.net/6ynofan5/
<div class="block">
<div class="title">Some dummy text here, huh</div>
<div class="info">
<div class="text">1</div>
<div class="text">2</div>
<div class="text">3</div>
</div>
</div>
.block {
display: flex;
flex-direction: column;
align-items: center;
}
.block .title {
font-size: 30px;
}
.block .info {
display: flex;
justify-content: space-between;
}
Div with class .info should be the same width as .title, there should not be fixed width.
The equalising of widths is managed by align-items where the default is stretch. In this instance you have over-ridden this and so a wrapper is needed.
Then the two inner divs can be their natural 100% width.
.block {
display: flex;
flex-direction: column;
border: 1px solid grey;
justify-content: center;
align-items: center;
}
.title {
font-size: 30px;
background: lightblue;
}
.info {
display: flex;
justify-content: space-between;
background: plum;
}
<div class="block">
<div class="wrap">
<div class="title">Some dummy text here, huh</div>
<div class="info">
<div class="text">1</div>
<div class="text">2</div>
<div class="text">3</div>
</div>
</div>
</div>
.block {
display: table;
flex-direction: column;
align-items: center;
}
https://jsfiddle.net/1mz9f8p0/1/
I'm trying to achieve the following result using flexbox:
I tried the with the following html but I can't get it to work.
<div class=" flex-center">
<div class="flex-item-center">
<p>
Some text in box A
</p>
</div>
<div class="flex-item-bottom">
<p>Some text in box B....</p>
</div>
</div>
CSS:
.flex-center {
display: flex;
align-items: center;
align-content: center;
justify-content: center;
}
.flex-item-center {
align-self: center;
}
.flex-item-bottom {
align-self: flex-end;
}
How can I make it look like the image?
I've made a posible solution.
.flex-center {
background-color: #739FD0;
color: #000000;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: center;
height: 400px;
}
.flex-center-bottom {
background-color: #739FD0;
color: #000000;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
align-content: center;
align-items: center;
}
.flex-item-center {
border: solid 2px #4675AA;
order: 0;
flex: 0 1 auto;
align-self: center;
}
.flex-item-bottom {
border: solid 2px #4675AA;
order: 1;
flex: 0 1 auto;
align-self: flex-end;
}
<div class="flex-center">
<div class="flex-item-center">
<p>DROP FILES HERE</p>
</div>
</div>
<div class="flex-center-bottom">
<div class="flex-item-center">
<p>Hint: You can also drop files in the all files page</p>
</div>
</div>
Update 2017: Tested in Google Chrome Versión 62.0.3202.89 (Build oficial) (32 bits).
.flex-center,
.flex-center-bottom {
align-items: center;
background-color: #739FD0;
color: #000000;
display: flex;
}
.flex-center {
height: 400px;
justify-content: center;
}
.flex-center-bottom {
justify-content: flex-end;
}
.flex-item-center {
border: solid 2px #4675AA;
font-family: Arial, sans-serif;
font-size: 1.6em;
line-height: 1px;
padding: 0 3px;
}
<div class="flex-center">
<div class="flex-item-center">
<p>Some text in box A</p>
</div>
</div>
<div class="flex-center-bottom">
<div class="flex-item-center">
<p>Some text in box B...</p>
</div>
</div>
I hope this helps you.
Is this what you are looking for? http://jsfiddle.net/DIRTY_SMITH/q12bh4se/6/
body {
background-color: lightblue;
}
#main {
width: 100%;
height: 400px;
border: 1px solid black;
display: -webkit-flex;
/* Safari */
-webkit-align-items: flex-start;
/* Safari 7.0+ */
display: flex;
align-items: flex-start;
}
#main div {
-webkit-flex: 1;
/* Safari 6.1+ */
flex: 1;
}
.flex-item-center {
margin-left: 40%;
border-style: solid;
-webkit-align-self: center;
/* Safari 7.0+ */
align-self: center;
}
.flex-item-bottom {
border-style: solid;
align-self: flex-end;
}
Try:
#main-wrapper {
background: blue;
width: 100%;
height: 100%;
min-height: 300px;
display: flex;
align-items: center;
}
.x-center {
display: flex;
justify-content: center;
}
.y-center {
flex: 1;
}
.x-right {
justify-content: flex-end;
}
.y-bottom {
align-self: flex-end;
}
.small-div {
padding: 10px;
}
<div id="main-wrapper">
<div class="x-center y-center small-div">Center center</div>
<div class="x-right y-bottom small-div">Bottom Right</div>
</div>
Notes:
The align-self won't work for IE10 or below.
Anybody know how to make the center div a bit more to the left without position relativing it? Thanks
In Bootstrap 4.x you can use the utility classes
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-center h-100">
<div class="d-flex align-items-center">center center</div>
</div>
<div class="d-flex justify-content-end h-100">
<div class="d-flex align-items-end">right bottom</div>
</div>
</div>
</div>
</div>
EDIT
Since I received a couple downvotes I believe a review is in order.
To me the above answer is still valid, however I understand it's not clear it requires some height.
How this height is achieved doesn't really matter. Either you set it fixed in CSS on a wrapper or for the code snippet's sake we set the document's height to make it responsive.
If the "center content" takes up the space in height, the "bottom content" can be positioned absolute, so it doesn't add height. All what's left is to make sure it covers the full width and positions from the bottom.
html, body { height: 100%; } /* can be anything that generates height */
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="d-flex justify-content-center h-100">
<div class="d-flex align-items-center">center center</div>
</div>
<div class="d-flex justify-content-end position-absolute w-100 fixed-bottom">
<div class="d-flex align-items-end">right bottom</div>
</div>
So functionality wise, there's no additional CSS required in Bootstrap.
Documentation justify content
Documentation position