2-column CSS Flex/Grid for UL - html

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>

Related

display: flex; does not work with <summary> on Safari [duplicate]

I have this pen where the layout is floated, but when I try to flexbox one container below the layout, the flexbox doesn't work. I know it is caused by the floats however, can't find a way to fix it. Tried to use clearfix but it doesnt work.
The items that i'm trying to flex is in summary tag.
Code Snippet:
summary {
clear: both;
padding: 20px;
background: white;
display: flex;
}
summary p {
width: 33%;
display: inline-block;
background: pink;
margin: 0px;
padding-right: 20px;
}
<summary class="clearfix">
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
</summary>
CodePen
The problem is that you are using flexbox in a summary tag, which is not a structural one. summary is used inside a details element. Consider using a proper semantic tag like article or section for this, and it will work.
Code Snippet:
summary,
article {
display: flex;
}
p::before {
content: "Paragraph.";
}
details > summary {
display: block;
}
<summary>
<p></p>
<p></p>
<p></p>
</summary>
<article>
<p></p>
<p></p>
<p></p>
</article>
<details>
<summary>Proper Usage</summary>
<p></p>
</details>
Change the styles to this classes
#wrapper {
width: 90%;
margin:auto;
padding: 0 20px 0 20px;
margin-bottom:20px;
display:flex;
flex-direction:column
}
and on summary remove clear and display:flex
every thing will work as expected
check this fiddle https://codepen.io/sahithiK/pen/LRqjoR?editors=1100
Hope this helps

Why isn't display:flex allowing my sidebar to take 100% of the available DIV height?

Ok, CSS gurus. Here's an easy one for you. I want to have a sidebar to the left of my main content area. I'd like the sidebar to take up 30% of the screen and the content to take up 70%. However, I'd like the sidebar area to take up 100% of the available height. I have
<div id="main">
<div id="side">
<%= render "layouts/sidebar" %>
</div>
<div id="contentArea"><%= yield %></div>
</div>
I thought setting the parent DIV to have "display:flex;" would make everything right ...
#main {
display: flex;
width: 100%;
background-color: green;
}
#side {
background-color: #e0e0e0;
width: 30%;
display: inline-block;
float: left;
height: 100%;
}
#contentArea {
text-align: center;
width: 70%;
display: inline-block;
}
but right now, the height of my sidebar is only equal to the content that's in it. How do I make it 100% of everything?
In your structure ‘main’ is parent div, that’s mean if you set ‘100% of everything’ to child div ‘side’ and this div not position absolute or fixed, ‘main’ get 100% too.
So, you can use relative lengths, like height: 100vh.
jsfiddle
But you can set to side div position fixed: it will help when you get scroll in contentArea, but side div all time will in left side with height 100vh.
jsfiddle
Tip: if you use flex, you can manipulate without float (e.g. justify-content
). Check it: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The problem is that you specified a height of 100% on #side. Ironically, this actually prevents the column from taking up the full vertical space, as it caps to at the height of the container. Because #main doesn't have a specified height, setting height: 100% on #side will constrain it to the height of the content (text) within.
Simply removing this causes the column to expand to take up the full vertical space:
#main {
display: flex;
width: 100%;
background-color: green;
}
#side {
background-color: #e0e0e0;
width: 30%;
display: inline-block;
float: left;
/*height: 100%;*/
}
#contentArea {
text-align: center;
width: 70%;
display: inline-block;
}
<div id="main">
<div id="side">
Side
</div>
<div id="contentArea">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ut interdum quam. Integer nec tincidunt erat, in scelerisque turpis. Pellentesque interdum turpis eu ante gravida, a auctor lacus pulvinar. Maecenas elementum massa ac felis gravida lobortis
vitae eget nisi. Donec erat turpis, condimentum et ipsum in, tincidunt fringilla quam. Nam est dui, porttitor eget nisl sit amet, mollis varius dui. Suspendisse dui mauris, tincidunt vitae blandit ac, consectetur sed ex. Sed bibendum felis ex, id
euismod odio euismod ac. Praesent viverra arcu quis arcu condimentum, eget varius elit suscipit. Donec tempus, justo vel iaculis vehicula, risus magna varius ex, vitae mattis elit turpis ac magna. Fusce porta tempus erat vel ultricies. Suspendisse
vel erat blandit, semper dui sed, consequat urna. Pellentesque ultrices pellentesque feugiat. Donec sit amet turpis in orci accumsan blandit. In tincidunt erat sed tristique sagittis. Duis ultrices lacus quis vestibulum venenatis. Maecenas et risus
quam. Quisque semper purus id mauris gravida dictum. Cras tellus augue, sollicitudin ac maximus eget, porta elementum elit. Fusce vulputate consectetur dapibus. Praesent semper augue lacus, vel laoreet tellus ultricies fermentum. Phasellus vestibulum
fringilla purus ut malesuada.
</div>
</div>
Hope this helps! :)
Use: #side{height: 100vh;} (vh = viewport height), and remove display flex so you can have unequal height for each div.
Link to jsfiddle https://jsfiddle.net/gcoh62o6/5/

Flexbox doesn't work in summary tag

I have this pen where the layout is floated, but when I try to flexbox one container below the layout, the flexbox doesn't work. I know it is caused by the floats however, can't find a way to fix it. Tried to use clearfix but it doesnt work.
The items that i'm trying to flex is in summary tag.
Code Snippet:
summary {
clear: both;
padding: 20px;
background: white;
display: flex;
}
summary p {
width: 33%;
display: inline-block;
background: pink;
margin: 0px;
padding-right: 20px;
}
<summary class="clearfix">
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
<p>Integer eget mauris et urna pulvinar consectetur hendrerit eget mauris. Praesent a interdum justo. Aenean ac diam nec neque fringilla cursus. Donec iaculis tortor in nunc vehicula rutrum. Integer malesuada mollis ligula at varius.</p>
</summary>
CodePen
The problem is that you are using flexbox in a summary tag, which is not a structural one. summary is used inside a details element. Consider using a proper semantic tag like article or section for this, and it will work.
Code Snippet:
summary,
article {
display: flex;
}
p::before {
content: "Paragraph.";
}
details > summary {
display: block;
}
<summary>
<p></p>
<p></p>
<p></p>
</summary>
<article>
<p></p>
<p></p>
<p></p>
</article>
<details>
<summary>Proper Usage</summary>
<p></p>
</details>
Change the styles to this classes
#wrapper {
width: 90%;
margin:auto;
padding: 0 20px 0 20px;
margin-bottom:20px;
display:flex;
flex-direction:column
}
and on summary remove clear and display:flex
every thing will work as expected
check this fiddle https://codepen.io/sahithiK/pen/LRqjoR?editors=1100
Hope this helps

Float div inside spans

I have this code in a fiddle
I would like to know if its possible to make div float inside text, like its following text?
.a {
position: relative;
width: 100px;
height: 40px;
background: red;
}
<span>Pause and play icons will automatically be attached to every mp3 song in text. Like this for example: </span>
<div class="a"></div><span> ut laoreet hendrerit mi. Nam vestibulum viverra diam. Nullam eros ipsum, rutrum ut, ultricies sed, congue sed, est. Pellentesque porttitor. Donec dictum urna eu mi. Maecenas in lorem.</span>
use display:inline-block along with vertical-align, as you can set it to fit you better.
To users on comments:
This is valid HTML, because span is sibling of div and not its parent.
.a {
display: inline-block;
vertical-align: middle;
width: 100px;
height: 40px;
background: red;
}
<span>Pause and play icons will automatically be attached to every mp3 song in text. Like this for example: </span>
<div class="a"></div><span> ut laoreet hendrerit mi. Nam vestibulum viverra diam. Nullam eros ipsum, rutrum ut, ultricies sed, congue sed, est. Pellentesque porttitor. Donec dictum urna eu mi. Maecenas in lorem.</span>

Centred div which is going on the left if there is content on the div on the right side

I have one div which is centred and another one on the right side which may have some content. If this on the right have content in it, the centred one needs to move on the left. In the end the content from the two divs needs to be in the centre.
For example: I have a search box in the centre. If I have an result from the search - the result and the search box needs to be in the centre. So the search box have moved a little bit on the left.
How can I make that whit CSS?
One way to do it is to use text-align: center and display: inline-block. Here's a fiddle with both elements centered: http://jsfiddle.net/rs6bmfq9/. And, here's a slightly different fiddle with "text" div removed: http://jsfiddle.net/hrham7w9/.
HTML:
<div class = "container">
<input type = "text" />
<div>
Nam at justo dignissim, dapibus lorem eget, consectetur metus. Suspendisse vitae massa a nunc congue pulvinar non luctus mi. Nam turpis ex, laoreet tempor justo ac, cursus convallis urna. Sed eros ligula, congue ut lacinia auctor, porttitor ut quam. Nullam maximus, dui in eleifend viverra, est augue vestibulum est, id lacinia nibh ante vel velit. Aenean vitae sem ipsum. In porta felis urna, vel tincidunt odio aliquam feugiat.
</div>
</div>
CSS:
.container {
white-space: nowrap;
text-align: center;
}
.container > * {
display: inline-block;
}
.container > input {
width: 30%;
vertical-align: top;
}
.container > div {
width: 40%;
text-align: left;
white-space: normal;
vertical-align: top;
border: 1px dotted gray;
}