I'm trying to use flexbox to build a responsive grid of equally sized cells. My code works if the contents of the cells is the same, but does not if the contents of the cells varies in length - the cells re-adjust to accommodate their content.
Here's what I'm after:
1. every cell is the same width
2. each cell's width auto-adjusts when the browser is resized.
Here's my code on fiddle: https://jsfiddle.net/v0erefnd/1/
html:
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">100</div>
<div class="flex-item">10,000</div>
<div class="flex-item">1,000,000</div>
<div class="flex-item">100,000,000</div>
<div class="flex-item">10,000,000,000</div>
<div class="flex-item">1,000,000,000,000</div>
</div>
<div class="flex-container">
<div class="flex-item">100</div>
<div class="flex-item">100</div>
<div class="flex-item">100</div>
<div class="flex-item">100</div>
<div class="flex-item">100</div>
<div class="flex-item">100</div>
<div class="flex-item">100</div>
</div>
css:
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row;
justify-content: space-around;
height: 50px;
line-height:30px;
}
.flex-item {
/*todo: how to prevent the flexbox to resize to accommodate the text?*/
background: tomato;
margin: 10px 5px;
color: white;
font-weight: bold;
font-size: 1.5em;
text-align: center;
flex-grow: 1;
overflow: hidden;
}
Thanks!
If you want all of the flexbox items to have the same width, you could add flex-basis: 100%:
Updated Example
.flex-item {
background: tomato;
margin: 10px 5px;
color: white;
font-weight: bold;
font-size: 1.5em;
text-align: center;
flex-basis: 100%;
overflow: hidden;
}
Related
I'm constructing a simple layout with a title and sub-title. When the two can be displayed on one line without the text wrapping, they should do so with a small amount of spacing between them. In all other cases, the title and sub-title should occupy 100% width. There should be no margin-left on the sub title.
I have created this using Flexbox and the gap property. It renders properly in Firefox:
Here's the code:
header {
font-family: sans-serif;
background-color: rebeccapurple;
color: #fff;
padding: 0 5px;
}
.container {
max-width: 800px;
width: 100%;
flex-grow: 1;
margin-left: auto;
margin-right: auto;
}
header .container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
gap: 0.5rem;
align-items: baseline;
}
<header>
<div class="container">
<h1>Long title for the page itself</h1>
<h2>Subtitle</h2>
</div>
</header>
<br />
<header>
<div class="container">
<h1>Shorter title</h1>
<h2>Subtitle</h2>
</div>
</header>
Unfortunately, popular browsers such as Google Chrome have failed to implement support for gap used in conjunction with a display: flex layout.
Is there a way I can implement this using e.g. display: inline-block elements and negative margins such that it will work in legacy browsers like Chrome and Internet Explorer?
Instead of gap: .5rem, use margin-right: .5rem on the h1.
h1 {
margin-right: .5rem;
}
.container {
max-width: 800px;
margin-left: auto;
margin-right: auto;
display: flex;
flex-wrap: wrap;
align-items: baseline;
}
header {
font-family: sans-serif;
background-color: rebeccapurple;
color: #fff;
padding: 0 5px;
}
<header>
<div class="container">
<h1>Long title for the page itself</h1>
<h2>Subtitle</h2>
</div>
</header>
<br />
<header>
<div class="container">
<h1>Shorter title</h1>
<h2>Subtitle</h2>
</div>
</header>
This question already has answers here:
CSS3 box-sizing property
(5 answers)
Closed 4 years ago.
I know this question has been asked several times and the solution is flex-wrap: wrap but for some reason this doesnt work in my code.
Could anyone briefly help me why my divs aren't wrapping?
I basically need always 2 divs next to eachother in a row and then to wrap.
JSFIDDLE: enter link description here
.wrapper {
display: flex;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-box;
flex-wrap: wrap;
}
.box {
flex: 50%;
text-align: center;
padding-bottom: 10px;
color: #8988DB;
flex-wrap: wrap;
border: 1px solid black;
}
<div class="wrapper">
<div class="box"><br>Valerian Root</div>
<div class="box"><br>Lavender</div>
<div class="box"><br>Lemon Balm</div>
<div class="box"><br>Chamomile</div>
<div class="box"><br>Passion Flower</div>
<div class="box"><br>Hops</div>
<div class="box"><br>Rooibos</div>
<div class="box"><br>Cinnamon</div>
</div>
Thanks so much!
Alpha
As a note, in the CSS rule for the flex container, place the regular display: flex property after all the prefix-versions.
For it to work also in IE11, use width: 50% instead of flex: 50%, combined with box-sizing: border-box, where borders/padding gets included in the set width.
.wrapper {
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-box;
display: flex;
flex-wrap: wrap;
}
.box {
box-sizing: border-box;
width: 50%;
padding: 0 30px 10px;
text-align: center;
color: #8988DB;
border: 1px solid black;
}
<div class="wrapper">
<div class="box"><br>Valerian Root</div>
<div class="box"><br>Lavender</div>
<div class="box"><br>Lemon Balm</div>
<div class="box"><br>Chamomile</div>
<div class="box"><br>Passion Flower</div>
<div class="box"><br>Hops</div>
<div class="box"><br>Rooibos</div>
<div class="box"><br>Cinnamon</div>
</div>
Step into CSS Grid, it's ideal for this use case. Your use case is so simple, you only need three lines of CSS to pull it off.
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr; // creates two responsive columns
grid-gap: 10px; // puts 10px between each node in the grid
}
Looks like all you need is a proper CSS reset, specifically, the box-sizing property so that borders are not included in the width calculations.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
display: flex;
flex-wrap: wrap;
}
.box {
flex: 50%;
text-align: center;
padding-bottom: 10px;
color: #8988DB;
border: 1px solid black;
}
<div class="wrapper">
<div class="box"><br>Valerian Root</div>
<div class="box"><br>Lavender</div>
<div class="box"><br>Lemon Balm</div>
<div class="box"><br>Chamomile</div>
<div class="box"><br>Passion Flower</div>
<div class="box"><br>Hops</div>
<div class="box"><br>Rooibos</div>
<div class="box"><br>Cinnamon</div>
</div>
I'm trying to make my css with flexbox, so I followed some articles and tried to set my elements like this example:
the elements 1 & 2 are in another container
I'm trying to set the two elements (1 and 3) to be next each other as the second example (The first is what I have now and the other is what I'm trying to achieve.)
but I can't find a good way with the Flexbox since I set the container to flex-direction: column;
<div class="container">
<div class="sub-ctn">
<h5 class="1"><span>♦ </span>{{ text }}</h5>
<span class="2">{{ value }}</span>
<div class="3">
<h5>{{ text }}
</div>
</div>
</div>
CSS:
.container {
margin-right: 2.5%;
direction: rtl;
}
.sub-ctn {
display: flex;
flex-flow: row;
margin-top: 1%;
flex-direction: column;
}
.1 {
width: 100%;
direction: rtl;
text-align: right;
}
.2 {
float: right;
/* text-align: right; */
}
.3 {
margin-left: 1%;
display: flex;
flex-direction: column;
}
let me know if another information is needed
Don't use float and flex together. Flex alone will be much easier and better.
.cont{
display: flex;
width: 80%;
border: 1px solid black;
padding: 10px;
}
.left-cont{
height: 100%;
flex-grow: 1;
}
.right-cont{
flex-grow: 1;
display: flex;
flex-direction: column;
}
.item{
text-align: center;
border: 1px solid black;
margin: 3px;
}
<div class="cont">
<div class="left-cont">
<div class="item">3</div>
</div>
<div class="right-cont">
<div class="item">1</div>
<div class="item">2</div>
</div>
</div>
I've been working on learning flexbox for layout and have been unable to figure out why text is not wrapping inside the flex-item. The text is breaking out of the container like this:
html,
body {
height: 100%;
}
.main {
max-width: 10em;
margin: 1em auto;
}
.flex-row {
display: flex;
align-items: center;
justify-content: center;
min-height: 12em;
border: 1px solid red;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-item {
padding: 5px;
border: 1px solid black;
}
<div class="main">
<div class="flex-row">
<div class="flex-column">
<div class="flex-item">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>
<div class="flex-item">
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
</div>
</div>
</div>
</div>
There are no spaces between your text.
The default value of the word-break property is normal, meaning that a continuous line of text has no line breaks.
For these reasons, your text is not wrapping and overflowing the container.
Add word-break: break-all to .flex-item.
html,
body {
height: 100%;
}
.main {
max-width: 10em;
margin: 1em auto;
}
.flex-row {
display: flex;
align-items: center;
justify-content: center;
min-height: 12em;
border: 1px solid red;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-item {
padding: 5px;
border: 1px solid black;
word-break: break-all; /* new */
}
<div class="main">
<div class="flex-row">
<div class="flex-column">
<div class="flex-item">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>
<div class="flex-item">
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
</div>
</div>
</div>
</div>
From MDN:
word-break
The word-break CSS property specifies whether or not the browser
should insert line breaks wherever the text would otherwise overflow
its content box.
In contrast to overflow-wrap, word-break will create a break at
the exact place where text would otherwise overflow its container
(even if putting an entire word on its own line would negate the need
for a break).
Values
normal
Use the default line break rule.
break-all
To prevent overflow, word breaks should be inserted between any two
characters (excluding Chinese/Japanese/Korean text).
keep-all
Word breaks should not be used for Chinese/Japanese/Korean (CJK) text.
Non-CJK text behavior is the same as for normal.
There's actually another reason – flexbox-specific – why the flex items are overflowing the container. Here's the explanation:
Why doesn't flex item shrink past content size?
To contain the items (without the need for the text to wrap), you could apply min-width: 0, overflow: hidden or overflow: auto to .flex-column.
html,
body {
height: 100%;
}
.main {
max-width: 10em;
margin: 1em auto;
}
.flex-row {
display: flex;
align-items: center;
justify-content: center;
min-height: 12em;
border: 1px solid red;
}
.flex-column {
display: flex;
flex-direction: column;
overflow: hidden; /* new */
/* overflow: auto; */
/* min-width: 0; */
}
.flex-item {
padding: 5px;
border: 1px solid black;
}
<div class="main">
<div class="flex-row">
<div class="flex-column">
<div class="flex-item">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>
<div class="flex-item">
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
</div>
</div>
</div>
</div>
So I've got this header with three elements in them.
What I want is basically this:
http://jsfiddle.net/zktbfmqo/2/
Only with vertically centered content in each of the divs as well.
Is there an easy and clever way to do this without using absolutes etc?
Vertical-align: middle doesn't seem to do much, but that property isn't always easy to work with either.
HTML:
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
CSS:
#container {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
min-width: 612px;
}
.box1, .box2, .box3 {
width: 150px;
height: 125px;
vertical-align: middle;
display: inline-block;
*display: inline;
zoom: 1;
text-align: center;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 0;
line-height: 0
}
First you can achieve the same result in a better way by using Flexbox.
For vertical align text to the middle you can simply approach that by adding the line-height property and set it to the same exact height of the container div so in your case it would be 125px or if you used flexbox it can be done with align-items: center , and here is the final code:
.wrapper {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row nowrap; /* Safari 6.1+ */
flex-flow: row nowrap;
-webkit-justify-content: space-between; /* Safari 6.1+ */
justify-content: space-between;
font-weight: bold;
height: 125px;
min-width: 612px;
padding: 5px;
border: 2px dashed #444;
}
.wrapper > div{
display: -webkit-flex;
display: flex;
-webkit-flex-basis: 150px;
flex-basis: 150px;
justify-content: center;
align-items: center;
}
.aside-1, .aside-3{
background: #ccc
}
.aside-2{
background: #0ff;
}
<div class="wrapper">
<div class="aside aside-1">text1</div>
<div class="aside aside-2">text2</div>
<div class="aside aside-3">text3</div>
</div>
Flexbox to the rescue!
Good resources:
https://philipwalton.github.io/solved-by-flexbox/
https://github.com/philipwalton/flexbugs
#container {
display: flex; /* magic maker */
justify-content: space-between; /* set equal space between boxes */
border: 2px dashed #444;
height: 125px;
/* just for demo */
min-width: 612px;
}
.box1, .box2, .box3, .box4 {
display: flex; /* magic maker */
/*
shorthand for flex-grow, flex-shrink, and flex-basis properties
we don't want the boxes to grow or shrink, and the basis is the explicit
width we want them
*/
flex: 0 0 150px;
justify-content: center; /* horizontally center text within */
align-items: center; /* vertically center text within */
height: 125px;
}
.box1, .box3 {
background: #ccc
}
.box2, .box4 {
background: #0ff
}
<div id="container">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
</div>
you can use display:table/table-cell and using a workaround with border-collapse/spacing + margin you will get the desired output.
#wrap {
border: 2px dashed #444;
height: 125px;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
overflow:hidden;
/* just for demo */
width: 612px;
}
#container {
margin: 0 -81px; /*must be equal to border-spacing */
}
#table {
display: table;
table-layout: fixed;
border-collapse: separate;
border-spacing: 81px 0;
width: 100%;
}
.box1,
.box2,
.box3,
.box4 {
width: 150px;
height: 125px;
vertical-align: middle;
display: table-cell;
text-align: center;
}
.stretch {
width: 100%;
vertical-align: middle;
display: table-cell;
}
.box1,
.box3 {
background: #ccc
}
.box2,
.box4 {
background: #0ff
}
<div id="wrap">
<div id="container">
<div id="table">
<div class="box1">Text</div>
<div class="box2">Text</div>
<div class="box3">Text</div>
<span class="stretch"></span>
</div>
</div>
</div>
Are you familiar with Bootstrap?
It is a CSS Framework made by Twitter.
Put this inside of your head -
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
Use this in your body to see what it does, there's great docs on it.
<div class="container"> <!-- Creates margin -->
<div class="row"> <!-- Read docs on rows, they're awesome! -->
<div class="col-lg-4"> <!-- 1 -->
<!-- Just to take up space -->
</div>
<div class="col-lg-4"> <!-- 2 -->
<!-- YOUR CONTENT GOES HERE -->
</div>
<div class="col-lg-4"> <!-- 3 -->
<!-- Just to take up space -->
</div>
</div> <!-- ./row -->
</div> <!-- ./container -->
Now inside of the 2nd ./col-lg-4 div all of that content will be perfectly centered in the screen with the text aligned left.
If you want to align center the text, replace
<div class="col-lg-4"> <!-- 2 -->
with
<div class="col-lg-4 text-center"> <!-- 2 -->
Hope this helps!