Make li element width the max of siblings, itself, and parent li - css

I've looked at several related posts here and none seem to cut to the core of my challenge.
The scenario is that I have an li element that contains a ul element. I want the widths of the li elements inside the contained ul to be at least as wide as the parent li.
Below are two examples. The first example displays the way I want it to. The second illustrates the issue. I want the items that start "Sub-Item 1" and "Sub-Item 2" to take on the width of the item that starts "Long Item". If you run the code snippet it should be pretty clear what I am after.
I am looking for a 100% CSS solution.
Any assistance would be appreciated.
<style>
ul {
padding:0;
}
ul li {
position: relative;
display: inline-block;
list-style: none;
text-decoration: none;
text-align: center;
float: left;
background-color: red;
white-space:nowrap;
}
ul li ul {
position: absolute;
display: flex;
flex-direction: column;
text-align: left;
background-color: lightgoldenrodyellow;
padding:0;
}
ul li ul li {
text-align: left;
width: 100%;
margin-left: 0;
border-style: none;
background-color: lightgoldenrodyellow;
padding:0;
}
</style>
<div style="position:absolute;top:0;">Example 1
<ul>
<li>
Short Item
<ul>
<li>This is longer than First Item and displays as desired.</li>
<li>Filler - width is same as sibling</li>
</ul>
</li>
</ul>
</div>
<div style="position:absolute; top:200px;">Example 2
<ul>
<li>
Long Item - This is deliberately longer. I want the width of li below to display as wide but it doesn't
<ul>
<li>Sub-Item 1: Shorter than Long Item and does NOT display as desired</li>
<li>Sub Item 2: Filler - width is same as sibling</li>
</ul>
</li>
</ul>
</div>

This can be accomplished by using flex and wrapping the "Short Item" text in a span tag.
ul {
display: flex;
padding:0;
}
ul li {
position: relative;
display: flex;
flex-basis: auto;
flex-direction: column;
list-style: none;
text-decoration: none;
background-color: red;
white-space:nowrap;
}
span{
flex-basis: auto;
flex-grow: 1;
}
ul li ul {
display: flex;
flex-direction: column;
text-align: left;
background-color: lightgoldenrodyellow;
padding:0;
}
ul li ul li {
text-align: left;
width: 100%;
margin-left: 0;
border-style: none;
background-color: lightgoldenrodyellow;
padding:0;
}
<div>Example 1
<ul>
<li>
<span>Short Item</span>
<ul>
<li>This is longer than First Item and displays as desired.</li>
<li>Filler - width is same as sibling</li>
</ul>
</li>
</ul>
</div>

Related

Make menu items and submenu items display vertically without covering each other up

As the first step in making my menu responsive, I want to add a media query in css to change the way the menu displays so that each list item is displayed vertically below the previous item, with it's own submenu items displayed below it before the next list item is displayed. Hope that makes sense. Here are the HTML and CSS that make the menu work in the desktop version of the site:
HTML
<nav>
<img id="logo" src="#logoUrl">
<ul>
<li class="#(CurrentPage.Url == "/" ? "current" : null)">Home</li>
#foreach (var item in menuItems)
{
<li class="#(CurrentPage.Id == item.Id ? "current" : null)">
#item.Name
#if (item.Children.Where("Visible").Any())
{
var subMenuItems = item.Children.Where("Visible");
<ul>
#foreach (var sub in subMenuItems)
{
<li>#sub.Name</li>
}
</ul>
}
</li>
}
</ul>
<br class="clear">
</nav>
(This is on Umbraco, so forgive all the Razor bits)
CSS
#logo {
float: left;
margin-right: 25px;
}
nav {
width: 100%;
height: auto;
background-color: #354a49;
}
nav > ul > li {
display: block;
position: relative;
width: auto;
height: 50px;
float: left;
font-size: 1.1em;
margin: 0px 20px 0px 20px;
padding: 15px 8px 13px 8px;
text-align: center;
}
nav ul li a {
color: #fefce9;
margin-left: auto;
margin-right: auto;
}
nav ul li a:hover {
font-style: italic;
}
nav ul ul {
display: none;
position: absolute;
top: 100%;
left: 0;
z-index: 99;
width: 200px;
}
nav ul li:hover {
border-bottom: 2px solid #fefce9;
background-color: #a1b0af;
}
nav ul li:hover > ul {
display: block;
margin-top: 2px;
}
nav ul li ul li {
display: block;
float: none;
padding: 20px 3px;
background-color: #a1b0af;
border-bottom: 2px solid #fefce9;
}
nav ul li ul li a {
color: #fefce9;
}
nav li.current {
background-color: #a1b0af;
border-bottom: 2px solid #fefce9;
}
nav li.current > a {
color: #fefce9;
font-style: italic;
}
And here is the CSS I have in my media query at the moment:
#logo {
margin-right: -50px;
}
nav > ul > li {
float: none;
margin: 0px;
}
nav ul ul {
width: 100%;
}
nav li.current {
background-color: inherit;
}
That displays the main menu items one below the other OK, but when I try to change things so that the submenu items appear between the menu items I just end up with the submenu items appearing over the top of the menu items and each other.
EDIT
Here's the rendered HTML as requested:
</nav>
<img id="logo" src="/media/1042/wshalogo.png">
<ul>
<li class="current">Home</li>
<li>
About us
<ul>
<li>Our People</li>
<li>Who we were and are</li>
<li>Our Houses</li>
<li>Annual Reports</li>
</ul>
</li>
<li>
Being a Tenant
<ul>
<li>Asbestos</li>
<li>Being Safe & Secure</li>
</ul>
</li>
<li>
News
<ul>
<li>Community Garden</li>
<li>Football Team</li>
<li>Health Centre</li>
</ul>
</li>
</ul>
<br class="clear">
</nav>
Your second level ul is position: absolute; which means it's taken out of the normal document flow and won't take up space in relation to any other elements. Try changing absolute to relative. That should keep the items correctly positioned in the menu.
nav ul ul {
display: none;
position: absolute; /* <--- Try changing this to relative. */
top: 100%;
left: 0;
z-index: 99;
width: 200px;
}
Also, the fixed height on your top-level li doesn't let the element grow past 50px. Try setting that instead to a min-height:
nav > ul > li {
display: block;
position: relative;
width: auto;
height: 50px; /* <-- min-height: 50px */
float: left;
font-size: 1.1em;
margin: 0px 20px 0px 20px;
padding: 15px 8px 13px 8px;
text-align: center;
}
That worked in this fiddle but led to awkward jumping when the sub-menu was hovered and then un-hovered.
Also, consider your use-case - if you're doing this to support tablet/mobile devices the :hover state won't work the same way it doesn't when you're using a mouse. Users would have to know to press to the side of the "About Us" link text to see the dropdown, otherwise they'll get taken directly to the "About Us" page without seeing the :hover state. It might be necessary to either show all the items in a tree structure or use JavaScript to add additional functionality for the submenus.
Here's a decent solution to a responsive sub-menu without JavaScript, but it also doesn't use links for top-level menu items that have sub-items.

horizontally align breadcrumbs - CSS

I am having a hard time aligning the breadcrumbs horizontally.
There is an existing style sheet for the container divs and something in it is preventing the output.
The ul li appear one below the other.
http://jsfiddle.net/y9tyc2cu/1/
HTML:
<div class="chatWrapper">
<div class="chatContainer">
<div class="chatMsgWrapper">
<ul id="crumbs">
<li>Home
</li>
<li>Main section
</li>
<li>Sub section
</li>
<li>Sub sub section
</li>
</ul>
</div>
</div>
</div>
CSS:
ul#crumbs, ul#crumbs li {
list-style-type:none;
padding:0;
margin:0;
}
#crumbs {
height:2.3em;
border:1px solid #dedede;
}
#crumbs li {
float:left;
line-height:2.3em;
color:#777;
padding-left:.75em;
}
#crumbs li a {
/*background:url(/Assets/Images/crumbs.gif) no-repeat right center;*/
background:gray;
padding:5px 15px 5px 0;
}
Here is the solution. float: none; for each li and display: inline; for ul.
Check here!
if you are a bootstrap user you need
you should have bootstrap.min.js
http://getbootstrap.com/2.3.2/components.html#breadcrumbs
<ul class="breadcrumb">
<li>Home <span class="divider">/</span></li>
<li>Library <span class="divider">/</span></li>
<li class="active">Data</li>
</ul>
just add display:inline and remove float: left from li
example
http://jsfiddle.net/y9tyc2cu/3/
You have two redundant styles for the li.
You may remove this style:
.chatContainer ul li{
float: left; clear: both; margin: 10px 0;
width: 100%; padding: 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
Also, make the li as display: inline-block or clear the floats properly:
#crumbs li {
display: inline-block;
line-height: 2.3em;
color: #777;
padding-left: .75em;
}
Your updated fiddle: http://jsfiddle.net/abhitalks/y9tyc2cu/2/
Update:
As per your comment, you can't remove or change an existing style. In that case, you need to override the styles which are set in the earlier defined style. Just add these two overrides in #crumbs li style, without changing or removing anything elsewhere:
width: auto; float: none;
So, your complete style now looks like this:L
#crumbs li {
display: inline-block;
line-height: 2.3em;
color: #777;
padding-left: .75em;
width: auto;
float: none;
}
Updated fiddle: http://jsfiddle.net/abhitalks/y9tyc2cu/6/
.

100% children height in horizontal navigation with dynamic logo/element height

I've browsed around for a while but I believe I have a slightly more unique situation here.
I have a simple navigation which is a <ul> list, with each <li> containing an anchor <a>. The first <li> contains an image which is the logo.
I'd like for each of the subsequent <li> AND <a> elements to expand to the height of the logo, whatever it may be (I would like for the only static height in this solution to be defined on the logo's image, if possible).
The elements should also be vertically centered.
When you hover on the <a> tags, the background and cursor selection should cover the entire height.
I've tried using display: flex; and display: table-cell, with vertical-align: middle and a bunch of other things. I've almost got it but there is some empty space above and below the <a> tags. The only way I can see to fix it is to use a static height on the <a> tags, but I'm posting here to see if anyone knows of any alternatives.
Please note that this doesn't have to be a cross-browser solution (although that would be nice).
Also note that these elements will include a sub-navigation dropdown, so solutions which might include overflow: hidden may not be applicable in that case.
Here is the code:
a {
font-family: 'Trebuchet MS';
text-decoration: none;
}
nav {
background: #444;
}
nav > ul > li {
display: table-cell;
vertical-align: middle;
}
nav > ul > li img {
display: table-cell;
vertical-align: middle;
height: 24px;
padding: 24px;
}
nav > ul > li a {
display: table-cell;
vertical-align: middle;
padding: 24px;
color: #fff;
}
nav > ul > li:hover a {
cursor: pointer;
background: white;
color: #444;
}
<nav role="navigation">
<ul>
<li>
<img src="http://i.imgur.com/ZPB7f3l.png" />
</li>
<li>About
</li>
<li>Work
</li>
<li>Ideas
</li>
<li>Contact
</li>
</ul>
</nav>
Here is the fiddle: http://jsfiddle.net/0br6r0sh/1
Any advice is appreciated!
Thanks,
Ryan
I've tried to implement your requirements using Flexbox. Unfortunately not in a cross browser fashion as it only works on Chrome.
The <img> is given a display: block to remove all padding/margin around it. I've used three sets of display: flex, for the <ul>, <li> and <a>.
a {
font-family: 'Trebuchet MS';
text-decoration: none;
}
nav {
background: #444;
}
nav > ul {
display: flex;
flex-direction: row;
align-items: stretch;
}
nav > ul > li {
background-color: #555;
display: flex;
}
nav > ul > li img {
height: 24px;
padding: 24px;
background-color: #ccc;
display: block;
}
nav > ul > li a {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 24px;
color: #fff;
background-color: #666;
}
nav > ul > li:hover a {
cursor: pointer;
background: white;
color: #444;
}
<nav role="navigation">
<ul>
<li>
<img src="http://i.imgur.com/ZPB7f3l.png" />
</li>
<li>About
</li>
<li>Work
</li>
<li>Ideas
</li>
<li>Contact
</li>
</ul>
</nav>

White Space between vertical nav bar and paragraph

I have some mysterious white space that I don't know how to get rid of. I have a vertical list and I want it to be right next to the paragraph with text. Here is my HTML and CSS
SOLVED BY jmgem I ALSO HAD TO READJUST THE SIZE OF MY PARAGRAPH ELEMENT SO IT WOULD FIT BESIDE THE NAV BAR
HTML
<div id="classOfferingList" class="classOfferingList" align="left">
<ul>
<li>
<a href="" >General U.S. K-12 English Speaking Course</a>
</li>
<li>
<a href="" >University Preperation Course</a>
</li>
<li>
<a href="" >SAT Preperation Course</a>
</li>
<li>
<a href="" >GRE Preperation Course</a>
</li>
</ul>
</div>
<div id="classOfferingInfo" >
<p>example text</p>
</div>
CSS
.classOfferingList ul {
list-style-type: none;
float: left;
}
.classOfferingList ul li {
margin: 5px 0px;
}
.classOfferingList ul li a {
list-style: none;
margin: 1px 0px;
display: inline-block;
background-color: blue;
width: 35%;
text-align: center;
}
First of all, I copied your code into jsfiddle. Go on in and have a look.
http://jsfiddle.net/GyuX5/
If I understand your question correctly, you wanted to put the paragraph right next to the vertical menu. So here's your adjusted CSS
.classOfferingList ul {
list-style-type: none;
float: left;
}
.classOfferingList ul li {
margin: 5px 0px;
}
.classOfferingList ul li a {
list-style: none;
margin: 0px;
display: inline-block;
background-color: grey;
text-align: center;
width: 150px;
}
#classOfferingInfo {
display: inline-block;
}
I had your paragraph display as an inline-block, then I changed the width of the li a to 150px instead of 35%. Voila.
Chose not to use a left float as they tend to disrupt layouts as they become more complicated. try to imagine html/css as blocks filling up a row in the browser from left to right.
Try floating the two main div to the left then they will be right next to each other. See Fiddle
.classOfferingList {
float: left;
}
.classOfferingList ul {
list-style-type: none;
float: left;
}
.classOfferingList ul li {
margin: 5px 0px;
}
#classOfferingInfo {
float: left;
}
.classOfferingList ul li a {
list-style: none;
margin: 1px 0px;
display: inline-block;
background-color: blue;
width: 35%;
text-align: center;
color: #fff;
}
http://jsfiddle.net/erenyener/TC856/
#classOfferingList > ul
{
padding:0px;
}
you need to reset ul element
or your question could be this
FIDDLE

Make inline-block element take up no vertical space

I have an evenly distributed menu like :
HTML
<nav>
<ul>
<li>Home
</li>
<li>About
</li>
<li>Contact
</li>
<li>Blog
</li>
</ul>
</nav>
CSS
nav ul {
padding:0;
margin:0;
text-align: justify;
text-transform: uppercase;
background-color: #000;
}
nav ul:after {
content:'';
width: 100%;
display: inline-block;
height: 0;
line-height: 0;
font-size: 0px;
}
nav ul li {
display: inline-block;
}
nav ul li a {
color: #fff;
}
This works great to spread the menu items accross the whole width of the bar as can be seen in this fiddle: http://jsfiddle.net/SjDEX/.
However, you can also see that a result of the ::after element the height of the ul is increased making extra space below the menu items.
Is there a way to get rid of this by making the after element not take up vertical space?
Setting its height to 0 does nothing and changing its display to block or something else breaks the layout.
It is the ul itself that has that height, not the :after, so just add
nav ul {
height: 20px;
}
Fiddle
And this code can be reduced to this:
nav ul:after {
content:'';
width: 100%;
display: inline-block;
}

Resources