<li> elements with adapted width - css

I'm wondering if it is possible to do this in CSS, without javascript:
A list of N <li> items, with display inline, equal width, and the width of the all equal to the width of the container
I can have 3 <li> items, in this case the <li> width will be 33%, or I can have 4 <li> items, then the li width will be 25%.

This is a perfect example for usage of display: table.
Works in modern browsers and IE8+...
Support chart
JSFiddle
css:
ul {
display: table;
width: 100%;
table-layout: fixed; /* optional, for equal spacing */
border-collapse: collapse;
}
li {
display: table-cell;
text-align: center;
vertical-align: middle; /* or similar, if needed */
}
html:
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>

It is possible with CSS3 flex boxes, as demonstrated in this fiddle (for webkit browsers only). There are other browser custom properties that would make this work for recent versions of Firefox and IE. If you need something that works for Opera or older versions of IE then there is a JavaScript library called Flexie which might work.
Credit to The CSS3 Flexible Box Layout (flexbox) for the information on the browser support.
HTML
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
CSS
ul {
display:-webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-pack:justify;
width:200px;
}
li {
-webkit-box-flex:1;
border:1px dashed grey;
text-align:center;
}

You could, with a limited number of possibilities. In CSS3 you can't do it for an arbitrary number of columns, though. You may be able to in CSS4; I don't know yet.
li {
display: inline;
}
/* 1 column */
li:first-child:last-child {
width: 100%;
}
/* 2 columns */
li:first-child:nth-last-child(2),
li:nth-child(2):last-child {
width: 50%;
}
/* 3 columns */
li:first-child:nth-last-child(3),
li:nth-child(2):nth-last-child(2),
li:nth-child(3):last-child {
width: 33.3333%;
}
/* 4 columns */
li:first-child:nth-last-child(4),
li:nth-child(2):nth-last-child(3),
li:nth-child(3):nth-last-child(2),
li:nth-child(4):last-child {
width: 25%;
}
I hope you get the idea. Do you want to do this? I hope not.

Assuming the lis are generated from some server-side code, you can use the following "trick":
// in the markup add a class to the UL based on the count of messages
<ul class="col<%= echo count(lis) %>">
...
// and in the CSS
// (notice you have to use display: inline-block, as inline doesn't allow you to
// specify a width)
li { display: inline-block; }
.col3 li { width: 33.3%; }
.col4 li { width: 25%; }
// etc

Make a standard left-floated list and you can (or must) set display to inline to avoid IE6 doubling a possibly existing margin-left.
Assuming you have a static page, you can set your list up like this:
HTML:
<ul class="listLR col3 clearfix">
<li></li>
<li></li>
<li></li>
</ul>
and CSS:
listLR {
width: 100%; // important for IE!
}
listLR > li {
display: inline;
float: left;
}
col3 > li {
width: 33.33%;
}
col4 > li {
width: 25%;
} //and so on
The use of a clearfix-class is demonstrated here

Related

Why does selecting multiple elements CSS work differently? [duplicate]

This question already has answers here:
Understanding CSS selector priority / specificity
(4 answers)
Closed 3 years ago.
I was trying to create a responsive menu but selecting a specific element worked out differently.
For example, when I selected "nav ul li" for list styles in the default size and selected "ul li" for list style in the breakpoint, it didn't work as I intended.
It was fixed when I selected "ul li" for both the default size and the breakpoint but I don't know why it fixed the issue because as far as I know, selecting "nav ul li" and "ul li" are the same thing. Could somebody help me with this?
nav {
width: 100%;
background-color: darkblue;
}
ul {
width: 80%;
margin: 0 auto;
padding: 0;
}
nav ul li {
list-style-type: none;
display: inline-block;
padding: 20px;
}
ul li:hover {
background-color: orange;
}
ul li a {
color: #ffffff;
text-decoration: none;
}
.toggle {
width: 100%;
padding: 10px 20px;
background-color: #001f44;
text-align: right;
box-sizing: border-box;
color: #ffffff;
font-size: 30px;
/* to hide toggle */
display: none;
}
/* Break Point for the toggle */
#media screen and (max-width:768px) {
.toggle {
display: block;
}
ul {
width: 100%;
}
ul li {
display: block;
text-align: center;
}
}
<div class="toggle">
<i class="fa fa-bars"></i>
</div>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Resume</li>
</ul>
</nav>
You are running into specificity issues. In CSS, if two different rules target the same element with same attributes, the rule with the more specific selector will win and cancel out the less specific rule.
Reading: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
nav ul li {/* more specific rule wins */
color: blue;
}
ul li {
color: red;
}
<nav>
<ul>
<li>The first list example</li>
</ul>
</nav>
<nav>
<ul>
<li>The second list example</li>
</ul>
</nav>
What is happing is that you are not overriding your selection in the media query.
For instance lets say you got:
CSS:
p a{
color: red
}
#media screen and (max-width:768px) {
a {
color: blue;
}
}
html:
<p> <a>Some Url </a> </p>
The media query wont override the selection for is not as specific as the prior selection.
CSS is about priorities for the more specific the higher the priority of style.
So as:
p a { some style} is more specific than a {some style} then the priority stands for the first one.
In your example, ul li is less specific than nav ul li, thats why you are not overriding the style with the media query.
Hope this answer your question.
Go to w3schools.com for CSS selection rules.
CSS is easy to start writing and really hard to maintain.
One approach to simplify maintainability and avoid specificity conflicts is BEM (Block, Element, Modifier) in which every element has a class and that class describes the element as either:
a Block
a Block Element
a Modified Block
a Modified Block Element
Eg.
<nav class="navigation">
<ul class="navigation__list">
<li class="navigation__list-item">The first list example</li>
</ul>
</nav>
<nav class="navigation">
<ul class="navigation__list">
<li class="navigation__list-item">The second list example</li>
</ul>
</nav>
This will help you entirely avoid any specificity conflicts.
N.B.
BEM is just one approach to writing CSS. Others which similarly seek to simplify maintainability and extendability are OOCSS and SMACSS.
You will find on the web nearly a decade's worth of blog posts and tutorials on any of these approaches to writing CSS.

Display info on hover SCSS/CSS

I'm making a hoverable ul that displays a p element in another div.
As there is no parent selector to be had in pure CSS, I'm stuck and cannot figure out how this is supposed to work.
Fiddle won't work for some reason(for me), so here is a bin:
https://jsbin.com/yohapudimo/edit?html,css,output
My best effort was:
#infoDrop > li:hover ~ #aboutPara > p{
display: inline;
}
while trying to target a sibling div
I think it might be possible without JS... this is untested though so bear with me -- it also has to be an adjacent element, which I'm not sure is a problem or not for you?
If this doesn't work for you, then I'm afraid you'll need JS.
#myPCont p {
display: none;
color: #fff;
}
.myCont:hover+#myPCont p {
display: block;
}
#myPCont {
background: #333;
height: 300px;
width: 300px;
}
<div class="myCont">
<ul class="hoverShowP">
<li>This is my first list item</li>
<li>This is my second..</li>
<li>And this is my third.</li>
</ul>
</div>
<div id="myPCont">
<p>Heyooo!</p>
</div>

Simple CSS: How to fix display:inline issue

Kinda embarrassed asking but I'm fairly new to CSS and I just wanted to add some simple display:inline styling on a HTML list item. The list is composed of varied heading, paragraph, image and link tags and I just cant seem to get them all inline on one row.
This is all the relevant parts of my code, hopefully someone can point out an easy fix.
HTML
<ul>
<li>
<h3>Quantity</h3>
</li>
<li>
<p>#</p>
</li>
<li><img onclick="addQuantity('itemName')" src="images/plus.png"></li>
<li>
<h3>1</h3>
</li>
<li><img onclick="minusQuantity('itemName')" src="images/minus.png"></li>
<li>
<h2>Add To Cart</h2>
</li>
<li>
<h4>Checkout</h4>
</li>
</ul>
CSS
ul {
list-style-type:none;
}
li {
display:inline;
}
Simple question, simple answer :)
Use inline-block
Have an example!
CSS
li {
display:inline-block;
}
Now, being CSS, there are numerous ways to achieve the layout you want. Here is a slightly more in-depth example using display: table and display: table-cell. Same HTML.
Have a second example!
CSS
* {
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
ul {
list-style-type:none;
display: table;
border-collapse: collapse;
border-spacing: 10px;
background: #333;
width: 100%;
}
li {
display:table-cell;
background: #DDD;
vertical-align: middle;
}

How to let ul re-size by window width change when its with nowrap property

As my title write, now I have a menu made by ul li, I won't let the menu break due to window is too narrow. But once it is attached "nowrap" property, it won't re-size with windows anymore, how can I make it is not only nowrap but no-break line.
<ul class="parallMenu">
<li>item1</li>
<li>item2</li>
</ul>
.parallMenu{
list-style:none;
margin-left:0;
padding-left:0;
text-decoration:none;
white-space:npwrap;
width:100%;
}
.parallMenu li{
width:120px;
min-width:30px;
display:inline-block;
}
Thanks!
So,
$(".parallMenu").toggleClass("nowrap");
.nowrap
{
width: 500px !important; /*(fixed value)*/;
}
same goes for the other properties
OR
<ul id="MyMenu" class="parallMenu wrap"></ul>
$("#MyMenu").toggleClass("wrap");
$("#MyMenu").toggleClass("nowrap");
.wrap
{
white-space :wrap;
}
.nowrap
{
white-space: nowrap;
}
and have different class defining differet stuff for u.
EDITED:
Please use CSS media screen if there is no script.
#media (min-width: 768px) {
.parallMenu
{
white-space:nowrap;
}
}

Display: table-cell on new row

Here is an example code for what I mean:
HTML
<ul class="table">
<li class="table-cell"></li>
<li class="table-cell"></li>
<li class="table-cell"></li>
<li class="table-cell"></li>
</ul>
CSS:
.table {
display: table;
}
.table-cell {
display: table-cell;
width: 25%;
}
Q: How can I make the third and forth <li> (table cells) display on new row with width: 50% each?
Q: Is there a way using only CSS and not jQuery or Javascript?
The simple answer is: you can't, at least not with lists. Adjacent elements with their display set to table-cell are treated as belonging to the same row (even if a row element is not provided, an anonymous one will be created for you). Since lists aren't allowed to contain any other tags between the ul and the li, this simply isn't possible with lists. You'll have to use either different markup or different styling.
Here are your options if you don't want to modify the markup.
Inline-block on the list items: http://jsfiddle.net/XNq74/1/
li {
display: inline-block; /* could use floats here instead */
width: 40%;
}
CSS columns would be a reasonable choice: http://jsfiddle.net/XNq74/
ul {
columns: 2;
}
http://caniuse.com/#feat=multicolumn
Flexbox would also work and can be used in combination with inline-block: http://jsfiddle.net/XNq74/2/
ul {
display: flex;
flex-flow: row wrap;
}
li {
flex: 1 1 40%;
}
http://caniuse.com/#search=flexbox
ul.table li+li+li { /** your CSS code **/ } This one is for the third element
ul.table li.last { /** your CSS code **/ } This one is for the fourth element

Resources