css - how to position <li> in horizontal <ul>? - html

I have section, which contains horizontal ul, which contains four li's,
as following:
#header-strip ul {
display: flex;
justify-content: space-between;
margin: 0;
padding: 0;
height: 4vh;
width: 100%;
background-color: grey;
list-style-type: none;
}
#header-strip li {
display: inline;
}
<section id="header-strip">
<ul>
<li>meant to be left</li
><li>meant to be centered</li
><li>meant to be just before last</li
><li>meant to be right</li
>
</ul>
</section>
Requirements:
- first item at left with some small percentage offset of screen edge
- second item centered in the middle
- third item to be at right, with some percentage space between to fourth
- fourth item at right, with percentage offset from screen edge
I am able to position li's with basic justify-content: space-between;, but don't know how to position it the custom way.
It should look like this:

Simply change the margin of the second element and make it auto
As a side note: with flexbox you don't need to worry about whitespace and no need to define element as inline
#header-strip ul {
display: flex;
margin: 0;
padding: 0;
color:#ffff;
width: 100%;
background-color: grey;
list-style-type: none;
}
#header-strip li {
margin:0 2%;
}
#header-strip li:nth-child(2) {
margin: auto;
}
<section id="header-strip">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</section>

if you are using flexbox:
<section id="header-strip">
<ul>
<li>meant to be left</li
><li class="fill">meant to be centered</li
><li>meant to be just before last</li
><li>meant to be right</li
>
</ul>
</section>
//css
.fill {
flex-grow: 2;
}

Related

aligning the bottom bar elements

Hi I am trying to align the bottombar elements so that they are in 2 columns on the side of 102. I was wondering if there is a way to fix it as they are all floating on the right at the moment. I am a beginner html css programmer and I am not very experienced yet. Ill appreciate any help you can give me!
CSS
/*bottom navbar*/
.bottomnav{
width: 100%;
background-color: rgb(248, 138, 180);
display: flex;
flex-direction: row;
}
.navbarlogo2{
display: block;
margin-left: auto;
margin-right: auto;
width: 10%;
text-decoration: none;
}
/*bottombar*/
.nav {
display: flex;
flex-direction: row;
}
.left, .right {
flex: 1;
}
HTML
<div class="bottomnav">
<ul class="bottomlogo">
<li class="navbarimg2"><img class="navbarlogo2" src="img/LOGO.png"></li>
</ul>
<div class='nav'>
<div class='left'>
<ul>
<li>About Us</li>
<li>Affiliates</li>
</ul>
</div>
<div class='right'>
<ul>
<li>TOS</li>
</ul>
</div>
</div>
</div>
END RESULT
WANTED RESULT
I made things like that. CSS Grid is one of the new HTML5 standard you should take a look. In your case, use a grid is better choice against flex because you're looking for a table-like structure.
I choosed to split your needs in 2 parts:
Center your logo
Make a 2 columns grid for your links
Centering your logo
We need to center an element and prevent it to interfere with our incoming links grid. So we'll set our container with a position: relative and place the img tag in position: absolute. Note the image's top right bottom left properties are now relative to the first parent positioned as relative.
And so we only need to make some simple maths. Note the calc() function, we don't want to center the top left corner of your logo but the center. So we need to remove the half of the defined logo's width.
navbarlogo2 {
left: calc(50% - 60px);
}
Make a 2 columns grid for your links
In order make a grid, you have to display your container as grid and set its grid-template-columns to 1fr 1fr. You can translate fr with the word fraction. So here, we're asking for a row split in 2 fractions.
Because we want a place for our logo, we're adding a gap (grid-cap) in out container to make some space between our 2 columns.
Learn more about the fr unit here.
body {
margin:0
}
.bottomnav {
width: 100%;
background-color: rgb(248, 138, 180);
position: relative;
}
.navbarlogo2 {
display: block;
margin-left: auto;
margin-right: auto;
width: 120px;
text-decoration: none;
position: absolute;
filter: brightness(10);
top: 15px;
left: calc(50% - 60px) /*center top left corner then remove half logo width (120px)*/
}
/*bottombar*/
.nav {
display: grid;
grid-gap: 120px;
grid-template-columns: 1fr 1fr;
}
.nav ul {
padding-left: 0;
}
.nav ul li {
list-style: none;
text-align: center;
padding-left: 0;
}
.left,
.right {
flex: 1;
}
<div class="bottomnav">
<div class="bottomlogo">
<img class="navbarlogo2" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg">
</div>
<div class='nav'>
<div class='left'>
<ul>
<li>About Us</li>
<li>Affiliates</li>
</ul>
</div>
<div class='right'>
<ul>
<li>TOS</li>
<li>Fourth </li>
</ul>
</div>
</div>
</div>

Justify inner Flexbox items across full width of flex container

I have a Flexbox in use for header navigation, the logo is aligned to the left and the ul items are aligned to the right as in a traditional style. Both the logo and the navigation links are flex items within a full width Flexbox, and I have given them both flex: 50%. The navigation links section is also a Flexbox (an inner Flexbox) to prevent the menu from stacking and instead behaving in a better responsive manner.
When I apply justify-content to that inner Flexbox, there is no change to the links, as if there is an overriding style or the property does not work on an inner text box. I should like the navigation links to equally divide themselves among the 50% of the screen width.
I've toyed with placing flex: auto on the items but can't keep it within the current layout by doing that, and I've tried fiddling with inline elements to see if I can remove any overriding property, but no cigar.
#nav {
display: flex;
flex: 50%;
align-items: center;
}
#logo {
margin-right: auto;
width: 50px;
height: auto;
}
#links {
margin-left: auto;
display: flex;
justify-content: space-between;
}
#links a {
text-decoration: none;
}
<nav id="nav">
<img id="logo" src="https://pngimage.net/wp-content/uploads/2018/06/logo-placeholder-png.png"/>
<ul id="links">
<li><a href="#">Link1<a></li>
<li><a href="#">Link2<a></li>
<li><a href="#">Link3<a></li>
<li><a href="#">Link4<a></li>
</ul>
</nav>
You were pretty close. Important changes I made were to set the width of the #links <ul> to 50% and add justify-content: space-between to the container #nav wrapper. A few other style changes to the ul so it doesnt have default margin and padding and I think it is behaving as you are expecting now..
#nav {
display: flex;
align-items: center;
justify-content: space-between;
}
#logo {
width: 50px;
flex: 0 0 50px;
}
#links {
width: 50%;
display: flex;
justify-content: space-between;
margin: 0;
padding: 0;
list-style: none;
}
#links a {
text-decoration: none;
}
<nav id="nav">
<img id="logo" src="https://pngimage.net/wp-content/uploads/2018/06/logo-placeholder-png.png"/>
<ul id="links">
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
<li>Link4</li>
</ul>
</nav>
I think you have problem with flex: 50%; CSS deceleration. It's not at proper place. I have re-write the html to use it properly and fixed the CSS according.
Here is the Modified CSS
#nav {
display: flex;
background: #eee;
}
#nav>#logo,
#nav>#links {
flex: 50%;
}
#logo img {
width: 50px;
height: auto;
}
#links {
display: flex;
justify-content: space-around;
list-style-type: none;
}
#links a {
text-decoration: none;
}
<nav id="nav">
<div id="logo"><img src="https://pngimage.net/wp-content/uploads/2018/06/logo-placeholder-png.png" /> </div>
<ul id="links">
<li><a href="#">Link1<a></li>
<li><a href="#">Link2<a></li>
<li><a href="#">Link3<a></li>
<li><a href="#">Link4<a></li>
</ul>
</nav>
Also the code available at codepen https://codepen.io/mobarak/pen/jRjZxB/

Making a horizontal list take up full div width, while vertical lists take up minimum width and pad the rest

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.

how to properly align list items vertically?

I wanted to create a list of items by displaying a name, a list of properties and an image. Although this seems like quite a common and easy problem, I am struggling to get it right.
After having changed the markup a dozen of times, I chose to represent the list by a ul in which each li consists of a h3(name), a ul(properties) and a img(image).
In order to make it fill the page a bit more, I used CSS's flexbox in order to put the image and the properties next to each other in a responsive way.
img {
max-width: 100px;
}
#example > ul > li {
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-around;
justify-content: space-around;
-webkit-align-items: center;
align-items: center;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
h3 {
width: 100%;
text-align: center;
}
div > ul {
border-left: 2px solid red;
}
<section id="example">
<ul>
<li>
<h3>Bulbasaur</h3>
<div>
<span>Properties</span>
<ul>
<li>green</li>
<li>seed</li>
<li>grass</li>
<li>poison</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/2/21/001Bulbasaur.png" />
</li>
<li>
<h3>Charmander</h3>
<div>
<span>Properties</span>
<ul>
<li>orange or some kind of red, I am not completely sure</li>
<li>lizard</li>
<li>fire</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/7/73/004Charmander.png" />
</li>
<li>
<h3>Squirtle</h3>
<div>
<span>Properties</span>
<ul>
<li>blue</li>
<li>tiny turtle</li>
<li>water</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/3/39/007Squirtle.png" />
</li>
</ul>
</section>
This looks pretty nice when the properties for all elements are equally long, but it kind of looks messy when this is not the case (the property-lists are not properly aligned as indicated by the red lines in the above snippet). I know I could get all the content in a table, causing every table element to be aligned nicely under each other, but then I don't know how I can have my names in a different line than the properties and the image...
My question could thus be formulated as:
How can I align the properties nicely under each other in such a way that they are displayed next to the image (to fill the space on the screen)? Additionally I would like that the image is displayed under the properties when the screen becomes too small (i.e. responsive design) and a separate line for the name.
Any help will be greatly appreciated
Update:
As it turned out that my question is not that clear, I tried to make it more clear by adding the vertical red lines in the snippet. I manage to get the desired result when using a table, but then I have to omit the names (as shown in the attached image) and the responsiveness...
You can just create a simple item element, something like this:
HTML
<li class="item">
<h2>Charmander</h2>
<div class="content">
<h3>Properties</h3>
<ul>
<li>orange or some kind of red, I am not completely sure</li>
<li>lizard</li>
<li>fire</li>
</ul>
</div>
<div class="image">
<img src="http://cdn.bulbagarden.net/upload/7/73/004Charmander.png" />
</div>
</li>
I simply divided the element in three main sections: title, properties and the image.
As you can see the properties are still inside a <ul> because they are used like a enumeration.
CSS
#example > ul {
padding: 0;
}
.item {
width: 100%;
background: #CCC;
padding: 20px;
box-sizing: border-box;
/* Padding will be inside the element (will not affect the width/height) */
margin: 20px 0;
overflow: hidden;
/* Used to keep the floated element inside the flow */
}
.item h2 {
text-align: center;
}
.item .content {
width: 60%;
float: left;
padding-left: 20px;
box-sizing: border-box;
}
.item .image {
width: 200px;
float: left;
}
.item img {
width: 100%;
}
.item .content ul {
border-left: 2px solid red;
margin-bottom: 20px;
}
With the first selector (#example > ul) I reset the default padding it has.
The text of the properties will just start on a new-line if it is too long (you can test this by resizing the window).
You can just edit the padding-left of the .content element, to move the properties a little bit more to the right or to the left.
Example JsFiddle
This is just to give you an example of how you want to approach this.
Hope it was helpful!
I have just been so stupid. As an alternative to the helpful answer of nkmol, it could also be as simple as changing the justify-content property to space-between and correct it by setting width and auto-margins.
img {
max-width: 100px;
}
#example > ul > li {
width: 80%;
margin: auto;
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
-webkit-align-items: center;
align-items: center;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
h3 {
width: 100%;
text-align: center;
}
li > div > ul {
border-left: 2px solid red;
}
<section id="example">
<ul>
<li>
<h3>Bulbasaur</h3>
<div>
<span>Properties</span>
<ul>
<li>green</li>
<li>seed</li>
<li>grass</li>
<li>poison</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/2/21/001Bulbasaur.png" />
</li>
<li>
<h3>Charmander</h3>
<div>
<span>Properties</span>
<ul>
<li>orange or some kind of red, I am not completely sure</li>
<li>lizard</li>
<li>fire</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/7/73/004Charmander.png" />
</li>
<li>
<h3>Squirtle</h3>
<div>
<span>Properties</span>
<ul>
<li>blue</li>
<li>tiny turtle</li>
<li>water</li>
</ul>
</div>
<img src="http://cdn.bulbagarden.net/upload/3/39/007Squirtle.png" />
</li>
</ul>
</section>
PS: I'm sorry for my awful question...
You need to break out your items from the primary UL
You can think of it as though you were building a table, but instead, use divs and then use a UL just to list the properties. This way, you can style each of the individual elements as needed.
look here: https://jsfiddle.net/oq04f6pm/2/
<section id="example">
<div class="section-title">Bulbasaur</div>
<div class="section-list">
<span>Properties</span>
<ul>
<li>green</li>
<li>seed</li>
<li>grass</li>
<li>poison</li>
</ul>
</div>
<div class="section-image">
<img src="http://cdn.bulbagarden.net/upload/2/21/001Bulbasaur.png" />
</div>
</section>
img {
max-width: 100px;
}
.section-title {
width: 100%;
text-align: center;
font-weight: bold;
}
.section-list, .section-image {
width: 50%;
float: left;
}
.section-image {
text-align: center;
}
#media screen and (max-width: 400px) {
.section-list, .section-image {
width: 100%;
}
.section-image {
text-align: left;
}
}

Why is justify-content space-between not doing anything?

I'm trying to get the top-nav and bot-nav divisions to separate vertically by using justify-content: space-between. However, it isn't doing anything. Can someone point out what I'm doing wrong please?
#import url(https://fonts.googleapis.com/css?family=Rock+Salt);
html {
font-family: 'Rock Salt', cursive;
}
.flex-container {
display: flex;
}
header {
width: 300px;
height: 100vh;
position: fixed;
background-color: blue;
}
nav.flex-container {
align-items: center;
flex-direction: column;
justify-content: space-between;
}
ul {
padding: 0;
margin: 0;
list-style-type: none;
}
#logo-container {
background-color: red;
width: 100%;
}
#logo {
margin: auto;
padding: 10px 0;
}
<body>
<div id="root-container">
<header>
<div id="logo-container" class="flex-container">
<h2 id="logo">Name Goes Here</h2>
</div>
<nav class="flex-container">
<div class="top-nav">
<ul>
<li>This is a list item</li>
<li>This is a list item</li>
</ul>
</div>
<div class="bot-nav">
<ul>
<li>This is a list item</li>
<li>This is a list item</li>
</ul>
</div>
</nav>
</header>
</div>
</body>
https://codepen.io/anon/pen/rxMPMN
The height of a block element defaults to the height of the block's content, unless you define a specific height. And flexbox justify-content defines how the browser distributes space between and around flex items. So it won't have any effects with flex-direction:column by default.
In your example nav.flex-container doesn't have any height defined, you can set either a percentage n% (as you already set 100vh on header, the parent element) or vh value to it.
nav.flex-container {
height: 80%; /*your value*/
}
Updated pen - https://codepen.io/anon/pen/LGRqzy
Or, set header to display:flex as well, and add flex:1 (grow) on nav.flex-container.
header {
display: flex;
flex-direction: column;
}
nav.flex-container {
flex: 1;
}
Updated pen - https://codepen.io/anon/pen/WrGPMW
You should add a height for .flex-container and then add overflow-y: scroll to the header to make the nav scrollable.
nav.flex-container
{
height: 100%;
align-items: center;
flex-direction: column;
justify-content: space-between;
}
header
{
width: $header-width;
height: 100vh;
position: fixed;
background-color: blue;
overflow-y: scroll;
}
justify-content only work in the flex-box main-axis direction, meaning flex-direction: row
You need to use align-content which is supposed to work for the cross-axis, flex-direction: column.
Reference Flexbox|Codrops Reference > align-content