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!
Related
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>
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.
I'm currently working on a menu consisting of two parts (see image). On mobile, I'd like to show these menu items stacked from top to bottom, but starting with the bottom menu and ending with the top menu. Is there any (clean) way to do this with CSS or will I have to create two menus and show the correct one depending on page width?
EDIT: To clarify, the image is just to show an example of what I mean. I'm wondering in a more general sense if it's possible to somehow reverse the divs in CSS (without absolute positioning etc).
EDIT 2: Apologies for not adding any code. Here's a small pen that shows the situation: https://codepen.io/anon/pen/GWwrMW
<div class="nav">
<ul class="nav__top">
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
<ul class="nav__primary">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
.nav__top,
.nav__primary {
list-style: none;
margin: 0 0 20px 0;
text-align: right;
li {
display: inline-block;
padding: 10px;
background-color: #ccc;
}
}
On mobile, I want the sub items to be displayed underneath the main items.
You can do this with flex and flex-direction: column-reverse, or for more control, using the order property on flex children. But with your example, flex-direction: column-reverse would work.
.nav__top li,
.nav__primary li {
display: inline-block;
padding: 10px;
background-color: #ccc;
}
#media (max-width: 420px) {
.nav {
display: flex;
flex-direction: column-reverse;
}
.nav li {
display: list-item;
}
}
<div class="nav">
<ul class="nav__top">
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
<ul class="nav__primary">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
This added CSS will reverse the order in the second menu:
.nav__primary {
display: flex;
flex-direction: row-reverse;
}
You can put it in a media query.
https://codepen.io/anon/pen/ryQjdg
ADDITION: I overread the wish of it to be stacked horizontally. In this case you need
.nav__primary {
display: flex;
flex-direction: column-reverse;
}
If you want responsive nav bar you have to use media queries. Something like this
#media screen and (max-width: 600px){
ul.topnav li {float: none;}}
This will work if your menu was built by list.
Figured it out. Since I only need to support mobile browsers I can use Flexbox:
.nav {
display: flex;
flex-direction: column-reverse;
}
I have a two column layout. Column 1 is a heading. Column 2 is a list.
I want the columns to fit to content. (e.g. Column 1 should be as wide as it's contents)
I also want the list to be horizontal.
I want to use Flexbox, so I can change items in the list and have the layout adapt accordingly.
E.g. So it looks like this:
How can I do this?
Here is my code (Codepen is here):
<div class="wrapper">
<nav class="topics">
<span class="unit unit-header">Topics: </span>
<ul id="list" class="list unit">
<li>All</li>
<li>Topic 1</li>
<li>Topic 2</li>
<li>Topic 3</li>
<li>Topic 4</li>
<li>Topic 5</li>
<li>Topic 5</li>
</ul>
</nav>
</div>
.wrapper {
width: 960px;
margin: auto;
padding-top:20px;
}
.topics {
display: flex;
}
.unit {
flex: 1 auto;
}
.list {
display:flex;
}
.list li {
flex: 1 auto;
}
If I add the following code, it works:
.unit-header {
display: table;
padding-right: 5%;
}
However, mixing table with flex-box seems a bit hacky to me. Is there a better way?
Have you tried using this instead?
.unit-header {
flex: 0 1 auto;
}
The above shorthand property means:
flex-grow: 0
flex-shrink: 1
flex-basis: auto
With a simple html list like in the example below, how do I get the list items to center when it goes onto a second line?
<div class="container">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>
.container{max-width:500px;}
li{display:block;float:left;background:grey;}
http://jsfiddle.net/hzazvwte/
When the container is shrunk and the menu items start dropping into the line below, I would like them to be centered. How can I achieve this?
You have to remove float, set text-align: center; to the container, inline-block to items, reset margin / padding and eliminate white spacing between elements.
.container {
max-width: 500px;
margin: 0 auto;
text-align: center;
}
ul {
margin: 0;
padding: 0;
}
li {
display: inline-block;
/* float: left; */
background: grey;
margin: 0;
}
Fiddle: http://jsfiddle.net/hzazvwte/4/
Do you mean the text in the li items?
.container{max-width:300px;}
li{
display:block;
float:left;
background:grey;
width: 100px;
text-align: center;
}