I'm experimenting with the latest columns feature in CSS3. Each ul has varying heights, and I want them to have equal margins above and below. At the moment, because one ul is much longer than the rest, it is pushing the second row down. Is it possible for the longest ul to not force so much space beneath it?
http://jsfiddle.net/t5ng3/
CSS:
.wrapper {
background-color: grey;
max-width: 600px;
-webkit-column-width: 50%;
}
ul {
background-color: orange;
display: inline-block;
vertical-align: top;
width: 20%;
}
HTML:
<div class="wrapper">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
<ul>
<li>Item</li>
<li>Item</li>
</ul>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
That's because of white space, which will cause normally a 4px offset, inorder to solve this, there are various ways, the cheap one is to use margin-left: -4px; but this will fail if the font-size > 100%, another way is to use font-size: 0; on the parent element, and the last one is to take out the indentation/white space from the source by sticking up the ul elements..
Demo
You can also float your elements to the left but for this it will be better if you wrap them inside a container div/section element.
Now I am not sure whether you are aware of this or not but you might like to have a look at column-count property which will do a similar job without breaking yourself the ul elements..
The "columns" you're seeing are purely the result of your lists being inline-block, not because you're using column-width. The column-width property does not appear to work as you would expect with a percentage value.
If you want exactly 2 columns, then you would use column-count: 2 rather than column-width: 50%.
http://jsfiddle.net/t5ng3/12/
.wrapper {
background-color: grey;
max-width: 600px;
-webkit-columns: 2;
-moz-columns: 2;
columns: 2;
}
ul {
background-color: orange;
}
If the child elements should not be split across columns, then the break-inside property is what you're looking for rather than trying to use display: inline-block.
ul {
background-color: orange;
-webkit-column-break-inside: avoid; /* old name */
page-break-inside: avoid; /* Firefox uses non-standard property */
break-inside: avoid;
}
You may wish to remove the top margin on the first element:
ul:first-child {
margin-top: 0;
}
It is happening because there is space between </ul> and <ul>. inline-block elements leave space.
Removeing space i.e. writing </ul><ul> will resolve your problem.
Updated fiddle.
Related
I'm trying to build a react components, which renders 2 lists. Both lists can dynamically get bigger or smaller.
I've got 100% space vertically. If both lists are big, than every list should take 50% height.
If any list isn't big enough to take the whole 50% height space, than the other one should grow.
I can't find a working solution so far. I think flex-grow and shrink is a good way to do it, but it doesnt work for me.
.container {
display: flex;
flex-direction: column;
flex: 1 1;
overflow-y: hidden;
}
.list_1 {
display: flex;
flex-direction: column;
flex: 1 1 auto;
overflow-y: auto;
}
.list_2 {
display: flex;
flex-direction: column;
flex: 1 1 auto;
overflow-y: auto;
}
<div class="container">
<div class="list_1">
<li>Item 1a</li>
<li>Item 1b</li>
<li>Item 1c</li>
</div>
<div classs="list_2">
<li>Item 2a</li>
<li>Item 2b</li>
<li>Item 2c</li>
</div>
</div>
I tried so many thinks from documentations but nothing works..
As you can see in the following snippet, I have given flex: 1 to both .list-1 and .list-2.
So when the second list grow, the first one shrinked.
If both has equal items, both will have 50% width also.
Please check and try updating your code with this solution.
.container {
display: flex;
flex-direction: column;
border: 1px solid blue;
height: 300px;
}
.list_1, .list_2 {
flex: 1;
border: 1px solid #ddd;
}
<div class="container">
<div class="list_1">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<div class="list_2">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
</div>
This question already has answers here:
How can I align one item right with flexbox?
(5 answers)
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
Closed 2 years ago.
I've got a navigation which looks sort like a this one under, and li items inside are flex items. This menu is rendered from the outside, and I'm not able to wrap any of the items inside the dedicated container.
What I'm trying to achieve is to set space-between between the last item and the other ones on the left. I've tried to do it with a margin-left on the last child, but it's not a nicest solution.
Is there a CSS option to "wrap" the last item somehow, so there's always space between that one and the ones on the left?
.container {
max-width: 1000px;
background-color: lightblue;
}
ul {
display: flex;
justify-content: space-between;
}
.last {
background: red;
}
<div class="container">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li class="last">Last Item</li>
</ul>
</div>
Using margin-left on the last element is a good solution. However, you can improve your implementation by using the :last-child selector:
ul li:last-child {
margin-left: 10px;
}
Instead of manually assigning the last class to the last child.
EDIT: If you mean you want your last child to be aligned all the way to the right. You can separate them into different lists, and use justify-content: space-between:
.container {
max-width: 1000px;
background-color: lightblue;
display: flex;
justify-content: space-between;
}
ul {
display: flex;
}
ul li {
width: 3rem;
}
.right li {
background-color: red;
}
<div class="container">
<ul class="left">
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
<ul class="right">
<li>Item</li>
</ul>
</div>
I have an element with a pre-determined width, and within that element I have 1 or more lists. Each list will have a class defining whether it is horizontal or vertical.
The horizontal list needs to span the full width of the div, but center the list items. When try to make the list items equally share the space given to them rather than just centering, I get no results - I don't have to worry about horizontal overflow, since I can just make a second horizontal list if I need to.
The same thing is true for when I try to do this with the vertical lists.
.c {
display: block;
width: 90%;
background: orange;
padding: 1% 5%;
text-align: center;
}
ol {
list-style-type: none;
padding: 0;
}
.h {
display: block;
background: blue;
}
.h li {
display: inline-block;
background: green;
}
.v {
display: inline-block;
background: red;
}
.v li {
background: violet;
}
<div class="c">
<ol class="h">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
<ol class="v">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
<ol class="v">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
</div>
And I want to end up with this:
How do I get the horizontal items to self-pad, as well as the vertical lists? I'm looking for results without the use of tables, display: table (etc), and flex, if possible. It doesn't matter if extra space is filled in with padding or margin to me.
This div container .c has 90% width.
So the properties are being inherited by the other classes it seems.
You also have the issue of the yellow background not covering the other classes.
The changes I made were creating a new class to wrap around everything to make sure it all has the yellow background and I also wrapped your .c div around the other 2 classes instead and changed the .h class to display inline-block, this means you can set the height and width of the element while keeping it inline, I set the width to 100% and aligned the text to centre.
.d {
background: orange;
}
.c {
display: block;
width: 90%;
padding: 1% 5%;
text-align: center;
}
ol {
list-style-type: none;
padding: 0;
}
.h {
text-align: center;
display: inline-block;
width: 100%;
background: blue;
}
.h li {
display: inline-block;
background: green;
}
.v {
display: inline-block;
background: red;
}
.v li {
background: violet;
}
<div class="d">
<ol class="h">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
<div class="c">
<ol class="v">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
<ol class="v">
<li>Item</li>
<li>Line</li>
<li>List</li>
</ol>
</div>
</div>
You have 4 options;
Make CSS rules for all the possible amounts of horizontal list elements
Use tables
Use JavaScript
Use flex
I can write examples for all those options, or just the option(s) you'd like.
This question already has answers here:
justify-content: space-between failing to align elements as expected
(3 answers)
Closed 6 years ago.
How can I get the below snippet to look like this:
So that the items are evenly spaced, and the first item has no empty space on the left & the last item has no empty space on the right. Similar to what MS Word can do:
Full-justification
All lines in a paragraph are expanded so they are neat against both
the left and right margins.
To expand the line, space has to be added, between words and
characters, to fill out the line.
In the code snippit below, there is lots of purple space to the left of the first item, I want to remove this.
ul {
list-style: none;
background-color: rebeccapurple;
color: white;
margin: 55px 10px;
display: flex;
// align-items: stretch;
justify-content: space-between;
}
li {
padding: 0;
background-color: #6495ed;
}
li:nth-of-type(2n) {
background: lightslategrey;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/dist/css/bootstrap.css" rel="stylesheet"/>
<ul class="nav navbar-nav">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
UPDATE
#kukkuz answer below solves the snippit but I also had to add the below to get it to work with twitter Bootstrap. Bootstrap was adding :before & :after elements that were messing things up for me.
Removing them got it working for me, but I would recommend using a more specific selector that ul otherwise you could mess things up with Bootstrap.
FYI - I was using Bootstrap from this CDN, v3.3.7:
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/dist/css/bootstrap.css
ul:before {
content: none;
}
ul:after {
content: none;
}
Reset the user-agent/browser padding of ul element - see demo below:
ul {
list-style: none;
background-color: rebeccapurple;
color: white;
margin: 55px 10px;
padding: 0;
display: flex;
/*align-items: stretch;*/
justify-content: space-between;
}
li {
padding: 0;
background-color: #6495ed;
}
li:nth-of-type(2n) {
background: lightslategrey;
}
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
Suppose there's an unordered list inside a resizable div container, and that list is laid out horizontally and aligned to the right.
In that list one of the items is chosen as "special", say is assigned id="pinned".
Is it possible by means of CSS only to make the #pinned item maintain its position relative to a containing div while that div is resized, so that other list items may change their position (float) around the #pinned item?
Here's an image of what I mean:
Yes, you can do that. This code will only work if the pinned list item is the first in the list.
HTML:
<ul>
<li id="pinned">item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
CSS:
ul {
background: lightyellow;
padding: 10px;
text-align: right;
}
li {
padding: 10px 50px;
background: lightblue;
display: inline-block;
margin: 10px;
}
#pinned {
float: right;
background: lightgreen;
margin-left: 14px;
}
DEMO