How do I remove space between flexbox vertically centred rows? - html

I have two rows, with a heading in the top row, and 2 columns in the bottom row, all vertically centred within a fullscreen wrap. For some reason, I cannot get rid of the extra vertical space that the fullscreen wrap adds in between the two rows, despite adding:
align-content:centre
as well as display: flex to both parent divs (.wrap and .row)
What am I doing wrong?
jsfiddle: https://jsfiddle.net/ar4Ltoke/2/
.wrap {
width: 1280px;
min-height: 100vh;
border-style: solid;
}
.row {
width: 100%;
align-items: flex-start;
margin: auto;
border: 1;
border-style: solid;
}
.column_left {
flex-basis: 60%;
border: 1;
}
.column_right {
flex-basis: 30%;
}
#media (min-width:640px) {
.row {
display: flex;
justify-content: space-between;
}
.wrap {
display: flex;
align-content: center;
flex-direction: column;
}
}
<div class="wrap">
<div class="row">
<p class="blue">About me</p>
</div>
<div class="row">
<div class="column_left">
<p class="leadpara">Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec ullamcorper nulla non metus auctor fringilla. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Fusce dapibus, tellus ac cursus
commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec ullamcorper nulla non metus auctor fringilla. Duis mollis, est non commodo luctus, nisi
erat porttitor ligula, eget lacinia odio sem nec elit. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
</p>
</div>
<div class="column_right">
<p class="leadpara">
Email
<br> Add me on Linkedin
<br> Tweet at #fsd
</p>
</div>
</div>
</div>

Two reasons:
You have margin: auto on .row. That causes both .row flex items to distribute space equally in the container, which forces them to separate.
The .wrap element is a column-direction flex container. That means that the main axis is vertical. As a result, you need justify-content to vertically center the rows.
revised demo
For a more detailed explanation see:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?

Because you are using <br> to change the line due to which extra spaces are created using something else to change the line. You can use a list instead if you want to show them pointwise with list-style-type as none. Please let me know if my answer is not clear. I will send the code if required.

Related

rotating div with text & pseudo element?

I've been working on how to rotate a div with number text and an ::after pseudo element styled into a line. Essentially I've gotten as far as arranging it horizontally (responding to screen width), but I want the text to rotate -90deg, stick to the left side of its container, and for the line to take up the remaining height of the container (but not go outside of the container).
Should look like this:
p {
display: flex;
align-items: center;
font-size: 10vw;
font-weight: bold;
margin: 0;
}
p::after {
content: '';
flex: 1;
margin-left: 1rem;
height: 2px;
background-color: #000;
}
<div class="container">
<div class="num">
<p>01</p>
</div>
</div>
I've tried adding a transform property with rotate and translate, messing with writing-mode properties, but can't seem to get the pseudo element to lengthen dynamically with the changing height (since the container's height changes with screen size). Any tips?
Figured it out, here's the solution (styled with flexbox) for anyone with this weirdly specific problem.
section {
display: flex;
background-color: blue;
}
.wrapper-section {
display: flex;
}
.section-sum {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.vt-line {
height: 100%;
width: 2px;
background-color: #262525;
margin: 0 auto;
}
.num p {
display: inline-block;
align-items: center;
font-size: 5em;
font-weight: bold;
margin: 0;
transform: rotate(-90deg);
}
.wrapper-aboutinfo {
display: flex;
align-items: center;
}
.container-aboutimg img {
display: block;
max-width: 100%;
margin: 0 auto;
}
<section id="about">
<div class="wrapper-section">
<div class="section-sum">
<div class="vt-line"></div>
<div class="num">
<p>01</p>
</div>
</div>
<div class="wrapper-aboutinfo">
<div class="container-aboutimg">
<img src="https://images.pexels.com/photos/3861964/pexels-photo-3861964.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260">
</div>
<div class="info-about">
<h2>Lorem Ipsum</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam volutpat pretium pharetra. Aliquam non ultrices neque. Praesent rhoncus sapien vitae sem ultrices, ut malesuada magna consequat. Mauris eu laoreet justo. Integer tristique porta nibh vitae ultrices. Praesent porta ligula ut nisl pellentesque congue. Sed finibus ut est et lobortis. Pellentesque velit magna, sagittis non lorem at, pulvinar tempor sem. Nam iaculis nisi nec elit efficitur, non varius sapien feugiat.
<br>
<br>
Morbi justo arcu, rhoncus non sagittis eu, faucibus id ipsum. Vivamus augue lectus, venenatis a commodo eget, ullamcorper vel lorem. Vivamus posuere sagittis eros et consectetur. In feugiat gravida lectus sed pulvinar. Etiam dapibus luctus magna, fermentum dapibus mauris vulputate in. Aliquam at massa erat. In tincidunt dictum risus, vel eleifend sem tempor id. </p>
</div>
</div>
</div>
</section>

2-column CSS Flex/Grid for UL

I've spent way too long at work today thinking about this, so I figured I'd ask the internet hive-mind.
I've got a standard <ul> with a number of <li> elements (currently 12 but could vary). I'd like to arrange these into 2 columns of equal width WHILE also not making the <ul> span full block width. The solution also needs to support IE11 unfortunately (no earlier). Any solution needs to also be responsive, so no set non-percentage widths. I've tried a couple different scenarios (you will want to expand snippet to full screen):
Solution 1 (grid):
*{
box-sizing: border-box;
}
div{
display: flex;
justify-content: center;
}
ul{
list-style: none;
margin-top: 0;
margin-bottom: 0;
padding: 0;
display: inline-grid;
grid-template-columns: repeat(2, 1fr);
}
li{
padding: 15px;
}
<div>
<ul>
<li>In maximus viverra scelerisque. Vestibulum dignissim ex non</li>
<li>Sed suscipit, turpis in suscipit consectetur, ante sem.</li>
<li>Ut et mauris et dui gravida fringilla ut.</li>
<li>Nullam iaculis fermentum sodales. Proin commodo eleifend lacus.</li>
<li>Sed molestie, libero at hendrerit sollicitudin, enim nisi.</li>
<li>Mauris a facilisis dolor. Sed pharetra hendrerit dolor.</li>
<li>Sed vitae felis tellus. Quisque sagittis, felis vitae.</li>
<li>Integer et elit metus. Cras congue vestibulum hendrerit.</li>
<li>Fusce suscipit ante sed tristique euismod. Duis quis.</li>
<li>Vestibulum quam felis, fringilla in justo malesuada, tristique.</li>
<li>Integer volutpat quam sed urna iaculis mollis. Maecenas.</li>
<li>Nullam dignissim ipsum vitae finibus dignissim. Nam viverra.</li>
</ul>
</div>
This above solution essentially works perfectly - it arranges the <li>s in 2 columns, the UL is centered in the containing flex div. But of course IE has issues, and while I could use IE prefixes in the old spec, I would still need to manually assign a column/row position for each li which is not possible for a list that could potentially have any number of elements.
Solution 2 (flex):
*{
box-sizing: border-box;
}
div {
display: flex;
justify-content: center;
}
ul {
list-style: none;
margin-top: 0;
margin-bottom: 0;
padding: 0;
display: inline-flex;
flex-wrap: wrap;
}
li {
padding: 15px;
width: 50%;
}
<div>
<ul>
<li>In maximus viverra scelerisque. Vestibulum dignissim ex non</li>
<li>Sed suscipit, turpis in suscipit consectetur, ante sem.</li>
<li>Ut et mauris et dui gravida fringilla ut.</li>
<li>Nullam iaculis fermentum sodales. Proin commodo eleifend lacus.</li>
<li>Sed molestie, libero at hendrerit sollicitudin, enim nisi.</li>
<li>Mauris a facilisis dolor. Sed pharetra hendrerit dolor.</li>
<li>Sed vitae felis tellus. Quisque sagittis, felis vitae.</li>
<li>Integer et elit metus. Cras congue vestibulum hendrerit.</li>
<li>Fusce suscipit ante sed tristique euismod. Duis quis.</li>
<li>Vestibulum quam felis, fringilla in justo malesuada, tristique.</li>
<li>Integer volutpat quam sed urna iaculis mollis. Maecenas.</li>
<li>Nullam dignissim ipsum vitae finibus dignissim. Nam viverra.</li>
</ul>
</div>
While this above solution is technically acceptable (works well enough, including IE11), the issue here is visual appeal. Because the <ul> now spans full width, despite being centered in the containing flex div, the <li>s spaning the 50% with left aligned text leaves a large about of visual white space on the right side of each column (wide screen needed to see extra space).
Solution 3 (tables for IE11):
I'm not going to bother posting a snippet for this one, as it was the least appealing. Essentially it involved targeting IE11 specifically, setting the <ul> to display:table;, setting the <li>s to display:table-cell; float: left; width: 50%; ...long story short, it was a mess that still didn't work visually.
Should I just cut my losses and go with solution 2? I'd really like to get the visual layout of solution 1 if possible... Any ideas?
The display: flex; property will turn the element into a flex container that affects the layout of the direct child elements only, so if it is only on the outer div it is only affecting the layout of the ul that is the direct child. For this reason I added display: flex; to the ul element so the contained child li elements get the flexible layout. A great resource for more info on flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
In order to address the extra white space I added a max-width to the ul less than 100% so the width does not go all the way to the edges, adjust this value as needed. I also changed the padding on the li elements, only padding on the left and right, and added margin-bottom to space them vertically.
Lastly, I recommend you add a class to your div wrapper so you can target everything contextually, otherwise your CSS targeting div will hit every div in the site, can be very problematic.
* {
box-sizing: border-box;
}
.wrapper {
display: flex;
justify-content: center;
}
.wrapper ul {
list-style: none;
margin: 0;
padding: 0;
max-width: 90%; // adjust the width compared to the container
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.wrapper li {
padding: 0 15px; // padding right and left only
margin-bottom: 20px; // vertical spacing between li elements
width: 50%;
}
<div class="wrapper">
<ul>
<li>In maximus viverra scelerisque. Vestibulum dignissim ex non</li>
<li>Sed suscipit, turpis in suscipit consectetur, ante sem.</li>
<li>Ut et mauris et dui gravida fringilla ut.</li>
<li>Nullam iaculis fermentum sodales. Proin commodo eleifend lacus.</li>
<li>Sed molestie, libero at hendrerit sollicitudin, enim nisi.</li>
<li>Mauris a facilisis dolor. Sed pharetra hendrerit dolor.</li>
<li>Sed vitae felis tellus. Quisque sagittis, felis vitae.</li>
<li>Integer et elit metus. Cras congue vestibulum hendrerit.</li>
<li>Fusce suscipit ante sed tristique euismod. Duis quis.</li>
<li>Vestibulum quam felis, fringilla in justo malesuada, tristique.</li>
<li>Integer volutpat quam sed urna iaculis mollis. Maecenas.</li>
<li>Nullam dignissim ipsum vitae finibus dignissim. Nam viverra.</li>
</ul>
</div>

Why can a flex item take full height in a fixed-position flex container, unless the item has display: flex applied?

I have a markup like the following:
<div id="red">
<div id="yellow">
alot of text
</div>
</div>
<div id="blue">
</div>
I can't get yellow to take 100% of red's height, it only takes 100% of the window even if red is overflowing. It works if I set red's display to block, but I need flex...
#red {
position: fixed;
height: 100%;
overflow-y: scroll;
width: 100px;
background-color: red;
display: flex;
flex-direction: column;
align-items: stretch;
align-content: stretch;
}
#yellow {
display: flex;
flex-grow: 1;
background-color: yellow;
}
#blue {
background-color: blue;
}
Why not apply the overflow to yellow instead of red?
#red {
position: fixed;
height: 100vh;
width: 100px;
background-color: red;
display: flex;
flex-direction: column;
}
#yellow {
display: flex;
overflow-y: scroll;
background-color: yellow;
}
#blue {
background-color: blue;
}
body {
margin: 0;
}
<div id="red">
<div id="yellow">
Cras gravida, diam non adipiscing cursus, sapien urna adipiscing enim, at faucibus nunc felis at turpis. Aliquam erat volutpat. Nulla facilisi. Aenean nec nisi gravida ante convallis euismod sed quis odio. Sed nulla est, fringilla vel rhoncus vel, fermentum
et turpis. Curabitur eu posuere tortor. Integer sit amet nisl elit, gravida rutrum ipsum. Cras nisl est, sodales quis faucibus nec, tempus vel libero. Aliquam lobortis gravida erat, in placerat libero ultricies in. Curabitur volutpat lorem ut ligula
aliquet a fermentum augue porttitor. Vestibulum varius, purus id sollicitudin tincidunt, velit felis tincidunt erat, ut feugiat augue diam commodo lorem. Donec in augue non est tincidunt consequat. Mauris nec justo eget augue varius pulvinar id ut
risus. Donec fringilla, enim vitae tincidunt accumsan, urna elit laoreet tellus, ac gravida dolor dolor ac quam. Vestibulum dignissim felis quis tortor sollicitudin ut placerat mi adipiscing.
</div>
</div>
<div id="blue"></div>
Here's a link that may shed some light:
Make child element use 100% of total OVERFLOW height of parent
The yellow element actually takes 100% of your red element. The overflowing text does not cause your elements to change the size. You should remove height: 100% from #red and use min-height: 100% instead.

IE11 CSS display inline-block overflowing inside flexbox

I'm using an inline-block element with a large content inside a flex-box, and for some reason Internet Explorer 11 will not wrap the contents of this element, but push the flexbox out of the screen. It renders fine in Chrome and FireFox.
Example of my problem: https://codepen.io/anon/pen/YVboBX
<div class="page">
<main>
<radio-widget>
<layout-container>
<section class="icon">X</section>
<section class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce in ipsum id lectus egestas scelerisque sit amet ut libero. Nam luctus turpis nisi, ut mollis libero sodales eu. Donec ante ante, venenatis non sodales sed, venenatis id lacus. In ante
risus, lobortis et ligula eget, commodo euismod risus. Ut sem orci, ultrices eu finibus vel, aliquam et quam. Nunc bibendum sodales libero et pulvinar. Cras porta feugiat lorem, vitae pretium augue fringilla et. Vestibulum dui lacus, ultrices
a ante et, euismod hendrerit ligula. Sed non urna ipsum. Fusce eget massa ex. Phasellus ac tempor ligula. Nullam sagittis dignissim ipsum, non commodo tellus luctus in. Etiam eget eleifend ex.
</section>
</layout-container>
</radio-widget>
</main>
<aside> a side</aside>
</div>
CSS
div.page {
display: flex;
flex-direction: row;
}
main {
flex-grow: 1;
flex-shrink: 1;
}
aside {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 5em;
}
radio-widget {
display: inline-block;
}
layout-container {
display: flex;
}
section.icon {
flex-shrink: 0;
flex-grow:0;
flex-basis: 5em;
}
section.content {
flex-shrink: 1;
flex-grow:1;
}
I already tried the following (possible) fix, but that does not solve my issue:
IE CSS display: inline-block Rendering issue
In IE11, flex elements must have some sort of width defined. Add this to your code:
main {
flex-grow: 1;
flex-shrink: 1;
width: 100%; /* NEW */
}
radio-widget {
display: inline-block;
max-width: 100%; /* NEW */
}
revised demo
References:
Why IE11 doesn't wrap the text in flexbox?
CSS wrap text not working in IE

Equal height rows in flex-direction: column

I have a flex layout with two flex items, displayed as rows (flex-direction: column). The items should have a minimum height but they should maintain the same height it one of them needs to grow. See this JSFiddle and decrease the width of the result pane; this forces the second .component element to increase its height, but the height of the first .component element remains the same.
Is it possible to force the flex items to maintain the same height? Please note that the main thing in this is the stacking of the two .component elements, which I couldn't achieve without flex-direction: column; flex-direction: row would have made the same height possible but the stacking does not work.
Here is the result of what I have so far:
div {
border: 1px solid black;
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
align-content: stretch;
}
.component {
min-height: 300px;
}
.left {
margin-left: 50px;
margin-top: 50px;
margin-right: 100px;
background-color: lightyellow;
}
.right {
margin-left: 100px;
margin-top: -250px;
margin-right: 50px;
background-color: lightgreen;
}
<div class="container">
<div class="component left">
</div>
<div class="component right">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sed orci scelerisque, scelerisque enim at, ullamcorper ipsum. Cras eget sapien mi. Aliquam ultrices, ligula ut mollis maximus, ligula massa imperdiet libero, at faucibus mauris ante non
magna. Sed ex lacus, efficitur sit amet neque ut, venenatis hendrerit libero. Suspendisse ornare orci mi. Nulla iaculis egestas libero, eu tincidunt urna tristique et. Quisque nec odio non elit molestie facilisis.
</p>
<p>
Vestibulum scelerisque justo urna, a semper nisi sollicitudin in. Cras congue enim eu euismod semper. Proin consequat gravida felis, quis tincidunt massa pulvinar quis. Morbi nec diam eget orci vestibulum malesuada. Sed volutpat metus eget mattis commodo.
Nulla facilisi. Praesent lectus mauris, consequat eu varius vitae, cursus vitae leo. Vivamus sagittis lacinia tortor eu ullamcorper. Integer eget velit magna. Duis vestibulum molestie posuere.
</p>
</div>
</div>
The flex equal height columns feature – which is the result of align-items: stretch, a default setting of a flex container – applies only to flex items on the same row.
It doesn't work for items in a multi-line flex container. This behavior is defined in the spec:
6. Flex Lines
In a multi-line flex container (even one with only a single line), the
cross size of each line is the minimum size necessary to contain the
flex items on the line (after alignment due to align-self), and the
lines are aligned within the flex container with the align-content
property.
In other words, when there are multiple lines in a row-based flex container, the height of each line (the "cross size") is the "minimum size necessary to contain the flex items on the line".
In addition, because align-items: stretch works along the cross-axis, the equal height columns feature is useless in flex-direction: column, where the cross-axis is horizontal.
To achieve equal height columns/rows across multiple lines consider a Javascript solution.
However, without knowing much about your overall objective, here's a simple way to achieve equal height rows in your current layout:
Add duplicate content in both divs. In the .component.left div, use visibility: hidden.
Revised Fiddle
You can just wrap those flexbox columns in another flexbox that's a row, there's no reason you can't have items be both flexboxes and flex items.
#container {
display: flex;
}
#container .col {
flex-grow: 1;
display: flex;
flex-direction: column;
background: grey;
}
<div id="container">
<div class="col">
asdf
asdf
asdf
</div>
<div class="col">
asdf
asdf
asdf
</div>
</div>
https://jsfiddle.net/1dp87bm2/1/