Align baselines of items inside a flexbox - html

I'm basically trying to get the baseline of the value to align with the baseline of the bottom unit instead of the first as it's happening in my code below.
I can get it to work if I ditch flexbox altogether but I need it for responsiveness.
The canonical advice seems to be to wrap flex items in inline-block but, as you can see from that codepen, it doesn't seem to work for me.
Here's the codepen where I've been trying stuff: https://codepen.io/jskrt/pen/OJyXxyv
.value_and_unit {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: baseline;
}
.value {
line-height: 1;
font-size: 120px;
margin-right: 10px;
}
.unit_container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: center;
}
.divider {
width: 100%;
}
.inline-block {
display: inline-block;
}
<div class="value_and_unit">
<span class="value">
340
</span>
<div class="unit_container">
<span class="unit">
m
</span>
<hr class="divider" />
<span class="unit">
s
</span>
</div>
</div>

Try the following:
.value_and_unit {
display: flex;
/* flex-flow: row nowrap; */
/* justify-content: flex-start; */
/* align-items: baseline; */
}
.value {
font-size: 120px;
margin-right: 10px;
line-height: 1;
}
Tell me if this is the desired effect, and if not, tell me what is the problem, so I have a clue to follow. Good luck!
EDIT: Replace the <h1> tag with <div> because browsers add line-height, margin and other properties to it by default! Style the item as desired, by adding bold by yourself. Keep in mind that h1 is a semantic tag with high weight and should not be used when not required!!!
EDIT2: I forgot to mention that I worked with the code in real environment and not in the code pen and everything seemed well if I understood your problem correctly. Try it yourself in real server too, if there is a problem with the codepen.

If the .value element will contain numbers only, then you can probably get away with a simple adjustment to the line-height. Make it bit smaller, so that the line box shrinks-to-fit the font height.
.value_and_unit {
display: flex;
border: 1px solid red; /* demo */
}
.value {
line-height: .75; /* key adjustment */
font-size: 120px;
margin-right: 10px;
}
.unit_container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: center;
}
.divider {
width: 100%;
}
<div class="value_and_unit">
<span class="value">340</span>
<div class="unit_container">
<span class="unit">m</span>
<hr class="divider" />
<span class="unit">s</span>
</div>
</div>
However, this method won't work if the .value element contains random letters, because the extra space above and below the numbers exists to accommodate descenders and ascenders.
In such case, you would need to try another method. align-items: flex-end would work (i.e. the visual baselines would be aligned), but the units would align below the numbers in this case.
.value_and_unit {
display: flex;
align-items: flex-end;
border: 1px solid red;
padding: 5px;
}
.value {
font-size: 120px;
margin-right: 10px;
border: 1px dashed blue;
}
.unit_container {
display: flex;
flex-flow: column nowrap;
align-items: center;
border: 1px dashed blue;
}
.divider {
width: 100%;
}
<div class="value_and_unit">
<span class="value">340jÁ </span>
<div class="unit_container">
<span class="unit">m</span>
<hr class="divider" />
<span class="unit">s</span>
</div>
</div>
So, because you want the "s" baseline aligned with the numbers' baseline, you're not actually seeking baseline alignment (because the true baseline of the larger box is under the "j"). You want an arbitrary alignment, so an adjustment to the line-height may be appropriate in this case.

Try to make the align-items value to end. It is like this
align-items: end;

Related

Center a paragraph element when text wraps without centering the text using flex

Before this gets down-voted into oblivion, let me say I've searched through the numerous SO questions that looked similar to this one, but none that I found addressed my issue.
I'm using flexbox to center some <p> tags both horizontally and vertically within an element. I don't want to center the text within the <p> element, just center the <p> elements themselves.
.app-outer {
display: flex;
flex-direction: column;
}
.app {
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
align-items: center;
}
.app p {
display: inline-block;
}
.title-bar {
background-color: #202225;
color: #72767D;
font-weight: bold;
padding: 0 0 2px 8px;
display: flex;
flex-direction: row;
width: 100%;
}
<div class="app-outer">
<div class="title-bar">
<span class="draggable">Skipwars</span>
<span class="btns">
<button id="btn-minimize" tabindex="-1">-</button><!--
--><button id="btn-close" tabindex="-1">×</button>
</span>
</div>
<div class="app">
<p>Add a browser source pointed at <!--http://localhost:3333/--></p>
<p>
Optional parameter <code style="display:inline">threshold=n</code>. ex: http://localhost:3333/?threshold=4 (default 8)
</p>
</div>
</div>
My app is 300px wide (I'm using electron).
As you can see, if the paragraph doesn't have enough text for multiple lines, it works fine. If it does, the paragraph expands to the width of .app, and the text is left-justified.
This is what I'm looking for:
I thought that setting the paragraphs' display to inline-block would do the trick, but it doesn't.
It's working as expected, but since the <p> tags are the same width as the viewport, they are flush to the left when the vp is too small, and in this case the url is so long that it wraps to the next line and leaves a space on the first, making it appear that it is not centered. I added some horizontal padding to the <p> tags to better illustrate:
.app-outer {
display: flex;
flex-direction: column;
}
.app {
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
align-items: center;
}
.app p {
display: inline-block;
padding: 0 20px;
}
.title-bar {
background-color: #202225;
color: #72767D;
font-weight: bold;
padding: 0 0 2px 8px;
display: flex;
flex-direction: row;
width: 100%;
}
<div class="app-outer">
<div class="title-bar">
<span class="draggable">Skipwars</span>
<span class="btns">
<button id="btn-minimize" tabindex="-1">-</button><!--
--><button id="btn-close" tabindex="-1">×</button>
</span>
</div>
<div class="app">
<p>Add a browser source pointed at
<!--http://localhost:3333/--></p>
<p>
Optional parameter <code style="display:inline">threshold=n</code>. ex: http://localhost:3333/?threshold=4 (default 8)
</p>
</div>
</div>

Flexbox content not spreading evenly with links and images

I'm using flex to build footer. I want the footer to be 60% of the width of the website and centered which is working perfectly. When I add content into the footer of text, links, and image links and try to justify space-evenly it doesn't work properly and there is a lot of extra white space on the right side within the footer. How do I remove it?
Footer
CSS
.site-wide-footer {
display: flex;
flex-wrap: wrap;
width: 60%;
height: auto;
border: 2px solid black;
border-radius: 24px;
color: white;
background-color: black;
margin: auto;
justify-content: space-between;
align-items: center;
}
HTML
<footer>
<div class="site-wide-footer">
<p>© 2018 copyright</p>
<p> ♦STORE</p>
<p>♦ABOUT US</p>
<p>♦SITEMAP</p>
<div class="social-footer">
<p><a href="discord url">
<img src="images/Discord-Logo-White.png" alt="Discord Logo"
class="discord-footer" onmouseover="hover(this);"
onmouseout="unhover(this);"></a>
<a href="facebook url/"><img
src="images/facebook-icon.png" alt="Facebook Icon" class="facebook-
footer"></a></p>
</div>
</div>
</footer>
How about using justify-content: space-evenly; instead? It will also make sure the the child elements are still centered even when it is wrapped over to the next line.
I think you might want to consider setting a flex rule for the flex-box children.
I'm not sure I understand what exactly you try to achive, but if you play with this flex rule, you can achieve a lot.
.site-wide-footer {
display: flex;
flex-wrap: wrap;
width: 60%;
height: auto;
border: 2px solid black;
border-radius: 24px;
color: white;
background-color: black;
margin: auto;
justify-content: space-around; /*you can play with it*/
align-items: center;
padding: 0 15px 0; /*fixed space on left and right of the flex-box*/
}
.site-wide-footer > { /*flex-box children */
flex: 1 0; /*play with this one a bit. you could also give it a minimum width like that: flex: 1 0 100px;*/
}`
And of course, you may find all the answers on this Complete Guide to Flexbox
Itamar

Vertical-align doesn't work on flex item

I tried to vertically centralize plain text inside a flex box element.
I decided to use property display:table-cell with vertical-align: middle. But it doesn't seem to work properly in flexbox elements.
How can I centralize it vertically, ideally without using a wrapper or positioning, and while still truncating long text with ellipses?
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: table-cell;
vertical-align: middle;
flex: 1 1;
background-color: cyan;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello, I'm very very long string! Hello, I'm very very long string!</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
View On CodePen
One solution is to define each flex item as its own flex container in order to vertically center its contents with align-items:center. To keep text-overflow working, add a child element to each flex item, which can then be truncated with ellipses.
I can't offer a succinct explanation as to why text-overflow doesn't work with display:flex, and neither can David Wesst. In his words:
It turns out that there really isn't a clean way to do this. If you're wondering how I came to that conclusion you can stop because I didn't. Those responsible for the specification did, and you can read the full conversation that started with a Mozilla bug report and leads to a whole mail group discussion about why it should (or, in this case, should not) be implemented as part of the spec.
Here's a working example:
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: flex;
align-items: center;
flex: 1;
background-color: cyan;
}
.item span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item"><span>Hello, I'm very very long string! Hello, I'm very very long string!</span></div>
<div class="item"><span>Hello</span></div>
<div class="item"><span>Hello</span></div>
<div class="item"><span>Hello</span></div>
</div>
Also see:
Setting ellipsis on text from a flex container
When you make an element a flex container (with display: flex or display: inline-flex), all in-flow children become flex items.
All flex items have their display value controlled by the container. It doesn't matter what you specify, the container overrides it.
So when you give a flex item display: table-cell, the browser ignores it. Here's what it looks like in Chrome Dev Tools:
Style Tab
Computed Tab
A flex container "blockifies" flex items, causing them to assume many qualities of block-level elements (source).
But the vertical-align property applies only to inline-level and table-cell elements (source).
That's why it doesn't work.
Regardless, vertical-align, even if it worked, is a totally unnecessary hack in this case. There are flex properties designed for aligning content in flex items.
.container {
width: 500px;
height: 500px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
flex: 1 1;
display: flex;
justify-content: center; /* horizontal alignment, in this case */
align-items: center; /* vertical alignment, in this case */
background-color: cyan;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
Related posts:
How to vertically align text inside a flexbox?
Setting ellipsis on text from a flex container
Blockquote ...float, clear and vertical-align have no effect on a flex item.
according to https://css-tricks.com/snippets/css/a-guide-to-flexbox/
See How to vertically align text inside a flexbox? for a possible solution.
You have to define those items also as flex containers, using the following CSS for them (no table-cell display...):
display: flex;
flex-direction: column;
justify-content: center;
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1 1;
background-color: cyan;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello, I'm very very long string! Hello, I'm very very long string!</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>

CSS button like vertical align feature

Pre History
I am building html form, with elements having multiple options ...., but instead of showing it as dropdown, i would like to show them as buttons without using any js, I removed buttons with label pointing to input checkbox.
Problem
I need label (or anchor or div) tag behave exactly like button tag without any extra wrapper tags, I googled all variation doesn't provide same result as native tag button.
<button class="button">
Text
<div>Small Text</div>
</button>
Solutions not work
line-height, padding does not provide same functionality, because button height/width and text length may vary. I tried special webkit style -webkit-appearance: button; no changes.
Mustery Flex
I tried flex
.button {
flex-wrap: wrap;
align-items: center;
justify-content: center;
display: inline-flex;
}
<div class="button">
Text
<div>Small Text</div>
</div>
but child div inside button not breaking/warping to new line.
p.s Environment tested, Google Chrome, Safari
I found solution using flex with flex-direction: column; so text and div treats like column items, here is code
label.button {
flex-direction: column;
justify-content: center; /* <-- actual veertical align */
display: inline-flex;
text-align:center;
}
JS Fiddle Demo
Does this does the job ?
div.button {
align-items: center;
text-align: center;
display: inline-block;
border: 1px solid black;
}
div.button div {
clear: both;
}
<div class="button">
Text
<div>Small Text</div>
</div>
Ghost element trick looks work well.
.wrap {
text-align: center;
background: #ededed;
margin: 20px;
}
.wrap:before {
content: '\200B';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.centered-guy {
display: inline-block;
vertical-align: middle;
width: 300px;
padding: 10px 15px;
border: #777 dotted 2px;
background: #666;
color: #fff;
}
<div class="wrap" style="height: 512px;">
<div class="centered-guy">
<h1>Some text</h1>
<p>Bool!<br>Look at me, mama!</p>
</div>
</div>

flex space-between doesn't work

I'm trying to center horizontally (img - .info - img) using space-between property. I'm facing a little issue the space-between doesn't add spaces between elements.
I know I'm missing something but I can't figure it out!
HTML:
<ul>
<li class="box-match">
<a href="#">
<img src="http://lorempixel.com/20/21" class="team1" alt="">
<div class="info">
<span class="time">10:30</span>
<span class="score">0-2</span>
</div>
<img src="http://lorempixel.com/20/20" class="team2" alt="">
</a>
</li>
</ul>
CSS:
a{
text-decoration: none;
width: 98px;
height: 40px;
display: flex;
flex-flow: row no-wrap;
align-items: center;
align-content: space-between;
background-color: lightgray;
}
.info{
text-align: center;
display: block;
width: 40px;
}
ul{
list-style: none;
}
http://codepen.io/eldev/pen/EaQJvR?editors=110
You are looking for justify-content: space-between.
Updated Example
MDN justify-content
The CSS justify-content property defines how a browser distributes available space between and around elements when aligning flex items in the main-axis of the current line. The alignment is done after the lengths and auto margins are applied, meaning that, if there is at least one flexible element, with flex-grow different than 0, it will have no effect as there won't be any available space.
a {
text-decoration: none;
width: 98px;
height: 40px;
display: flex;
flex-flow: row no-wrap;
align-items: center;
justify-content: space-between;
background-color: lightgray;
}
In my case one of the flex items had a margin-left: 100px; set. Removing it fixed the problem.
Try to add a width to your ul, if no width no space to let between.