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>
Related
Note: NOT a duplicate of :
Flexbox displays divs incorrectly rather than making the container scrollable
Can't scroll to top of flex item that is overflowing container
My use-case attempts to center the overflowing items. Solutions acknowledge this limitation, without solving it. (Their items are not centered)
Imagine if Netflix presented their choices with the middle item positioned in the center of the screen. That's the effect I'm going for with my columns sroller, but my first item is partially cut off. I found a solution on SO using jQuery, but I'd rather wrestle CSS into submission. Need to tag one of you in though... got any ideas?
* {
font-family: sans-serif;
}
.options-wrapper {
font-size: 3vw;
text-align: center;
}
.options-wrapper .options-visualized {
display: flex;
flex-wrap: nowrap;
overflow-x: scroll;
justify-content: center;
margin: 0 auto;
}
.options-wrapper .options-visualized .option {
flex-basis: 40vw;
flex-shrink: 0;
margin: 0 8vw;
display: flex;
flex-direction: column;
}
.options-wrapper .options-visualized .option:first-of-type {
margin-left: 2vw;
}
.options-wrapper .options-visualized .option:last-of-type {
margin-right: 2vw;
}
.options-wrapper .options-visualized .option img {
width: 100%;
margin: 0 auto;
}
.options-wrapper .options-visualized .option .option-label {
margin-top: 1em;
flex-basis: 100%;
font-size: 0.92em;
line-height: 1.25;
}
.options-wrapper .options-visualized .option .option-label span {
display: block;
}
<div class="options-wrapper graded-bg">
<h6 class="options-title">options:</h6>
<div class="options-visualized">
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 1</span></div>
</div>
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 2</span></div>
</div>
<div class="option">
<img src="https://cdn.pixabay.com/photo/2020/03/19/23/32/willow-catkin-4949064_960_720.jpg">
<div class="option-label"><span class="name">Option 3</span></div>
</div>
</div>
</div>
Here's a pen: https://codepen.io/sashaikevich/pen/yLgbWQx
I just edited &:last-of-type to be like this :
&:last-of-type {
margin-right: -56vw;
}
Try this Example to know what I mean :
https://codepen.io/kevinmmansour/pen/VwPrJGw
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>
In the current Firefox (50), when the two items in the header wrap below 715px, the lower item extends below the header's height. I have played with the flex shorthand statements of each item, and min-widths, and tried a #media query for a screen with that max-width, and can't get it to stop. The page is here.
The CSS:
header {
display: flex;
flex-flow: row-reverse wrap;
justify-content: space-around;
height: 320px;
padding: 20px 0;
}
.sec1 {
flex: 4 2 200px;
min-width: 200px;
padding-right: 6vw;
padding-left: 3vw;
margin-top: 2vw;
#media only screen and (max-width: 1350px) {
flex: 6 1 0;
margin-top: 6vw;
}
}
.sec2 {
align-self: center;
flex: 7 0 250px;
display: flex;
flex-direction: row-reverse;
justify-content: flex-start;
p {
width: 40%;
text-align: right;
margin-right: 30px;
margin-bottom: 25px;
align-items: flex-start;
}
}
.accent {
font-size: 20px;
color: #967832;
line-height: 24px;
background: rgba(0, 0, 0, 0.7);
border-radius: 50px;
border: 8px solid black;
padding: 12px;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
align-items: stretch;
}
section {
display: box;
display: flex;
padding: 15px;
flex: 1 0 350px;
margin-top: 3vw;
margin-left: 6vw;
}
<header>
<div class="sec1">
<img src="http://www.moonwards.com/img/MWLogo-for-black-bckgnd.svg" alt="Moonwards" id="logo">
</div>
<div class="sec2">
<p class="accent">What would it really be like
<br>to live on the Moon?</p>
</div>
</header>
<div class="container">
<section>
<div class="outerDiv">
<div class="innerDiv intro">
<h1>Realistic Lunar Colony, Coming Online</h1>
<p>
This project is building a series of virtual colonies on the Moon. They will be richly detailed and interactive presentations that are entirely plausible, technically and scientifically. They will examine all the questions, consider all the implications.
When humanity undertakes ventures on the scale of space settlement, it matters a great deal how many people have given it real thought beforehand. These colonies serve that purpose.
</p>
</div>
</div>
</section>
<aside>
<div class="sideDiv"id="RSS-feed">
<p id="item2" class="atom"><span class="datetime">Mon, 07 Nov 2016 19:50:00 GMT</span><span class="title">Lalande map</span><span class="description">Kim has finished composing an extremely detailed map of the Lalande crater. It is a huge file, but available at request.</span>
</p>
</div>
The issue seems to be that Firefox isn't considering the height of the container when wrapping. What is the way to stop the overflow?
Your code is overly complex. Much of it can be safely removed. Try a process of elimination to pinpoint the problem.
Here's a revised version of your code (tested on Chrome & FF):
<header>
<img id="logo" src="http://www.moonwards.com/img ... svg" alt="Moonwards" id="logo">
<p id="note">What would it really be like<br> to live on the Moon?</p>
</header>
revised codepen
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!
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;
}