List items with flexbox - and sometimes a link - css

I have some list items which contains an image and text aligned side by side. The image part always stays the same width (in px) whereas I would like the box next to it to fill out the rest of the space.
In my example, it works fine. But if I want the list item to become a link
.advanced-list {
padding-left: 0;
list-style: none;
}
.advanced-list li {
display: flex;
min-height: 80px;
zoom: 1;
flex-direction: row;
background-color: #f5f5f5;
}
.advanced-list li .list-img {
display: block;
height: 235px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
flex: 0 0 235px;
order: 1;
}
.advanced-list li .list-content {
padding: 15px;
line-height: 1.3333333;
order: 2;
}
.advanced-list li .list-content .list-header {
margin-top: 0;
margin-bottom: 5px;
}
.advanced-list li .advanced-link {
display: flex;
color: #252525;
text-decoration: none;
flex-direction: row;
}
.advanced-list li+li {
margin-top: 5px;
}
<ul class="advanced-list">
<li>
<div class="list-content">
<h4 class="list-header">List item without link</h4> Lorem ipsum dolor...
</div>
<div class="list-img" style="background-image: url('https://placehold.it/550x300?text=Img:+550+x+300')"></div>
</li>
<li>
<a href="#" class="advanced-link">
<div class="list-content">
<h4 class="list-header">List item with link inside</h4> Short text - keep width 100%.
</div>
<div class="list-img" style="background-image: url('https://placehold.it/550x300?text=Img:+550+x+300')"></div>
</a>
</li>
</ul>
by adding a link around it, something goes wrong:
See this fiddle - the second list item has a link - how should the flexbox be applied here so that the text takes up the remaining width?

Your .advanced-link anchor element is in a flex container. So it wont have full width.
Set :
.advanced-list li .advanced-link {
width: 100%;
}
or
.advanced-list li .advanced-link {
flex: 1
}

Related

Align item left, or right if no room left in window

How can you display an item per default in its "normal" position (preferably over any following items), like this:
div {
border: 1px solid black;
}
ul {
display: flex;
padding: 0;
list-style: none;
width: 250px;
border: 1px solid black;
}
li {
display: flex;
position: relative;
}
.item {
padding: 0.4em;
background-color: #f99;
}
.dropdown {
position: absolute;
left: 100%;
z-index: 1;
padding: 0.4em;
opacity: 0.7;
background-color: #2f6f44;
}
<ul>
<li>
<div class="item">First</div>
</li>
<li>
<div class="item">Second</div>
<div class="dropdown">Dropdown</div>
</li>
<li>
<div class="item">Third</div>
</li>
<li>
<div class="item">Fourth</div>
</li>
</ul>
but if the window becomes too small (represented by the ul here), it sticks to the right:
div {
border: 1px solid black;
}
ul {
display: flex;
position: relative;
padding: 0;
list-style: none;
width: 150px;
border: 1px solid black;
}
li {
display: flex;
}
.item {
padding: 0.4em;
background-color: #f99;
}
.dropdown {
position: absolute;
right: 0;
z-index: 1;
padding: 0.4em;
opacity: 0.7;
background-color: #2f6f44;
}
<ul>
<li>
<div class="item">First</div>
</li>
<li>
<div class="item">Second</div>
<div class="dropdown">Dropdown</div>
</li>
<li>
<div class="item">Third</div>
</li>
<li>
<div class="item">Fourth</div>
</li>
</ul>
In other words, if (this.left + this.width > totalWidth) stick right else stay left.
I can either get one or the other behaviour (like above), but not so that it switches seamlessly between the two.
The simplest solution is to compute the element width and the window width and position it using JavaScript, but bugs/edge cases easily slip in, so I'm trying to look for a complete CSS solution.
Any number of containers/wrappers are welcome. One solution I tried looking at was wrapping all the "following" elements (Third and Fourth in the examples above) in a separate li with Dropdown. That way a flex element can take up the space between the previous element (Second) and the edge of the container, but then Dropdown can't go any further left than Second (if the container gets too small).
The elements are dynamic in width based upon changing content.

Give an optimal flexbox width but allow shrink when parent has no more room

I have a wrapper div with flexbox on it, containing two other divs:
The right hand div has 3 other divs in it, one is a search bar
Is there a way I can use flexbox to say fill all the space available, unless the parent is being forced to shrink?
This is my CSS
.header-nav {
background: $storm;
.container {
display: flex;
justify-content: space-between;
}
.logo {
display: block;
}
a {
color: #fff;
text-decoration: none;
}
.is-search {
display: flex;
align-items: center;
background:yellow;
}
}
.header-nav-profile {
display: flex;
}
.block-menu,
.inline-menu {
display: flex;
margin: 0;
padding: 0;
li {
list-style: none;
}
}
.inline-menu {
display: flex;
align-items: center;
a {
padding: 2px 12px 2px 10px;
}
}
.block-menu {
border-left: 1px solid $grey;
border-right: 1px solid $grey;
a {
display:block;
padding: 25px;
box-sizing: border-box;
}
li + li a,
.is-search {
border-left: 1px solid $grey;
}
.is-search {
padding-left: 18px;
padding-right: 18px;
// flex-basis: 280px;
}
}
And HTML
<div class="header-nav">
<div class="container">
<div class="header-nav-profile">
<a href="/">
<img src="http://placehold.it/80x80" alt="Logo" class="logo">
</a>
<ul class="inline-menu">
<li>
Name
</li>
<li class="has-icon">
Add bookmark
</li>
<li>
View bookmark
</li>
</ul>
</div>
<ul class="block-menu">
<li>
Dashboard
</li>
<li>
Period
</li>
<li>
Filters
</li>
<li class="is-search">
<div class="search">
<input type="text" placeholder="Search">
<span class="submit"></span>
</div>
</li>
</ul>
</div>
</div>
I have a link to a demo if you want to try it out:
https://codepen.io/EightArmsHQ/pen/dmZxRv?editors=1100
I'd like the search bar to have a good length (longer than the other two items in its div) then as the width gets smaller only then does it start shrinking.
Modify your block menu class like this:
.block-menu {
border-left: 1px solid grey;
border-right: 1px solid grey;
flex-grow:1;
justify-content:flex-end
}
Basically you can use flex-grow to take up the available space and then justify-content:flex-end to move them to the right (end of) the container.
Here is a codepen
Try using max-width: pixel amount; and max-height: pixel amount;.
It that doesn’t work, it’s possible with #media tags.
.selector {
width: normal width;
}
#media (max-width: 800px) {
.selector {
width: percent amount; /* Width when window is thinner than 800px */
}
}

CSS: increase width for list items

I am new to css and am currently trying to split the screen in two parts and place text on the left and the right side. However, for some reason the right "box" doesn't cover the whole right part of the screen, only like 200-300 px...
JSFiddle:
https://jsfiddle.net/19mw8hzL/
The black text should reach to the right side of the screen.
<div class="wrapper">
<div id="one">
<p class="w-text-1">Strategy</p>
</div>
<div id="two">
<ul>
<li>Visioning</li>
<li>Strategic Analysis</li>
<li>Strategy Formulation</li>
<li>Business Model Innovation</li>
<li>Financial Modeling</li>
</ul>
</div>
</div>
Flexbox can do that.
.w-text-1 {
font-family: 'Garamond', serif;
color: rgba(163, 42, 46, 1);
font-size: 35px;
}
.wrapper {
display: flex;
}
.wrapper div {
color: #fff;
}
#one {
width: 20%;
}
#two {
flex: 1;
background: lightblue;
text-align: right;
}
#two a {
text-decoration: none;
font-family: 'Gotham', sans-serif;
font-size: 17px;
color: #000;
border: 1px solid grey;
}
#two ul {
overflow: hidden;
padding: 0;
}
#two li {
display: inline-block;
margin: 5px 0 0 0;
}
<div class="wrapper">
<div id="one">
<p class="w-text-1">Strategy</p>
</div>
<div id="two">
<ul>
<li>Visioning
</li>
<li>Strategic Analysis
</li>
<li>Strategy Formulation
</li>
<li>Business Model Innovation
</li>
<li>Financial Modeling
</li>
</ul>
</div>
</div>
Change your css for #two, to add in the 20% of #one, to make 100%:
#two {
float: left;
overflow: hidden;
width: 76%; /* this is completing the width with the 4% padding */
padding-top: 17px;
padding-right: 4%;
}
Hi please modify these
Lets make the parent element as 100% and make the children div as 50% each
.wrapper {
width : 100%;
}
#one {
float:left;
width:50%;
}
width to 46% because we have given padding right as 4% so (46+4 = 50)
#two {
float: right;
width: 46%;
padding-top: 17px;
padding-right: 4%;
}
:)
*{
box-sizing: border-box;
}
This will remove padding as part of the width of all elements. Don't use '*' as a selector as it's quite heavy on the DOM.
#two {
width: 80%;
}
Because 20% + 80% = 100%
#two li {
display: inline-block;
}
This will add a width and a height to the li's

Oneline horizontal list with middle item that fits its content width

I have a horizontal list of items, arranged with display:table-cell.
The middle item can vary in content length, and it should expand accordingly.
And obviously its siblings should shrink to make space to it.
Here is a sample of what I did until now:
http://codepen.io/Pictor13/pen/mJoyXw
But the middle item still overflows over the right sibling, when the content grows.
Is it possible to achieve what I want? Are display: table-cell and white-space: nowrap the right approach?
Note: the width, if specified, should always be generic and not fixed to a specific px/em.
Wellll....flexbox can do that.
.container {
background-color: yellow;
padding: 1px;
}
li {
text-align: center;
border: 2px solid #ccc;
background-color: green;
color: red;
list-style: none;
}
ul {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
margin: 3px;
background-color: brown;
}
li {
-webkit-box-flex: 1;
-webkit-flex: 1 0 auto;
-ms-flex: 1 0 auto;
flex: 1 0 auto;
}
input {
width: 270px;
width: inherit;
}
form {
background-color: blue;
margin: 0;
padding: 0;
}
<div class="container">
<ul class="list">
<li>B</li>
<li>C</li>
<li class="middle">
<form>
<input type="number" value="123123418190238901390812903823" min="1" max="123012301232138192738798127398712983" />
<span>to page and with some long content</span>
<button>go</button>
</form>
</li>
<li>E</li>
<li>A</li>
</ul>
</div>
Codepen Demo

equivalent tr of CSS?

How do you separate the menu bar from the body in a div, to place everything after contact below it, is there a corresponding code like a newline? I would really appreciate the help :) Thanks in advance
here's a link of picture shot:
CSS
/* because of the * default code it takes out all margin and padding */
* {
margin: 0px;
padding: 0px;
}
#container {
display: table;
}
#row {
display: table-row;
}
#left, #right, #middle {
display: table-cell;
}
#row {
display: table-row;
}
#left, #right, #middle {
display: table-cell;
}
body {
font-family: verdana;
font-size: 10px;
background-color: ABC;
padding: 50px;
margin: auto;
}
h1 {
text-align: center;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
float: left;
position: relative;
}
li + li {
border-left: 1px solid #ccc;
}
a {
display: block;
padding: 7px 10px;
color: #222; /*changes the color of all item font color in menu bar */
background: #eee; /*changes the background color of Menu bar */
text-decoration: none;
}
a:hover {
color: #fff;
background: #666; /* changes hover bg color of any menu item being pointed*/
}
a:active {
color: #f2f75e;
background: #0090cf;
}
/* Child Menu Styles */
.level-two {
position: absolute;
top: 100%;
left: -9999px;
width: 100px;
}
li:hover .level-two {
left: 0;
}
.level-two li {
width: 100%;
border: 0;
border-top: 1px solid #ccc;
}
HTML
<h1>
<ul class="level-one">
<li> Home </li>
<li> Drops
<ul class="level-two">
<li> One </li>
<li> Two </li>
<li> Three </li>
</ul>
</li>
<li> Contact </li>
</ul>
</div>
<div id="container">
<div id="row">
<div id="left">
<h4>Left Col</h4>
<p>...</p>
</div>
<div id="middle">
<h4>Middle Col</h4>
<p>...</p>
</div>
<div id="right">
<h4>Right Col</h4>
<p>...</p>
</div>
</div>
</div>
</h1>
add clearfix class on both of .
DEMO
.clearfix{
clear:both;
}
DEMO1
One alternative to the clear property is to trigger a new block formatting context on the menu in order to contain the floats inside .level-one :
.level-one {
/* trigger block formatting context to contain floats. */
overflow: hidden;
}
Demo at http://jsfiddle.net/mrYdV/1/
Here is a list of other property/value pairs that trigger block formatting context
W3C specification
Bulletproof backwards-compatible version
There is a great answer with more details covering this method at How does the CSS Block Formatting Context work?
The clear property will do this for you. You can add it to your #container for example:
#container {
display: table;
clear:both;
}
Clear means something like:
clear all elements on both sides of this element

Resources