Flexbox drop down menu position and movement - html

I'm trying to design a header with 3 items:
----------
LOGO
---------- hidden navigation bar
----------
BUTTON
----------
Which then grows to:
----------
LOGO
----------
li
li
li
li
----------
BUTTON
----------
I'd like the logo and the button to remain vertically centered and for all growth/movement to happen downwards from the top of the button/bottom of the logo-container. I've managed this without flexbox, but I'd like to use it so that I can get a better understanding of why this isn't working.
At the moment - unless I put a large height for the logo container - which feels a bit hacky - the menu grows upwards as well as down. I'd ideally like to use justify-content: space-around but obviously that attributes some space to the hidden menu.
I feel like flex-shrink might be a solution, but I'm very much a novice at all this, and can't get it to work. Here's what I've got so far:
https://codepen.io/nwoodward/pen/RMrRVZ
$('#button').click(function() {
$('.menu').toggleClass('menu--open', 700);
})
header {
background: #808080;
display: flex;
flex-direction: column;
min-height: 100px;
}
#logo-container {
display: block;
flex-grow: 2;
background: red;
width: 100%;
height: 50px;
text-align: center;
}
#logo-container img {
height: 40px;
}
.menu {
height: 0px;
overflow: hidden;
background-color: green;
}
.menu--open {
height: auto;
}
#button {
background: blue;
width: 100%;
height: 20px;
text-align: center;
cursor: pointer;
}
#rest {
height: 500px;
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div id="logo-container">
<img src="https://trellis.co/wp-content/uploads/2015/09/hidden_meanings_facts_within_famous_logos_cover_image.jpg">
</div>
<div class="menu">
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div id="button">Click Me</div>
</header>
<section id="rest">

I don't see any good reason to use flexbox in that case. But to answer your question, the key is the header {min-height: 100px;} setting.
With the default collapsed menu, the overall computed height of elements in the header is smaller than 100px. However it will be greater than 100px when the menu expands. Therefore, it creates the effects of pushing the menu to the top first and then to the bottom.

Related

I just need to center an unordered list, and image in the middle of a blank page

I am trying to center just 2 elements in the center of a page. This is a page with clickable icons for your social links. But I need to find a way to center them in a way that they are centered no matter the device's size. Please bare in mind this is my second day ever developing. Any feedback is highly appreciated!
Here is what it should look like in the end
Here is the code I have
<div class="fresh">
<img width="160" src=logo.svg>
</div>
<div class="icons-inline">
<ul class="icons">
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
<svg>insert super long svg</svg>
</ul>
</div>
css:
.fresh {
color: #E3EEF8;
text-align: center;
padding-top: 20%;
}
.icons {
text-align: center;
padding-right: 1.5%;
}
I'm currently just using text-align and then setting the padding to 20% on the top text so that it pushes both of them down and appears centered only on MY specific screen. But I want it to work on phones, other monitors, etc.
use flex-box, try this:
You can skip the * {...} since it will override every element in your document, and you'll have to set margin and padding manually
*{
box-sizing: border-box;
padding: 0;
margin: 0;
}
.flex-container{
display: flex;
flex-flow: row wrap; /* can also try column wrap */
align-items: center;
justify-content: center;
}
#main-container{ /* this will be the size of your browser window */
width: 100%;
height: 100vh;
}
html:
<section class="flex-container" id="main-container">
<!-- your things here -->
</section>
if you want an ul to show li elementos horizontally just add flex-container class to it, it will show horizontally, then you can add this rule ul.flex-container li to treat those kind of list better, e. g:
ul.flex-container li{
margin: 15px 0 0 15px;
}
your code could look like this:
<section class="flex-container" id="main-container">
<ul class="flex-container">
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ul>
</section>
you'll have a main container with the size of fhe window with its elements centered, inside youll have a list with its elements horizontally aligned
I like to use this approach:
.pageContainer {
display: grid;
place-items: center;
min-height: 100vh;
}
You can read more about it directly from MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-items
Create a container at least as big as the screen, and align the content to the center of the container.
The centering of elements can be handled by Flexbox. You just need to make sure that the container that holds the logo and the list of social media icons is as big as any screen the user might have. You can use viewport-percentage sizes for that, for example min-height: 100vh means “make the height of this element at least 100 percent of the viewport height”, where viewport is the size of the browser window.
Here’s a working solution:
body {
margin: 0;
}
main {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
img {
margin-bottom: 16px;
}
ul {
display: flex;
list-style-type: none;
padding: 0;
}
li:not(:last-of-type) {
margin-right: 16px;
}
<main>
<img src="https://picsum.photos/id/237/280/120" alt="Logo" />
<ul>
<li>Icon 1</li>
<li>Icon 2</li>
<li>Icon 3</li>
<li>Icon 4</li>
<li>Icon 5</li>
<li>Icon 6</li>
<li>Icon 7</li>
</ul>
</main>

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>

Horizontal align for dynamic content (special case)

I have a navigation menu (header menu) in my web page which is actually takes dynamic content. The dynamic menu items are loaded into ul>li>{dynamic_content}. I want this navigation bar (I mean the ul ) in the center of the section, not vertically but horizontally. I can have text-align:center because it has multiple children tags.
Also I can't do the following,
.class{
width:50%;
margin-left:auto;
margin-right:auto;
}
because I can't set a width since this is a DYNAMIC navigation.
You may think why I can't try
.class{
position:absolute;
left:50%;
transform:translateX(-50%);
}
This is also can not be done, because I can't set the position:absolute since it's going to be a fixed header on scroll. It make some position problems in responsive.
I'm looking for an alternative to solve this problem.
You can use justify-content: center from flexbox.
.container {
display: flex;
justify-content: center;
}
<div class="container">
<span>Title 1</span>
<span>Title 2</span>
<span>Title 3</span>
</div>
Using flexbox to center the list on the page will work.
nav {
width: 100%;
display: flex;
justify-content: center;
}
ul {
margin: 0;
display: flex;
list-style: none;
}
li:not(:last-child) {
margin-right: 1rem;
}
<nav>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</nav>
If you are looking for old browsers support, another option would be using display table as it is explained here
.something-semantic {
display: table;
width: 100%;
}
.something-else-semantic {
display: table-cell;
text-align: center;
vertical-align: middle;
}
<div class="something-semantic">
<div class="something-else-semantic">
Unknown stuff to be centered.
</div>
</div>
I think I figured it out a new way to align contents Horizontally.This works nice to me and have no issue with browser compatibility.
Wrapped the navigation with a div and set text-align:center and added display:inline-block to the ul that I wanted to center.
div {
text-align: center;
}
ul {
display:inline-block;
list-style-type: none;
}
ul>li{
float:left;
}
<div>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>

Flexbox element not scrolling overflow

I'm currently trying to make a sidebar layout work. I feel like I'm nearly there but the last bit is just not working.
html,body {
width: 100%;
height: 100%;
}
#wrapper {
display: flex;
width: 100%;
height: 100%;
}
.sidebar {
height: 100%;
position: fixed;
width: 200px;
background: red;
overflow: auto;
flex-direction: column;
display: flex;
}
ul {
padding: 0;
margin: 0;
}
.menu {
flex: 1;
background: rgb(150,0,0);
}
.users {
overflow: auto;
max-height: 240px;
min-height: 100px;
}
<div id="wrapper">
<div class="sidebar">
<ul class="menu">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
<ul class="users">
<li>user 1</li>
<li>user 2</li>
<li>user 3</li>
</ul>
</div>
<div class="content">
</div>
</div>
Here is a fiddle of the layout which works better to see the issue than the above snippet:
https://jsfiddle.net/ybp4og8w/1/
All works great except when the height of the window gets really small, smaller than the menu items list. The content at the bottom disappears off screen. Ideally I'd like to have the user list sticky at the bottom (which is correct right now but I've also had this issue when messing with the code), not overlap the menu items when the height gets small but instead make the sidebar become scroll-able.
Any tips on how to achieve this?
I see your jsfiddle and apply this code in #sidebar
overflow-y:scroll;
May be this helpful.
Thanks!

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;
}
}