Vertically centering content in display: flex; columns - css

I’m using Flexbox to align the height of two adjacent columns, which works. I now need to vertically center the inner content within the flex box columns without using fixed heights. Additionally this all needs to work within Bootstrap 3. Please see code below:
.row-flex,
.row-flex > div[class*='col-'] {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex: 1 1 auto;
}
.row-flex-wrap {
-webkit-flex-flow: row wrap;
align-content: flex-start;
flex: 0;
}
.row-flex > div[class*='col-'],
.container-flex > div[class*='col-'] {
margin: -.2px;
/* hack adjust for wrapping */
}
.container-flex > div[class*='col-'] div,
.row-flex > div[class*='col-'] div {
width: 100%;
}
.flex-col {
display: flex;
display: -webkit-flex;
flex: 1 100%;
flex-flow: column nowrap;
}
.flex-grow {
display: flex;
-webkit-flex: 2;
flex: 2;
}
.content {
border: 1px solid black;
padding: 20px;
}
.content-inner {
border: black solid 1px;
padding: 20px;
}
.img {
width: 100px;
height: auto;
display: block;
margin: 0 auto;
}
figcaption {
text-align: center;
}
[class*="col-"] {
padding: 0;
}
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row row-flex row-flex-wrap">
<div class="col-xs-7">
<div class="content">
<div class="content-inner">
<figure>
<img class="img" src="http://i80.photobucket.com/albums/j182/swiftian/headersnstuff/sidebar_zaius.jpg" alt="Macaque in the trees">
<figcaption>Dr. Zaius</figcaption>
</figure>
</div>
</div>
</div>
<div class="col-xs-5">
<div class="content">
<div class="content-inner">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate. Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis dolor, in sagittis nisi. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate. Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis dolor, in sagittis nisi.
</div>
</div>
</div>
</div>
<!--/row-->
</div>
<!--/container-->
<hr>
JS FIDDLE
https://jsfiddle.net/baydbzbn/1/
Appreciate any help.

Add this to your .content class CSS definition
display: flex;
align-items: center;

Related

CSS Center text inside paragraph [duplicate]

This question already has answers here:
How can I center text (horizontally and vertically) inside a div block?
(27 answers)
Closed 2 years ago.
How to vertically center text inside p? Thank you.
enter image description here
Flexbox solution - the more modern solution:
https://jsfiddle.net/2zqeL6g8/
The HTML:
<div class="todo">
<div class="todo-left">
<p>TODO 1</p>
</div>
<div class="todo-right">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus aliquam egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus aliquam egestas.</p>
</div>
</div>
The CSS:
.todo {
display: flex;
}
.todo-left {
background: #ccc;
padding: 0 15px;
flex: 0 0 100px;
display: flex;
align-items: center;
}
.todo-right {
background: #f5f5f5;
padding: 0 15px;
flex: 1;
display: flex;
align-items: center;
}
CSS table solution - older method, but works in older browsers ie8+:
https://jsfiddle.net/2zqeL6g8/2/
The HTML:
<div class="todo">
<div class="todo-row">
<div class="todo-cell-left">
<p>TODO 1</p>
</div>
<div class="todo-cell-right">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus aliquam egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus aliquam egestas.</p>
</div>
</div>
</div>
The CSS:
.todo {
display: table;
border-collapse: collapsed;
width: 100%;
}
.todo-row {
display: table-row;
}
.todo-cell-left,
.todo-cell-right {
display: table-cell;
vertical-align: middle;
padding: 0 15px;
}
.todo-cell-left {
background: #ccc;
width: 100px;
}
.todo-cell-right {
background: #f5f5f5;
}
.todo {
display: flex;
}
.todo-left {
background: #ccc;
padding: 0 15px;
flex: 0 0 100px;
height:100px;
display: flex;
align-items: center;
}
.todo-right {
background: #f5f5f5;
padding: 0 15px;
flex: 1;
display: flex;
align-items: center;
}
<div class="todo">
<div class="todo-left">
<p>TODO 1</p>
</div>
<div class="todo-right">
<p>Lorem ipsum dolor sit .</p>
</div>
</div>

How to make a div in a flexbox appear in next line?

I want the div in the flexbox container to appear in the next line.
I have a drawer div and within that have details div. within details div I want the SVG and span elements to be in one line. If the span element has text more than one line then should fit in next line and the div element after span element should always be below the span element and centered in the list element(no matter span element has text one or more than one line).
Something like below.
Below is the code,
.drawer {
display: flex;
flex-direction: column;
position: absolute;
width: 392px;
top: 55px;
right: 8px;
min-height: 40%;
max-height: 450px;
margin-left: 16px;
&::after {
content: " ";
position: absolute;
bottom: 100%;
left: 83%;
margin-left: -5px;
border-width: 14px;
border-style: solid;
}
}
.item {
display: flex;
flex-direction: row;
font-size: 12px;
padding: 8px;
min-height: 49px;
li {
list-style: none;
}
.details {
display: flex;
flex-grow: 1;
color: #333;
margin-right: 4px;
}
}
<div class="drawer">
<ul>
<li class="item">
<div class="details">
<svg/>
<span>sometext</span>
<div>
<div/><img/>
</div>
</div>
</li>
</ul>
</div>
Could someone help me solve this? Thanks.
Your structure contains too many styles, which I was not sure after looking at the requirement of yours (png attached).
I have added a simple structure suiting your requirement, please see if it makes sense.
In case you want something please revert
.drawer {
display: flex;
flex-direction: column;
position: absolute;
width: 392px;
top: 55px;
left: 8px;
min-height: 40%;
max-height: 450px;
margin-left: 16px;
}
svg {
border: solid 1px;
}
.drawer::after {
content: " ";
position: absolute;
bottom: 100%;
left: 83%;
margin-left: -5px;
border-width: 14px;
border-style: solid;
}
.item {
display: flex;
flex-direction: row;
font-size: 12px;
padding: 8px;
min-height: 49px;
}
.item {
list-style: none;
border-bottom: solid 1px;
}
.item .details {
color: #333;
margin-right: 4px;
}
.media {
display: flex;
align-items: flex-start;
}
.media-body {
flex: 1;
}
<body>
<div class="drawer">
<ul>
<li class="item">
<div class="media">
<svg class="bd-placeholder-img mr-3" width="64" height="64" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 64x64"><title>Placeholder</title><rect width="100%" height="100%" fill="#868e96"></rect><text x="50%" y="50%" fill="#dee2e6" dy=".3em">64x64</text></svg>
<div class="media-body" style="margin-left:20px;">
<p> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis
in faucibus. </p>
<p style="text-align:center;"> Center align Text </p>
</div>
</div>
</li>
<li class="item">
<div class="media">
<svg class="bd-placeholder-img mr-3" width="64" height="64" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 64x64"><title>Placeholder</title><rect width="100%" height="100%" fill="#868e96"></rect><text x="50%" y="50%" fill="#dee2e6" dy=".3em">64x64</text></svg>
<div class="media-body" style="margin-left:20px;">
<p> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis
in faucibus. </p>
<p style="text-align:center;"> Center align Text </p>
</div>
</div>
</li>
<li class="item">
<div class="media">
<svg class="bd-placeholder-img mr-3" width="64" height="64" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 64x64"><title>Placeholder</title><rect width="100%" height="100%" fill="#868e96"></rect><text x="50%" y="50%" fill="#dee2e6" dy=".3em">64x64</text></svg>
<div class="media-body" style="margin-left:20px;">
<p> Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis
in faucibus. </p>
<p style="text-align:center;"> Center align Text </p>
</div>
</div>
</li>
</ul>
</div>
</body>
The text below will be centred more content on top
.drawer {
display: flex;
flex-direction: row;
}
.drawer_icon {
width: 60px;
height: 60px;
background: palevioletred;
margin-right: 16px;
}
p {
text-align: center;
}
<div class="drawer">
<div class="drawer_icon"></div>
<div>
<span>Some Text</span>
<p>Centered text</p>
</div>
</div>

Why isn't my layout working?

I need some help with a practice project I'm working on. I've got my content divs (.primary, .secondary and .tertiary) sat within a wrapper that's currently set to 100% width (for the sake of debugging).
I want it so that .primary and .secondary appear next to each other side by side at a screen size of 779px and above with tertiary set at 100% of the wrapper's width below them.
All three content divs also have the class col which I've floated left so in theory, I should be able to set .primary and .secondary to 50% and they should happily sit next to each other, right?
Wrong.
They sit as blocks below each other. Both have a width of exactly half of the wrapper (used dev tools in google chrome to check) but they won't sit next to each other until I sit their widths to 48% and then they leave a gap to their immediate right.
I honestly can't make heads or tails of it. I'm going to include the full code below for anyone that wants to just copy and paste to see the weirdness. I should note as well, there is a normalize file on there, downloaded from: https://necolas.github.io/normalize.css/
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Dragon Ball Fan Site</title>
<link rel="stylesheet" type="text/css" href="css/normalize.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet">
</head>
<body>
<header class="main-header clearfix">
<div class="container">
<h1 class="title">Dragon Ball Fan Site</h1>
<ul class="main-nav">
<li>Main</li>
<li>Manga</li>
<li>Anime</li>
<li>Video Games</li>
<li>Register</li>
</ul>
</header>
<div class="banner">
<img src="img/main-img.png" alt="Main Image, Goku" class="main-img">
<h1 class="name">Dragon Ball Fansite</h1>
<span class="tagline">A Site For Fans, By Fans</span>
</div>
</div>
<div class="wrapper clearfix">
<div class="secondary col">
<h2>Welcome</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vel dui at odio imperdiet pulvinar vitae sed arcu. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vel dui at odio imperdiet pulvinar vitae sed arcu. Cras accumsan leo nulla, at suscipit augue finibus ac. Aliquam ut mi vulputate, ullamcorper metus quis, tempor lorem. Praesent eleifend dignissim ligula. Nunc enim lectus, fringilla at odio vel, sagittis volutpat velit. Integer pretium ac nisl eget volutpat.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="primary col">
<h2>About Dragon Ball</h2>
<img src="img/cast.png" alt="Main Cast" class="cast">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vel dui at odio imperdiet pulvinar vitae sed arcu. Cras accumsan leo nulla, at suscipit augue finibus ac. Aliquam ut mi vulputate, ullamcorper metus quis, tempor lorem.</p>
</div>
<div class="tertiary col">
<h2>About Us</h2>
<ul>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
<li>Ut vel dui at odio imperdiet pulvinar vitae sed arcu. Cras accumsan leo nulla, at suscipit augue finibus ac.</li>
<li>Aliquam ut mi vulputate, ullamcorper metus quis, tempor lorem.</li>
</ul>
</div>
</div>
</div>
<footer class="main-footer">
<span class="copyright"> ©Dragon Ball Fan Site 2018</span>
</footer>
</body>
</html>
/* =========
Fonts
========= */
#font-face {
font-family: 'Roboto', sans-serif;
}
##font-face {
font-family: 'saiyain-sans';
src: url(font/Saiyan-Sans.ttf);
}
/* =========
Elements
========= */
* {
margin: 0;
padding: 0;
}
body {
font-family: 'Roboto', helvetica, sans-serif;
font-size: 1.25em;
}
h1 {
margin: 0;
font-weight: 400;
font-size: 2.441em;
}
h2 {
font-size: 1.953em;
padding-bottom: 1em;
padding-left: 0;
padding-right: 0;
}
p {
line-height: 1em;
margin: 0;
padding: 0;
}
div {
margin: 0;
}
/* =========
Classes
========= */
.main-header {
text-align: center;
color: #f85b1a;
margin-bottom: 1em;
padding-top: 2em;
}
.title {
padding-bottom: 1em;
}
.main-nav li {
padding-bottom: 0.5em;
font-weight: 400;
}
.main-nav a {
text-decoration: none;
color: #f85b1a;
display: block;
}
.banner {
text-align: center;
background-color: #f85b1a;
color: #fff;
padding: 1em;
margin-bottom: 2em;
}
.main-img {
border-radius: 50%;
border: 3px solid #000;
margin-bottom: 2em;
}
.name {
font-family: 'saiyain-sans', 'Roboto', sans-serif;
margin-bottom: 0;
}
.wrapper {
margin: 0 auto;
width: 90%;
}
.col {
border: 1px solid red;
}
.primary,
.secondary {
margin-bottom: 1em;
}
.cast {
width: 100%;
padding: 0;
margin: 0 auto;
}
.main-footer {
background-color: #072083;
text-align: center;
padding: 1em;
margin-top: 1em;
}
.copyright {
font-size: 0.8em;
color: #8a9294;
}
/* =========
media queries
========= */
#media (min-width: 779px) {
.container {
margin: 0 auto;
}
.main-header {
padding: 1em;
}
.title,
.col {
float: left;
}
.title {
padding-top: 0;
padding-bottom: 0;
font-size: 1.25em;
}
.main-nav {
float: right;
}
.main-nav li {
display: inline-block;
float: left;
list-style: none;
font-size: 1.25em;
padding: 0 0.2em;
border-right: 1px solid #8a9294;
}
.main-nav li:last-child {
border-right: none;
}
.name {
padding-bottom: 0.5em;
}
.tagline {
font-size: 1.5em;
}
.wrapper {
width: 100%;
padding: 0;
}
.secondary,
.primary {
width: 50%;
}
.copyright {
padding: 2em;
}
/* =========
Clearfix
========= */
.clearfix::after {
content: " ";
display: table;
clear: both;
}
}
I finally figured it out. It was the border box property. Adding any padding and things like that were pushing it to be bigger than the wrap. I had the border property added to test where it was going wrong and that was just adding to the problem.
Thanks to everyone that took the time to look.

Position div B on top of div A

Hi I'm struggling with this issue.
Desktop:
Div A
Div B
But in responsive the divs have to change their position like this:
Responsive:
Div B
Div A
I made a jsfiddle:
#a {
height: 50px;
width: 100%;
background-color: red;
}
#b {
height: 50px;
width: 100%;
background-color: green;
}
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
Is this possible?
You can use grid-row from CSS grid layout
section {
display: grid;
grid-auto-rows: minmax(50px, auto)
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#media (max-width:768px) {
#b {
grid-row: 1
}
}
<section>
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
</section>
Alternatives:
use order with also CSS grid layout
section {
display: grid;
grid-auto-rows: minmax(50px, auto)
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#media (max-width:768px) {
#b {
order: -1
}
}
<section>
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
</section>
use column-reverse from flexbox layout (as suggested by #G-Cyr in comments below)
section {
display: flex;
flex-direction: column;
}
div {
height: 50px;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#media (max-width:768px) {
section {
flex-direction: column-reverse;
}
}
<section>
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
</section>
use flex-wrap/wrap-reverse with flexbox layout
section {
display: flex;
flex-wrap: wrap
}
div {
height: 50px;
flex: 0 100%
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#media (max-width:768px) {
section {
flex-wrap: wrap-reverse
}
}
<section>
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
</section>
use order with flexbox layout
section {
display: flex;
flex-direction: column;
}
div {
height: 50px;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#media (max-width:768px) {
#b {
order: -1
}
}
<section>
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
</section>
If you need to support older browsers, you can do it this way as well. But this only works if the elements have a fixed height, otherwise you will have to play some other games.
#a {
height: 50px;
width: 100%;
background-color: red;
}
#b {
height: 50px;
width: 100%;
background-color: green;
}
#media (max-width:768px) {
#a {
position: relative;
top: 50px;
}
#b {
position: relative;
top: -50px;
}
}
<div id="a">
div 1
</div>
<div id="b">
div2
</div>
Here is another answer with 2 selector and a single rule :transform:scale(-1);
/* target the container and its direct-child */
div,
div>* {
transform: scale(-1);
}
#media (min-width:768px) {
div,
div>* {
transform: scale(1);
}
#a del {
text-decoration: none;
}
#a ins {
display: none;
}
<div>
<h1 id="a">HTML Ipsum Present<del>s</del><ins>ed</ins></h1>
<p id="b"><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
</div>

How to make flexbox items with custom widths jump to available space

I'm trying to achieve Pinterest-like layout, but with items of different percentage widths. Expected behaviour is pretty much like Javascript masonry plugin.
My flexbox code for some reason does not nake flexbox items jump side-by-side to another, event, when exact space is available.
Illustration of what I'm trying to achieve
demo on jsfiddle
https://jsfiddle.net/31v7et9f/1/
html
<div class="masonry">
<div class="item-1-4">item 25%</div>
<div class="item-1-1">item 100%</div>
<div class="item-3-4">item 75%</div>
<div class="item-1-2">item 50%</div>
<div class="item-1-2">item 50%</div>
<div class="item-1-1">item 100%</div>
</div>
css
* {box-sizing: border-box;}
/* parent */
.masonry {
display: flex;
flex-flow: column;
}
/* childs */
.masonry > div {
background: gray;
outline: solid 1px black;
height: 100px;
}
/* child sizes */
.item-1-1 {width: 100%;}
.item-3-4 {width: 75%;}
.item-1-2 {width: 50%;}
.item-1-4 {width: 25%;}
Flexbox items are by default layed out in the order they appear in the html. So, using your html and using flex-flow: row wrap; you'll get your 2 50%s side by side, but not your 75% and 25%.
/* parent */
.masonry {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
You could rearrange your html (do some math in javascript to determine which order they should be in to tile).
<div class="masonry">
<div class="item-1-1">item 100%</div>
<div class="item-1-4">item 25%</div>
<div class="item-3-4">item 75%</div>
<div class="item-1-2">item 50%</div>
<div class="item-1-2">item 50%</div>
<div class="item-1-1">item 100%</div>
</div>
You could also use order to group items that should be able to tile, though it's not perfect
/* child sizes */
.item-1-1 {
width: 100%;
-webkit-order: 1;
order: 1;
}
.item-3-4 {
width: 75%;
-webkit-order: 2;
order: 2;
}
.item-1-2 {
width: 50%;
-webkit-order: 3;
order:3;
}
.item-1-4 {
width: 25%;
-webkit-order: 2;
order:2;
}
https://jsfiddle.net/31v7et9f/2/
We can use flex-wrap: wrap; align-items: flex-stat; in parent flex class and child we can use flex: 1 auto; so that it consider available space and align automatically.
.fill-height-or-more {
min-height: 100%;
display: flex;
flex-wrap: wrap;
align-items: flex-stat;
}
.fill-height-or-more
div {
flex: 1 auto;
display: flex;
flex-direction: column;
justify-content: center;
}
.some-area
div {
padding: 1rem;
}
.some-area
div:nth-child(1) {
background: rgba(136, 204, 102, 1);
}
.some-area
div:nth-child(2) {
background: rgba(121, 181, 210, 1);
}
.some-area
div:nth-child(3) {
background: rgba(140, 191, 217, 1);
}
.some-area
div:nth-child(4) {
background: rgba(159, 202, 223, 1);
}
.some-area
div:nth-child(5) {
background: rgba(179, 213, 230, 1);
}
.some-area
div h1, .some-area
div h2 {
margin: 0 0 0.2rem 0;
}
.some-area
div p {
margin: 0;
}
html, body {
height: 100%;
}
<section class="some-area fill-height-or-more">
<div>
<h1>Boxes That Fill Height (or more)</h1>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>
<div>
<h2>Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error ut.</p>
</div>
<div>
<h2>Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error ut.</p>
</div>
<div>
<h2>Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error ut.</p>
</div>
<div>
<h2>Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error ut.</p>
</div>
</section>

Resources