Expand child height based on taller sibling (parent height set to auto) - html

Simple question (snippet below):
<ul> with display: flex
each <li> should have the same size and together must occupy the full width of the <ul>
each <li> has a <a> which the content may have 1 or 2 lines of text.
each <li> has height set to auto to adjust to the <a> content
My problem:
I need the "one-line" links to auto expand to the height of the "two-line" links. Setting height: 100% doesn't work because their parent height it's intentionally set to auto to adjust for content.
But in some cases I'll get two-line links, and some cases all will be one-line. So I need the one-line links to auto-expand when that happens.
How is this possible?
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: inline-block;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: inline-block;
background-color: lightblue;
padding: 8px 0px;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>

You don't need to use inline-block with flex. Just use display: flex for li and display: block for a. Finally, add the width: 100% for a. It seems match your requirement.
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: flex;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: block;
background-color: lightblue;
padding: 8px 0px;
width: 100%;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>

you can omit padding from top and bottom of the anchor and use height 100% a{height: 100%;}
#root {
width: 140px;
box-sizing: border-box;
}
ul {
display: flex;
justify-content: space-between;
margin: auto;
padding: 0;
}
li {
flex-grow: 1;
flex-basis: 30px;
list-style-type: none;
display: inline-block;
border: 1px dotted blue;
height: auto;
}
a {
cursor: pointer;
border: 1px dotted green;
display: inline-block;
background-color: lightblue;
height: 100%;
}
<div id="root">
<ul>
<li><a>Link 1</a></li>
<li><a>Long Link 2</a></li>
</ul>
</div>

Related

CSS <li> does not extend

I have <ul> list and inside <li> i have link <a href="...">
I want the <li> not to be influenced by the content and have fixed size.
My CSS
ul.files {
display: inline-block;
padding: 0;
margin: 0 auto;
}
ul.files li {
display: inline;
}
ul.files li a {
color: black;
float: left;
padding: 8px 15px;
text-decoration: none;
border: 1px solid #ddd;
margin: 0 3px;
background-color: #ffffff;
}
My HTML
<ul class="files">
<li>
<a id="some_id" href="http">123</a>
</li>
</ul>
To be able to set fixed width and height to <li> you need to change display: inline; to inline-block
ul.files li {
display: inline-block;
width: 150px;
height: 150px;
}
To center text
To center content of li you can use display: inline-flex
ul.files li {
display: inline-flex;
justify-content: center;
align-items: center;
width: 150px;
height: 150px;
}

How can i make list items in a horizontal container fill the entire container evenly without spacing between?

I've made a horizontal list using flexbox that fills its container evenly.
But when i try to change the background of the list items during hover etc. you can see there is empty space between each element. Is there any way to get rid of this while still making the list items fill the entire width of the container?
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
li {
color: black;
cursor: pointer;
list-style: none
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>
For example here the items are evenly spaced, but there's lots of space between each item.
What i want is something like this when i hover over a list item:
Any ideas how to do this?
Remove all extern padding/margin then use flex:1 and padding within li:
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
padding:0;
margin:0;
display: flex;
flex-wrap: wrap;
}
li {
color: black;
flex:1;
text-align:center;
padding:10px 0;
cursor: pointer;
list-style: none
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>
.wrapper {
margin-top: 30px;
border: 1px solid lightblue;
width: 100%;
}
ul {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
li {
width: 100%;
color: black;
cursor: pointer;
list-style: none;
text-align: center;
padding: 15px 0;
}
li:hover {
background-color: lightblue;
color: white;
}
<div class="wrapper">
<ul>
<li>123</li>
<li>ABC</li>
<li>789</li>
<li>XYZ</li>
</ul>
</div>

List exceeds width of parent container

I want to build a navigation in the header containing three items where the first two ones are aligned left and the third one is aligned right. Tried it by use of flexbox but there is an arror: The ul is exceeding the width of it's parent container.
header {
width: 100%;
background: #417690;
margin-left: 10px;
margin-right: 10px;
font-size: 20px;
height: 70px;
}
header ul {
height: 100%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: center; */
}
header ul li {
display: inline-block;
padding-right: 15px;
margin-left: 10px;
}
.filler {
flex-grow: 1;
}
<header>
<ul>
<li>Logo</li>
<li>New article</li>
<li class="filler"></li>
<li>username</li>
</ul>
</header>
How can I fix this?
Tested in FF and Opera.
Reset margin to zero and add box-sizing: border-box to all elements to include the padding in the size calculations. You may also reset the padding for the ul element - see demo below:
* { /* ADDED */
box-sizing: border-box;
}
header {
width: 100%;
background: #417690;
/*margin-left: 10px;
margin-right: 10px;*/
font-size: 20px;
height: 70px;
}
header ul {
height: 100%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: center; */
padding: 0; /* ADDED */
}
header ul li {
display: inline-block;
padding-right: 15px;
margin-left: 10px;
}
.filler {
flex-grow: 1;
}
<header>
<ul>
<li>Logo</li>
<li>New article</li>
<li class="filler"></li>
<li>username</li>
</ul>
</header>
Try this:
header ul {
box-sizing: border-box;
padding: 0;
}

Extra space under page footer

I'm remaking an article I found on The Economist (here) and I ran into an issue with my footer where it showed a very thin line of white space under the footer.
I actually resolved the issue but I'm not sure why what I did worked.. Here's the pen for it (here), and here's the footer and HTML code.
/****************
Footer
****************/
/*
The footer is organized into three rows with columns in each row.
*/
footer {
height: 400px;
border-top: 5px red solid;
margin-top: 50px;
background-color: #c1c1c1;
color: white;
background-color: #161616;
}
.footer-container {
width: 80%;
height: 100%;
margin: 0 auto;
}
footer ul {
list-style: none;
}
a:link {
text-decoration: none;
color: #b6b6b6;
font-weight: bold;
font-size: .9em;
}
a:link:hover {
color: white;
}
.footer-link {
padding: 10px 0;
color: #b6b6b6;
font-weight: bold;
}
.footer-link:hover {
color: white;
cursor: pointer;
}
.row-1 {
display: flex;
height: 50%;
}
.row-1-col-1 {
width: 10%;
text-align: left;
display: flex;
flex-direction: column;
justify-content: center;
}
.row-1-col-1 ul {
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 0;
padding: 0 15px;
height: 70%;
}
.row-1-col-2 {
width: 60%;
display: flex;
flex-direction: column;
justify-content: center;
}
/* "Keep updated */
.row-1-col-2 div p {
font-weight: bold;
color: #7a7a7a;
}
.row-1-col-2 > div {
height: 70%;
margin-left: 30px;
padding-left: 30px;
border-left: 1px #7a7a7a solid;
border-right: 1px #7a7a7a solid;
}
.row-1-col-2 ul {
padding: 0;
display: flex;
}
.footer-s-media-icon {
width: 25px;
padding: 0 15px;
filter: grayscale(100%);
}
.row-1-col-3 {
display: flex;
flex-direction: column;
justify-content: center;
width: 30%;
}
.row-1-col-3 ul {
height: 70%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.row-2 {
height: 40%;
border-top: 1px #7a7a7a solid;
border-bottom: 1px #7a7a7a solid;
}
.row-2-col-1 {
height: 100%;
}
.row-2-col-1 > div {
margin: 0 auto;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.row-2-col-1 > div p {
margin: 0;
text-align: center;
}
/* Published since Sept...to take part in... */
.row-2-col-1 > div p:first-child {
font-weight: bold;
}
/* "a severe contest between intellegence... */
.row-2-col-1 > div p:nth-child(2) {
font-style: italic;
}
.row-3 {
height: 9%;
width: 100%;
display: flex;
}
.row-3-col-1 {
display: flex;
width: 100%;
}
.row-3-col-1 ul {
display: flex;
padding: 0;
margin-bottom: 0;
}
.row-3-col-1 li {
padding: 0 8px;
font-size: .8em;
}
.row-3-col-1 p {
margin-bottom: 0;
margin-top 0;
margin-left: auto;
font-size: .8em;
}
<footer>
<div class="footer-container">
<div class="row-1">
<div class="row-1-col-1">
<ul>
<li class="footer-link">Subscribe</li>
<li class="footer-link">Contact us</li>
<li class="footer-link">Help</li>
</ul>
</div>
<div class="row-1-col-2">
<div>
<p>Keep updated</p>
<ul>
<li><img src="https://www.celestionplus.com/wp-content/themes/celestion-impulse-response-2017/img/icon-facebook.png" class="footer-s-media-icon"></li>
<li><img src="http://www.vonmaur.com/Images/Social/twitter-logo-blue.png" class="footer-s-media-icon"></li>
<li><img src="https://www.carpetone.com/~/media/CarpetOne/Modules/Global/Footer/SocialLinks/google.png?h=30&w=30&la=en" class="footer-s-media-icon"></li>
<li><img src="http://www.shoetastic.ie/skin/frontend/default/theme054/images/linkedin-logo.png" class="footer-s-media-icon"></li>
<li><img src="https://2.bp.blogspot.com/-GEyWc6EEApk/VYCEOt34T-I/AAAAAAAAAmw/slVlbI1gy_c/s1600/tumblr%2Blogo%2B30x30.png" class="footer-s-media-icon"></li>
<li><img src="http://www.oacsd.org/sysimages/iconIG.png" class="footer-s-media-icon"></li>
<li><img src="http://www.sunyjefferson.edu/sites/default/files/images/YouTube-icon.png" class="footer-s-media-icon"></li>
<li><img src="http://theriveratranchomirage.com/wp-content/uploads/2015/11/favicon.png" class="footer-s-media-icon"></li>
</ul>
Subscribe to The Economist newsletters
</div>
</div>
<div class="row-1-col-3">
<ul>
<li class="footer-link">Advertise</li>
<li class="footer-link">Careers</li>
<li class="footer-link">Site Map</li>
<li class="footer-link">Reprints</li>
<li class="footer-link">Media Centre</li>
</ul>
</div>
</div>
<div class="row-2">
<div class="row-2-col-1">
<div>
<p>Published since September 1843 to take part in</p>
<p> “a severe contest between intelligence, which presses forward, and an unworthy, timid ignorance obstructing our progress.”</p>
</div>
</div>
</div>
<div class="row-3">
<div class="row-3-col-1">
<ul>
<li>Terms of Use</li>
<li>Privacy</li>
<li>Cookies</li>
<li>Accessibility</li>
</ul>
<p>Copyright © The Economist Newspaper Limited 2017. All rights reserved.</p>
</div>
</div>
</div>
</footer>
The footer is made of three rows all of which fall within a container. The columns have heights of 50%, 40%, and 9%. The issue was caused due to the 3rd row having a height of 10% which should have summed up to the full 100% of the footer container.
My question is, why did changing the 3rd row's height fix this issue? Does anyone have any background knowledge that would fill in this information for me?
It's because of the borders that you have applied with .row-2 are not calculated as part of the height of the element. They're in addition to it's height. In the end .row-2 is 2px larger than 40%.
You can fix this with box-sizing: border-box;.
border-box
This is the box model used by Internet Explorer when the document is in Quirks mode. Note that padding and border will be inside of the box e.g. .box {width: 350px; border: 10px solid black;} leads to a box rendered in the browser of width: 350px. The content box can't be negative and is floored to 0, making it impossible to use border-box to make the element disappear.
Here the dimension is calculated as, width = border + padding + width of the content, and height = border + padding + height of the content.
.footer-container > .row-2 {
box-sizing: border-box;
}
You could also use calc() for height.
.row-2 {
height: calc( 40% - 2px );
border-top: 1px #7a7a7a solid;
border-bottom: 1px #7a7a7a solid;
}
The one issue I have with calc() is if you change the thickness of your borders at all you also have to update the value for height. With box-sizing: border-box; it's automatic.

HTML: Show full content of non-floated element on tree/menu structure

I need to properly skin a menu/tree like structure.
Each item is composed by three elements: two floats (one left and one right) and the last non-floated to fill the remaining space automatically expanding the container when possible.
In the first level all renders properly but on sub-levels the width of container is too small.
NOTE: I need each level ul container will be independently sized based on its content.
HTML example structure:
<ul>
<li>
<div class="link">
<span></span>
<span>3434</span>
<span>Item 1</span>
</div>
<ul>
<li>
<div class="link">
<span></span>
<span>123</span>
<span>Item 1.2</span>
</div>
</li>
<li>
<div class="link">
<span></span>
<span>312</span>
<span>Item 1.2342342</span>
</div>
</li>
<li>
<div class="link">
<span></span>
<span>12</span>
<span>Item 1.2234123</span>
</div>
</li>
</ul>
</li>
<li>
<div class="link">
<span></span>
<span>3453</span>
<span>Item 2123123123123123123</span>
</div>
</li>
<li>
<div class="link">
<span></span>
<span>34534</span>
<span>Item asdasdasd</span>
</div>
</li>
</ul>
CSS:
ul {
position: absolute;
background: white;
border: 1px solid black;
overflow: visible;
margin: 0;
padding: 0;
}
li {
position: relative;
margin: 0;
padding: 0.1em 0.5em;
}
ul>li>ul {
left: 100%;
}
.link {
display;
block;
position: relative;
}
.link>span:nth-child(1) {
display: block;
float: left;
width: 1em;
height: 1em;
margin-right: 0.25em;
background: cyan;
}
.link>span:nth-child(2) {
display: block;
float: right;
height: 1em;
margin-left: 0.25em;
background: red;
color: white;
}
.link>span:nth-child(3) {
display: block;
white-space: nowrap;
overflow: auto;
}
Here a jsfiddle to better show the problem
You can increase the width of the .ul>.li>.ul element:
ul>li>ul {
left: 100%;
width:100%;
}
This will make it increase to be the same width as the top level menu:
https://jsfiddle.net/dxr76e1z/1/
You could render inner <ul> as a table and it will autosize to fit its contents:
ul>li>ul {
left: 100%;
display: table;
}
Finally I have found the solution using flexbox model. This method preserve also jQuery animations.
Only CSS update is needed:
ul {
display: block;
position: absolute;
list-style: none;
background-color: orange;
border: 1px solid red;
padding: 0.2em;
}
li {
display: block;
}
ul>li>ul {
left: 100%;
}
.link {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: stretch;
align-content: stretch;
margin: 0.2em;
}
.link>span {
display: block;
align-self: auto;
}
.link>:nth-child(1) {
flex-shrink: 0;
width: 1em;
background-color: cyan;
margin-right: 0.25em;
}
.link>:nth-child(2) {
order: 1;
flex-shrink: 0;
background-color: red;
margin-left: 0.25em;
white-space: nowrap;
color: white;
}
.link>:nth-child(3) {
flex-basis: 100%;
flex-shrink: 1;
background-color: yellow;
white-space: nowrap;
}
Here the updated jsfiddle.