I made a flexbox card using HTML, CSS. I should add a dropdown menu to the bottom of the card below the footer section, which is shown by clicking the button. I tried but can not get a menu of the same width as a card and right position. How can I achive this?
function showMenu() {
document.getElementById('dropdown').classList.toggle('show');
}
.card {
display: flex;
flex-direction: column;
height: 300px;
width: 200px;
border: 1px solid black;
position: relative;
}
.card .header {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}
.card .body {
display: flex;
flex: 5;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
border-top: 1px solid black;
}
.card .footer {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}
.dropdown-content {
display: none;
flex: 2;
position: absolute;
background-color: blue;
overflow: none;
z-index: 999;
color: #ffffff;
flex-direction: column;
}
.show {
display: block;
}
<div class="card">
<div class="header">
Header
</div>
<div class="body">
Body
</div>
<div class="footer">
<button onclick="showMenu()">Toggle Menu</button>
</div>
<ul id="dropdown" class="dropdown-content">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</div>
I need dropdown menu same size as card and positioned below footer
Add top: 100%, box-sizing: border-box and margin: 0 to the menu.
function showMenu() {
document.getElementById('dropdown').classList.toggle('show');
}
.card {
display: flex;
flex-direction: column;
height: 300px;
width: 200px;
border: 1px solid black;
position: relative;
}
.card .header {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}
.card .body {
display: flex;
flex: 5;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
border-top: 1px solid black;
}
.card .footer {
display: flex;
flex: 2;
justify-content: center;
align-items: center;
}
.dropdown-content {
margin: 0;
box-sizing: border-box;
display: none;
position: absolute;
top: 100%;
width: 100%;
flex: 2;
background-color: blue;
overflow: none;
z-index: 999;
color: #ffffff;
flex-direction: column;
}
.show {
display: block;
}
<div class="card">
<div class="header">
Header
</div>
<div class="body">
Body
</div>
<div class="footer">
<button onclick="showMenu()">Toggle Menu</button>
</div>
<ul id="dropdown" class="dropdown-content">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</div>
Related
I have the following setup:
.layout {
display: flex;
flex-direction: column;
height: 100vh;
}
.appbar {
background-color: blue;
color: white;
}
.sidebar {
flex-grow: 1;
overflow-y: auto;
}
.drawer-container {
height: 100%;
display: flex;
}
.drawer {
position: relative;
background-color: #272b34;
color: lightgray;
border-style: none;
align-self: stretch;
overflow-y: auto;
}
.list {
list-style: none;
padding: 1rem;
}
.drawer-content {
padding: 1rem 1rem 1rem 1rem;
margin-top: 1px;
align-self: stretch;
background-color: #eef5f9;
overflow: auto;
flex: 1 1 auto;
}
.component {
background-color: white;
height: 100%;
box-shadow: 0px 0px 3px 1px rgb(0 0 0 / 10%);
overflow: auto;
border-radius: 4px;
}
.header {
padding: 1rem 1rem 1rem;
background-color: #f8f9fa;
}
.grid-container {
margin: 1rem 1rem;
height: calc(100% - 82px);
background-color: red;
}
.grid {
background-color: yellow;
max-height: 100%;
overflow: auto;
}
.grid-content {
height: 500px;
}
<div id="layout" class="layout">
<div id="appbar" class="appbar">
APPBAR
</div>
<div id="sidebar" class="sidebar">
<div id="drawercontainer" class="drawer-container">
<div id="drawer" class="drawer">
<ul class="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div id="drawercontent" class="drawer-content">
<div id="component" class="component">
<div class="header">HEADER</div>
<div class="grid-container">
<div class="grid">
<div class="grid-content">GRID CONTENT</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The question is about this piece of css:
.grid-container {
margin: 1rem 1rem;
height: calc(100% - 82px);
background-color: red;
}
Setting the height like this, I can avoid, that the component element has a scrollbar. It means, the grid-container and the header have a total height of the component. But if I test it with different screen size / pixel ratio, I get a scrollbar (with little scrolling). Note, that the component has to have the property overflow set.
The question is, how can I avoid to set the height this way? How can I avoid the use of pixels or any other units? Basically, I want that the grid-container fills always the remaining area from the component element on any screen sizes / resolutions, without showing any scrollbar, it means not extending it.
Hopefully this snippet does what you want:
Sane default of box-sizing: border-box on every element
Removed stupid margin on the body which caused pagewide scrollbar on 100vh height
Swapped margin on grid-container for padding
Tidied up some shorthands etc. padding: 1rem 1rem 1rem 1rem -> padding: 1rem are the same
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.layout {
display: flex;
flex-direction: column;
height: 100vh;
}
.appbar {
background-color: blue;
color: white;
}
.sidebar {
flex-grow: 1;
overflow-y: auto;
}
.drawer-container {
height: 100%;
display: flex;
}
.drawer {
position: relative;
background-color: #272b34;
color: lightgray;
border-style: none;
align-self: stretch;
overflow-y: auto;
}
.list {
list-style: none;
padding: 1rem;
}
.drawer-content {
padding: 1rem;
margin-top: 1px;
align-self: stretch;
background-color: #eef5f9;
overflow: auto;
flex: 1 1 auto;
}
.component {
height: 100%;
box-shadow: 0px 0px 3px 1px rgb(0 0 0 / 10%);
overflow: auto;
border-radius: 4px;
}
.header {
padding: 1rem;
background-color: #f8f9fa;
}
.grid-container {
padding: 1rem;
height: calc(100% - 82px);
}
.grid {
background-color: yellow;
max-height: 100%;
overflow: auto;
}
.grid-content {
height: 500px;
}
<div id="layout" class="layout">
<div id="appbar" class="appbar">
APPBAR
</div>
<div id="sidebar" class="sidebar">
<div id="drawercontainer" class="drawer-container">
<div id="drawer" class="drawer">
<ul class="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
</div>
<div id="drawercontent" class="drawer-content">
<div id="component" class="component">
<div class="header">HEADER</div>
<div class="grid-container">
<div class="grid">
<div class="grid-content">GRID CONTENT</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I'm having some problems creating a header.
Here, my ul is not using the full height of the nav, but the nav IS using the full height of the header.
I want to fix this in order to center vertically the text.
Thank you.
(edit) When I use height: 100%; on the ul, this happens.
This is my HTML:
<header>
<div class="logo">
<img src="img/logo.png"/>
</div>
<nav>
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>WORKS</li>
<li>CONTACT</li>
</ul>
</nav>
</header>
This is my SASS:
$BLACK:#000;
$WHITE:#fff;
* {
box-sizing: border-box;
}
header {
width: 100%;
height: 75px;
background-color: $BLACK;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
.logo {
width: 50%;
display: flex;
align-items: center;
padding-left: 50px;
}
nav {
width: 50%;
padding-right: 50px;
ul {
list-style-type: none;
display: flex;
flex-flow: row wrap;
justify-content: right;
li {
display: inline-block;
margin-left:50px;
a {
text-decoration: none;
color: $WHITE;
}
}
}
}
}
Here is a solution for this. Just add line-height: 75px; to the li elements and set the ul element's margin to zero by adding margin: 0px;.
* {
box-sizing: border-box;
}
header {
width: 100%;
height: 75px;
background-color: #000;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
header .logo {
width: 50%;
display: flex;
align-items: center;
padding-left: 50px;
}
header nav {
width: 50%;
padding-right: 50px;
}
header nav ul {
list-style-type: none;
display: flex;
flex-flow: row wrap;
justify-content: right;
margin: 0px;
}
header nav ul li {
display: inline-block;
margin-left: 50px;
line-height: 75px;
}
header nav ul li a {
text-decoration: none;
color: #fff;
}
<header>
<div class="logo">
<img src="img/logo.png"/>
</div>
<nav>
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>WORKS</li>
<li>CONTACT</li>
</ul>
</nav>
</header>
However I converted your SASS code into CSS to run it on the stack overflow code snippet runner. You can change this to SASS again if you want.
Thanks and best regards!
Its probably because you did not reset the margin for the ul tag and also apply a 100% percent height to it also.
$BLACK: #000;
$WHITE: #fff;
* {
box-sizing: border-box;
// margin: 0;
// padding: 0;
}
header {
width: 100%;
height: 75px;
background-color: $BLACK;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
.logo {
width: 50%;
display: flex;
align-items: center;
padding-left: 50px;
}
nav {
width: 50%;
padding-right: 50px;
background: red;
ul {
list-style-type: none;
display: flex;
flex-flow: row wrap;
justify-content: right;
background: orange;
height: 100%;
li {
display: inline-block;
margin-left: 50px;
a {
text-decoration: none;
color: $WHITE;
}
}
}
}
}
<header>
<div class="logo">
<img src="https://via.placeholder.com/20x20.png/09f/fff" />
</div>
<nav>
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>WORKS</li>
<li>CONTACT</li>
</ul>
</nav>
</header>
Please update your css with following code:
$BLACK:#000;
$WHITE:#fff;
* {
box-sizing: border-box;
}
header {
width: 100%;
height: 75px;
background-color: $BLACK;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
.logo {
width: 50%;
display: flex;
align-items: center;
padding-left: 50px;
}
nav {
width: 50%;
padding-right: 50px;
height: 100%;
display: flex;
align-items: center;
ul {
list-style-type: none;
display: flex;
flex-flow: row wrap;
justify-content: right;
flex: 1 0 auto;
align-self: stretch;
align-items: center;
li {
display: inline-block;
margin-left:50px;
a {
text-decoration: none;
color: $WHITE;
}
}
}
}
}
How can I align 2 different Component side by side using flexbox ?
I have my 1st component "nav-menu" and the 2nd "homepage" I would like it to be side by side.
homepage.component.html
<app-nav-menu></app-nav-menu>
<div class="container">
<div>
<img src="https://colorlib.com/preview/theme/amado/img/product-img/pro-big-1.jpg">
</div>
</div>
I gave a width to my container
homepage.component.css
.container {
display: flex;
width: 50%;
}
div.container>div {
flex-grow: 1;
}
img {
width: 20%;
height: auto;
}
nav-menu.component.html
<h1>Furniture</h1>
<nav class="nav" role="navigation">
<ul clas="menu">
<li>Home</li>
<li>Shop</li>
<li>Product</li>
<li>Cart</li>
</ul>
</nav>
I gave a width to my nav
nav-menu.component.css
* {
box-sizing: border-box;
}
h1 {
display: flex;
justify-content: space-between;
margin-left: 30px;
margin-bottom: 100px;
}
nav {
width: 40%;
}
.nav ul {
margin: 0px;
padding: 0px;
background: white;
list-style: none;
}
.nav a {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0.5em;
text-decoration: none;
color: black;
font-size: 2em;
width: 10px;
}
.nav a:hover {
color: #FFA500;
transition: 0.1s;
}
whats the next step ?
thanks.
you have to wrap your both components in a flex
<div style="display: flex; flex-grow: grow">
<app-component-1></app-component-1>
<app-component-2></app-component-2>
</div>
I was experimenting with flexbox on IE and noticed that my navigation bar does not work the same on IE compared to all other browsers.
The navigation bar should appear on two lines as soon as the buttons on the right don't fit in the space right next to the logo. If it doesn't fit, it's pushed on the second line with flex-wrap: wrap. And when it's pushed to the second line it centers all buttons over the entire width of the screen.
I fixed this by using a high flex-grow number on the spacer between the logo and the navigation bar. This works well on chrome, edge, etc, but not on internet explorer 11.
The demo I use for to test this:
https://jsfiddle.net/td2rq4h1/
*{
box-sizing: border-box;
}
body{
background: red;
}
.logo{
background-color: yellow;
width: 145px;
height: 70px;
margin-right: 100px;
}
#headermenu{
background-color: gray;
.telephone {
border: 3px solid pink;
width: 145px;
height: 30px;
margin-right: 100px;
}
}
#menu{
background-color: blue;
}
.spacer {
flex-grow: 1000;
background-color: green;
display: flex;
flex-wrap: wrap;
}
.inner-spacer {
flex-grow: 1;
flex-basis: 100%;
}
.link {
flex-grow: 0;
}
nav{
border: 5px solid black;
flex: 1 1;
display: flex;
justify-content: center;
}
ul{
list-style: none;
margin: 0;
padding: 0;
text-align: center;
}
li{
border: 2px solid purple;
background-color: white;
padding: 1em;
white-space: pre;
margin: 0;
display: inline-block;
}
<div id="menu" class="d-flex flex-wrap">
<div class="logo">Logo</div>
<div class="spacer"></div>
<nav>
<ul class="d-flex flex-row">
<li>Home</li>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
</ul>
</nav>
</div>
Can anybody explain me why this happens and how i could resolve this? Thanks
you may reduce the use of flex: x properties and play with margin instead ... hudge flex value..
example forked from the broken jsfiddle:
* {
box-sizing: border-box;
}
.d-flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
body {
background: red;
}
.logo {
background-color: yellow;
width: 145px;
height: 70px;
margin-right: 100px;
}
#headermenu {
background-color: gray;
}
#headermenu .telephone {
border: 3px solid pink;
width: 145px;
height: 30px;
margin-right: 100px;
}
#menu {
background-color: blue;
}
.spacer {
flex-grow: 1;
background-color: green;
display: flex;
}
nav {
border: 5px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
}
nav ul {
list-style: none;
margin: 0 auto;
padding: 0;
text-align: center;
}
nav ul li {
border: 2px solid purple;
background-color: white;
padding: 1em;
white-space: pre;
margin: 0;
display: inline-block;
}
<div id="menu" class="d-flex flex-wrap">
<div class="logo">Logo</div>
<div class="spacer"></div>
<nav>
<ul class="d-flex flex-row">
<li>Home</li>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
</ul>
</nav>
</div>
explanation : IE11 will be soon a decade old and did not update bugs on its flex implementation since. it's been edge since, and even edge will stop being updated.
I am trying to create the layout shown in the diagram below with css flex, I am part way there but need to help with the 3 boxes on the right and the box on the bottom, can anyone help?
layout view needed:
this is how far i got: my attempt on the view on jsfiddle
.game-heading{background: #a3a3a3;}
header{
display: flex;
}
article{
display: flex;
}
.scores {
display: flex;
flex-wrap: wrap;
flex: 1;
line-height: 1;
}
.period {
background: #c29d31;
padding: 5px 10px;
text-align: center;
}
.results{
display: flex;
flex-direction: column;
}
.score-nr {
background: #9E8231;
flex: 1;
line-height: 10px;
padding: 6px;
}
.competitors{
color: #2d2929;
flex-direction: row;
align-items: flex-start;
float: left;
flex-grow: 0;
}
.fa {
align-self: center;
padding: 10px;
}
.venue-content{
background: #a3a3a3;
width: 100%
}
h4{
display: inline-flex;
}
.competitor-name {
padding: 4px;
}
ul li{
padding: 5px 10px;
border: 1px solid #808080;
}
Here is a start, where I moved the ft-container inside the header, positioned before the venue-content.
Then, by splitting the ul into to 2 ul, you can easily line them up side-by-side, adding display: flex to the ft-container.
Updated fiddle
Stack snippet
body {
font-size: 12px;
}
.game-heading {
background: #a3a3a3;
}
header {
display: flex;
}
article {
display: flex;
}
.scores {
display: flex;
flex-wrap: wrap;
flex: 1;
line-height: 1;
}
.period {
background: #c29d31;
padding: 5px 10px;
text-align: center;
}
.results {
display: flex;
flex-direction: column;
}
.score-nr {
background: #9E8231;
flex: 1;
line-height: 10px;
padding: 6px;
}
.competitors {
color: #2d2929;
flex-direction: row;
align-items: flex-start;
float: left;
flex-grow: 1;
}
.fa {
align-self: center;
padding: 10px;
}
.venue-content {
background: #a3a3a3;
width: 100%
}
h4 {
display: inline-flex;
}
.competitor-name {
padding: 4px;
}
/* styles below have been changed/added */
ul li {
padding: 5px 10px;
}
ul {
border: 1px solid #808080;
}
.ft-container {
display: flex;
}
.ft-container ul:last-child {
display: flex;
align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<section class="container-one-row two">
<h3 class="game-heading">game type </h3>
<article class="game-content">
<header class="event-title">
<div class="scores">
<span class="period">Time</span>
<div class="results">
<span class="score-nr">5122</span>
<span class="score-nr">8213</span>
</div>
<div class="competitors">
<h3 class="competitor-name">jimmy1234</h3>
<h3 class="competitor-name">player98763</h3>
</div>
<i class="fa fa-arrow-right"></i>
<section class="ft-container">
<ul>
<li>222
</li>
<li>543
</li>
</ul>
<ul>
<li>mid
</li>
</ul>
</section>
<div class="venue-content">
<h4>Neutral</h4>
<i class=" fa fa-gamepad"></i>
</div>
</div>
</header>
</article>
</section>
Updated based on a comment saying, can't move the ft-container's markup
Then you needed to use absolute positioning, to position the ft-container at the right, and match its height against the competitors, which in itself need to match the ft-container and arrow to avoid a wrap.
Updated fiddle
Stack snippet
body {
font-size: 12px;
}
.game-heading {
background: #a3a3a3;
}
header {
display: flex;
flex: 1;
}
article {
position: relative;
display: flex;
}
.scores {
display: flex;
flex-wrap: wrap;
flex: 1;
line-height: 1;
}
.period {
background: #c29d31;
padding: 5px 10px;
text-align: center;
}
.results {
display: flex;
flex-direction: column;
}
.score-nr {
background: #9E8231;
flex: 1;
line-height: 10px;
padding: 6px;
}
.competitors {
color: #2d2929;
flex-direction: row;
align-items: flex-start;
width: calc(100% - 200px);
}
.fa {
align-self: center;
padding: 10px;
}
.venue-content {
background: #a3a3a3;
width: 100%;
}
h4 {
display: inline-flex;
}
.competitor-name {
padding: 4px;
}
ul li {
padding: 5px 10px;
}
ul {
border: 1px solid #808080;
}
.ft-container {
position: absolute;
right: 0;
top: 0;
height: 44px;
display: flex;
}
.ft-container ul:last-child {
display: flex;
align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<section class="container-one-row two">
<h3 class="game-heading">game type </h3>
<article class="game-content">
<header class="event-title">
<div class="scores">
<span class="period">Time</span>
<div class="results">
<span class="score-nr">5122</span>
<span class="score-nr">8213</span>
</div>
<div class="competitors">
<h3 class="competitor-name">jimmy1234</h3>
<h3 class="competitor-name">player98763</h3>
</div>
<i class="fa fa-arrow-right"></i>
<div class="venue-content">
<h4>Neutral</h4>
<i class=" fa fa-gamepad"></i>
</div>
</div>
</header>
<section class="ft-container">
<ul>
<li>222
</li>
<li>543
</li>
</ul>
<ul>
<li>mid
</li>
</ul>
</section>
</article>
</section>