Why is the closing X not displayed if the navbar is opened? - javascript

I've tried now quite a time to figure out, why the closing symbol (X) is not displayed if I open my navbar.
If it is closed, everything seems fine.
In the Google Chrome dev tools the icon is still on the page, but in front-end it is not visible.
My environment:
macOS Monterey
VS Code with Live Preview extension
Google Chrome
Is there something I don't see?
Here is my index.html file (I know, the JavaScript should be in an own file ;-P):
section {
background-color: blue;
padding: 20px;
/* height: 40px; */
display: flex;
justify-content: space-between;
align-items: center;
}
img {
height: 30px;
width: auto;
}
.toggle-box a img {
filter: invert(1);
}
.img.menu.hide {
display: none;
}
img.close {
display: none;
}
img.close.show {
display: flex;
/* z-index: 9999; */
}
nav.navigation {
display: none;
}
nav.navigation.active {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: blue;
/* z-index: 1111; */
}
nav.navigation.active a {
padding: 20px;
color: #ffffff;
font-size: 20px;
font-weight: bold;
text-decoration: none;
}
.phone-logo a img {
filter: invert(1);
}
<section>
<div class="toggle-box">
<a onclick="showMenu()" href="#">
<img class="menu" src="menu-outline.svg" />
<img class="close" src="close-outline.svg" />
</a>
</div>
<nav class="navigation">
Sec 1
Sec 2
Sec 3
Sec 4
</nav>
<div class="phone-logo">
<a href="#">
<img src="call-outline.svg" />
</a>
</div>
</section>
<script>
function showMenu() {
document.querySelector(".menu").classList.toggle("hide");
document.querySelector(".close").classList.toggle("show");
document.querySelector(".navigation").classList.toggle("active");
}
</script>
</body>

Elements which fall later in the document have a higher stacking order, meaning that they're layered over earlier elements. You can rearrange your markup to resolve that.
section {
background-color: blue;
padding: 20px;
/* height: 40px; */
display: flex;
justify-content: space-between;
align-items: center;
}
img {
height: 30px;
width: auto;
}
.toggle-box a img {
filter: invert(1);
}
.img.menu.hide {
display: none;
}
img.close {
display: none;
}
img.close.show {
display: flex;
/* z-index: 9999; */
}
nav.navigation {
display: none;
}
nav.navigation.active {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: blue;
/* z-index: 1111; */
}
nav.navigation.active a {
padding: 20px;
color: #ffffff;
font-size: 20px;
font-weight: bold;
text-decoration: none;
}
.phone-logo a img {
filter: invert(1);
}
<section>
<nav class="navigation">
Sec 1
Sec 2
Sec 3
Sec 4
</nav>
<div class="toggle-box">
<a onclick="showMenu()" href="#">
<img class="menu" src="menu-outline.svg" />
<img class="close" src="close-outline.svg" />
</a>
</div>
<div class="phone-logo">
<a href="#">
<img src="call-outline.svg" />
</a>
</div>
</section>
<script>
function showMenu() {
document.querySelector(".menu").classList.toggle("hide");
document.querySelector(".close").classList.toggle("show");
document.querySelector(".navigation").classList.toggle("active");
}
</script>
</body>

It's just a matter of z-index for the .toggle-box.
section {
background-color: blue;
padding: 20px;
/* height: 40px; */
display: flex;
justify-content: space-between;
align-items: center;
}
img {
height: 30px;
width: auto;
}
.toggle-box a img {
filter: invert(1);
}
.img.menu.hide {
display: none;
}
img.close {
display: none;
}
img.close.show {
display: flex;
/* z-index: 9999; */
}
nav.navigation {
display: none;
}
nav.navigation.active {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: blue;
/* z-index: 1111; */
}
nav.navigation.active a {
padding: 20px;
color: #ffffff;
font-size: 20px;
font-weight: bold;
text-decoration: none;
}
.phone-logo a img {
filter: invert(1);
}
.toggle-box {
z-index: 1;
}
<section>
<div class="toggle-box">
<a onclick="showMenu()" href="#">
<img class="menu" src="menu-outline.svg" />
<img class="close" src="close-outline.svg" />
</a>
</div>
<nav class="navigation">
Sec 1
Sec 2
Sec 3
Sec 4
</nav>
<div class="phone-logo">
<a href="#">
<img src="call-outline.svg" />
</a>
</div>
</section>
<script>
function showMenu() {
document.querySelector(".menu").classList.toggle("hide");
// document.querySelector(".close").classList.toggle("show");
document.querySelector(".navigation").classList.toggle("active");
}
</script>
</body>

Related

Why does my page width only stretch to 100% with "fit-content"?

I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:
html, body{
background-color: rgb(167, 72, 72);
height: 100%;
min-width: 100%;
}
I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink
I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.
Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.
Here is the JSX I have for reference:
import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";
const Header = () => {
const texts = [
'ORDERS OF $5K SHIP FREE',
'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
];
let currentTextIndex = 0;
setInterval(() => {
const shippingDealsText = document.querySelector('.shipping-deals-text');
shippingDealsText.classList.add('out');
setTimeout(() => {
shippingDealsText.textContent = texts[currentTextIndex];
shippingDealsText.classList.remove('out');
currentTextIndex = (currentTextIndex + 1) % texts.length;
}, 1000);
}, 5000);
return (
<div className="header">
<div className="header-top">
<div className="top-logo">
<h5 className='small-logo'>LEVIATHAN</h5>
</div>
<div className="space"></div>
<div className="link-container">
<div className="link-wrap">
Gift Cards
</div>
<div className="link-wrap">
Contact Us
</div>
<div className="link-wrap">
Order Status
</div>
<div className="link-wrap">
Live Chat
</div>
</div>
</div>
<div className="header-middle">
<div className="middle-logo">
<h5 className='big-logo'>LEVIATHAN</h5>
</div>
<div className="search-container">
<div className="search-wrapper">
<input
type="text"
id="search-bar"
placeholder="Search"
className='search'
/>
<div className="search-icon-wrapper">
<SearchIcon className='search-icon'/>
</div>
</div>
</div>
<div className="shipping-deals-container">
<div className="button-container">
<div className="shipping-deals-button">
<span className="deals-text">DAILY SHIPPING DEALS </span>
</div>
</div>
<div className="text-container">
<div className="text-slideshow">
<p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
</div>
</div>
</div>
<div className="icons-right">
<Profile className='login-pic'/>
<span>Log In</span>
<Cart className='shopping-cart'/>
</div>
</div>
<div className="header-bottom">
<div className="nav-bar">
<ul className='navigation'>
<li className='menu-items'>
<a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
<a href="/" className='button'>Equipment for Crossfit</a>
<a href="/" className='button'>New Gear</a>
<a href="/" className='button'>Barbells</a>
<a href="/" className='button'>Plates</a>
<a href="/" className='button'>Rigs and Racks</a>
<a href="/" className='button'>Shoes</a>
<a href="/" className='button'>Apparel</a>
<a href="/" className='button'>3 Ships Free</a>
<a href="/" className='button'>Zeus</a>
<a href="/" className='button drop-down'>The Index</a>
</li>
</ul>
</div>
</div>
</div>
)
}
export default Header
Here is the styling I am currently applying:
.header {
min-width: 100%;
margin: 0;
padding: 0;
}
.header-top {
background-color: white;
display: flex;
height: 2.5rem;
width: 100%;
}
.top-logo {
position: relative;
margin-left: 3rem;
}
.space {
flex-grow: 1;
}
.small-logo {
padding-top: 0.5em;
position: relative;
font-size: larger;
color: rgb(133, 133, 133)
}
.link-container {
display: flex;
/*border: 1px solid red;*/
margin-right: 3rem;
}
.link-wrap {
/*border: 1px solid green;*/
font-size: 14px;
padding-left: 1rem;
padding-top: 0.75rem;
}
.link-wrap a {
text-decoration: none;
color:#666666;
cursor: pointer;
}
/* Large section of header, black background */
.header-middle {
background-color: black;
height: 7rem;
display: flex;
}
/* Big LEVIATHAN text */
.middle-logo {
/*border: 1px solid red;*/
position: relative;
margin-left: 3rem;
display: flex;
justify-content: center;
align-items: center;
cursor: co;
}
.big-logo {
font-size: 48px;
/*padding-top: 2rem;*/
position: relative;
color: white;
}
.big-logo:hover {
color: rgb(210, 0, 0);
}
.search-container {
position: relative;
width: 40%;
display: flex;
flex-basis: 60%;
margin-left: 3rem;
align-items: center;
justify-content: center;
}
/*This is what has the appearance of the search bar*/
.search-wrapper {
min-width:100%;
height: 35%;
position: relative;
background-color: white;
display: flex;
flex-basis: 50%;
}
.search-icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
}
.search-icon {
color: black;
font-size: 20px;
}
/*This is the actual search bar tucked inside*/
.search {
width: 100%;
height: 100%;
border: none;
outline: none;
margin-left: 1em;
font-size: 17px;
}
.search::placeholder {
color:rgb(94, 94, 94);
}
/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
width: 18em;
margin-left: 2.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
/*border: 2px solid rgb(136, 77, 255);*/
}
.shipping-deals-button {
width: 65%;
height: 44%;
background-color: rgb(234, 2, 2);
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-top: 1.5em;
}
.button-container {
width: 100%;
height: 50%;
/*border: 2px solid magenta;*/
}
.deals-text {
color: white;
font-size: 12px;
position: relative;
text-align: center;
align-items: stretch;
width: 100%;
}
.text-container {
/*border: 2px solid rgb(20, 182, 11);*/
width: 100%;
height: 50%;
}
.text-slideshow {
color: white;
width: 100%;
height: 50%;
font-size: 12px;
}
.shipping-deals-text {
transition: opacity 1s;
opacity: 1;
font-size: 13px;
}
.out {
opacity: 0;
transition: opacity 1s;
}
.shipping-deals-text-red{
color: red;
}
.navigation {
display: flex;
align-items:flex-start;
height: 3rem;
}
.menu-items {
height: 100%;
margin-left: 1.5rem;
padding-right: 1.5rem;
display: flex;
align-items: flex-start;
flex: 1;
}
ul {
list-style-type: none;
background-color: #333333;
}
.button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
text-decoration: none;
color: white;
text-transform: uppercase;
white-space: nowrap;
padding: 1em;
font-weight: bold;
}
.button:hover {
color:rgb(210, 0, 0)
}
.red {
background-color: rgb(210, 0, 0);
}
.red:hover {
color: white;
}
.drop-icon {
font-size: 25px;
}
.icons-right {
height: 50%;
margin-top: 2em;
min-width: 10%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1rem;
}
.login-pic {
color: white;
font-size: 20px;
}
.shopping-cart {
color: white;
font-size: 20px;
margin-left: 1rem;
}
.icons-right span {
color: white;
margin-left: 0.5em;
}
#media (max-width: 1025px) {
.shipping-deals-container {
display: none;
}
.header-top {
display: none;
}
.header-middle {
height: 50%;
}
.search-wrapper {
border: 2px solid white;
height: 2rem;
}
.icons-right {
margin-bottom: 2rem;
}
}
I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for
With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.
The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;
Hope this helps.
On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.
It should look more like this ->
<ul>
<li>
Shop
</li>
<li>
Equipment for Crossfit
</li>
<li>
New Gear
</li>
<!-- ... -->
</ul>

disable left or right arrow at the last item

Just made a simple div slider with navigation arrows. The div slider works just fine, except, I want some sort of CSS styling to be applied to the arrows.
That is, when a user clicks the left or right arrow, up to the last item, apply CSS styling telling the user they've reached the end of the slider.
let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')
let container = document.getElementById('slider')
buttonLeft.addEventListener('click', function() {
container.scrollLeft -= 90
})
buttonRight.addEventListener('click', function() {
container.scrollLeft += 90
})
body {
background-color: #555;
height: 100vh;
display: grid;
align-items: center;
justify-items: center;
font-family: 'Helvetica';
}
div#slide_wrapper {
width: 440px;
display: flex;
justify-content: space-between;
height: fit-content;
}
div#slider {
width: 350px;
display: flex;
height: fit-content;
flex-wrap: nowrap;
overflow: hidden;
}
div.thumbnail {
min-width: 80px;
min-height: 80px;
cursor: pointer;
display: grid;
place-items: center;
font-size: 30px;
}
div.thumbnail:not(:last-child) {
margin-right: 10px;
}
div.thumbnail:nth-child(1) {
background-color: darkturquoise;
}
div.thumbnail:nth-child(2) {
background-color: goldenrod;
}
div.thumbnail:nth-child(3) {
background-color: rebeccapurple;
}
div.thumbnail:nth-child(4) {
background-color: powderblue;
}
div.thumbnail:nth-child(5) {
background-color: firebrick;
}
div.thumbnail:nth-child(6) {
background-color: sienna;
}
div.thumbnail:nth-child(7) {
background-color: bisque;
}
div.thumbnail:nth-child(8) {
background-color: navy;
}
div#slide_wrapper>button {
height: fit-content;
align-self: center;
font-size: 24px;
font-weight: 800;
border: none;
outline: none;
}
div#slide_wrapper>button:hover {
cursor: pointer;
}
<div id="slide_wrapper">
<button id="slide_left" class="slide_arrow">❮</button>
<div id="slider">
<div class="thumbnail active">1</div>
<div class="thumbnail">2</div>
<div class="thumbnail">3</div>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<div class="thumbnail">6</div>
<div class="thumbnail">7</div>
<div class="thumbnail">8</div>
</div>
<button id="slide_right" class="slide_arrow">❯</button>
</div>
Simply check to see if you need to disable each button based on the position of the scroll. Then if there is a need to disable a button, add the disabled class to the button, otherwise remove it.
Future enhancements.
Remove the hardcoded 360 value for the scroll end. This should be calculated from the size of the carousel items and the width of the viewport.
Allow more than one carousel to work with the same code. This could be achieved by using a javascript class that would hold the elements inside an object, separate from other carousels.
See the demo:
let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')
let container = document.getElementById('slider')
let checkScroll = function() {
if (container.scrollLeft <= 0)
buttonLeft.classList.add("disabled");
else
buttonLeft.classList.remove("disabled");
if (container.scrollLeft >= 360)
buttonRight.classList.add("disabled");
else
buttonRight.classList.remove("disabled");
}
checkScroll();
buttonLeft.addEventListener('click', function() {
container.scrollLeft -= 90;
checkScroll();
})
buttonRight.addEventListener('click', function() {
container.scrollLeft += 90;
checkScroll();
})
body {
background-color: #555;
height: 100vh;
display: grid;
align-items: center;
justify-items: center;
font-family: 'Helvetica';
}
div#slide_wrapper {
width: 440px;
display: flex;
justify-content: space-between;
height: fit-content;
}
div#slider {
width: 350px;
display: flex;
height: fit-content;
flex-wrap: nowrap;
overflow: hidden;
}
div.thumbnail {
min-width: 80px;
min-height: 80px;
cursor: pointer;
display: grid;
place-items: center;
font-size: 30px;
}
div.thumbnail:not(:last-child) {
margin-right: 10px;
}
div.thumbnail:nth-child(1) {
background-color: darkturquoise;
}
div.thumbnail:nth-child(2) {
background-color: goldenrod;
}
div.thumbnail:nth-child(3) {
background-color: rebeccapurple;
}
div.thumbnail:nth-child(4) {
background-color: powderblue;
}
div.thumbnail:nth-child(5) {
background-color: firebrick;
}
div.thumbnail:nth-child(6) {
background-color: sienna;
}
div.thumbnail:nth-child(7) {
background-color: bisque;
}
div.thumbnail:nth-child(8) {
background-color: navy;
}
div#slide_wrapper>button {
height: fit-content;
align-self: center;
font-size: 24px;
font-weight: 800;
border: none;
outline: none;
}
div#slide_wrapper>button:hover {
cursor: pointer;
}
.slide_arrow.disabled {
opacity: 0.2;
cursor: auto !important;
}
<div id="slide_wrapper">
<button id="slide_left" class="slide_arrow">❮</button>
<div id="slider">
<div class="thumbnail active">1</div>
<div class="thumbnail">2</div>
<div class="thumbnail">3</div>
<div class="thumbnail">4</div>
<div class="thumbnail">5</div>
<div class="thumbnail">6</div>
<div class="thumbnail">7</div>
<div class="thumbnail">8</div>
</div>
<button id="slide_right" class="slide_arrow">❯</button>
</div>
a simple solution to this is to actually create a css class that defines the style of arrows when there are no more items and then just add/remove class based on current index of items

How do I loop through refs made from a v-for to then add a class depending if the radio is clicked?

here is what my services page currently looks like:
So when you choose one of the blue radio buttons, it loads the green radio buttons which are sub options, clicking on a green sub option will show the information for that specific product/service.
As you can see when you select a categeory and then a service, it all works correct but I need to add an "active-radio-button" class to the ones that are currently selected.
Similar to a nav bar showing which page is currently active.
I've tried giving each radio button a $ref and then I loop through all the refs to see if they are checked, however it doesnt work, I can't even figure out how to print each ref to the console (although I can see them in the Vue developer console).
Here is the service page:
<template>
<div class="services">
<div class="header services__header">
<h1 :class="$mq">Services</h1>
</div>
<div class="services__services-container">
<div class="select-wrapper">
<div
class="services__services-container__category-selection"
:key="`category-${index}`"
v-for="(item, index) in this.JSON"
>
<!-- GENERATE CATEGORIES -->
<input
v-model="currentCategory"
#change="UncheckRadio"
type="radio"
class="services__services-container__category-selection__category"
:class="$mq"
:value="item"
:ref="item.name"
/>
<label :for="item">{{ item.name }}</label>
</div>
</div>
<!-- GENERATE SERVICES -->
<div class="services__services-container__service-selection" v-if="currentCategory != null">
<div class="select-wrapper">
<div
class="services__services-container__service-selection__service"
:key="`option-${index}`"
:class="$mq"
v-for="(option, index) in currentCategory.options"
>
<input
type="radio"
class="services__services-container__service-selection__service__wrapper"
:class="$mq"
:value="option"
v-model="currentService"
:ref="option.optionName"
/>
<label :for="option">{{ option.optionName }}</label>
</div>
</div>
</div>
<!-- GENERATE DESCRIPTIONS -->
<div class="services__services-container__product-description" v-if="currentService != ''">
<div class="services__services-container__product-description__description" :class="$mq">
<div :class="$mq">
<img :src="currentService.images" alt />
<p>{{ currentService.description }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import services from "#/JSON/services.json";
export default {
name: "Services",
data: function() {
return {
JSON: [],
currentCategory: "",
currentService: ""
};
},
created: function() {
//TO TEST
this.JSON = services.services;
},
methods: {
UncheckRadio: function() {
this.currentService = "";
console.log("kek");
for (const ref in this.refs) {
console.log(ref.key);
}
}
}
};
</script>
<style lang="scss">
#import "#/scss/variables.scss";
#import "#/scss/button.scss";
#import "#/scss/header.scss";
#import "#/scss/input.scss";
.services {
width: 100%;
height: auto;
display: grid;
grid-template-rows: 15vh auto auto auto;
&__services-container {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
padding: 2rem;
&__category-selection {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-blue;
}
}
&__service-selection {
&__service {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-green;
}
}
}
/* For IE10 */
select::-ms-expand {
display: none;
}
&__product-description {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
#include green-gradient;
padding: 2rem;
border-radius: 1.5rem;
&__description {
& img {
margin-bottom: 1rem;
height: 10rem;
width: 10rem;
object-fit: cover;
}
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
}
}
}
}
.select-wrapper {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
//
border-radius: 1.5rem;
position: relative;
width: auto;
height: auto;
margin-bottom: 1rem;
}
.select-icon {
font-size: 1rem;
color: $white;
position: absolute;
right: 0.5rem;
pointer-events: none;
}
.transition {
transition: all 0.25s linear;
}
.active-radio-button {
border-bottom: 0.1rem solid black;
}
</style>

Add and align text to custom Electron Menu bar CSS

So I have the following CSS and HTML for a menu bar:
<header>
<div id="name">Unnamed Masterpiece</div>
<div id="close" onclick="closeWindow()">✕</div>
<div id="min" onclick="minWindow()">―</div>
</header>
header {
display: flex;
justify-content: flex-start;
-webkit-app-region: drag;
background: #292929;
flex-direction: row-reverse;
}
Which, with the close and minimize sign individually styled gives me the following:
However I would like the title to be on the far left and centered.
How would I do this?
Without changing the HTML or CSS you already have, you can add this to you CSS:
#name {
flex: 1;
text-align: center;
order: 1;
}
#close, #min {
order: 0;
}
It will change the order of elements, make the text grow and also center it.
You can try this:
header {
display: flex;
justify-content: flex-start;
-webkit-app-region: drag;
background: #292929;
align-items: center;
}
<header>
<div id="name" style="width: 100%;">Unnamed Masterpiece</div>
<div id="min" onclick="minWindow()" style="">―</div>
<div id="close" onclick="closeWindow()">✕</div>
</header>
Hi You can use like this. I suggest you don't use inline style and by the id style.
<div className="window-header">
<div className="left-side">
Logo - icon
</div>
<div className="draggable-bar" id="titleBar">
Title name or names
</div>
<div className="right-side">
<div id="min-btn" className="btn-box">
<div className="min"></div>
</div>
<div id="max-btn" className="btn-box max">
<div className="maxmize"></div>
</div>
<div id="close-btn" className="btn-box">
<div className="close"></div>
</div>
</div>
</div>
Style codes =>
.window-header {
display: flex;
}
.window-header .left-side, .window-header .draggable-bar, .window-header .right-side {
display: flex;
flex: 1;
}
.window-header .draggable-bar {
-webkit-app-region: drag;
flex-grow: 34;
flex-basis: 0;
align-items: center;
justify-content: center;
color: #c3c3c3;
}
.window-header .draggable-bar:hover {
cursor: move;
}
.window-header .left-side img {
display: flex;
width: 15px;
height: 24px;
margin-top: 3px;
margin-left: 4px;
}
.window-header .left-side .title {
align-items: center;
display: flex;
color: #999;
padding-left: 5px;
user-select: none;
}
.window-header .right-side {
justify-items: flex-end;
justify-content: flex-end;
display: flex;
}
.window-header .right-side .btn-box {
display: inline-flex;
justify-content: center;
width: 30px;
height: 30px;
}
.window-header .right-side .btn-box:hover {
background-color: #797979;
}
.window-header .right-side .btn-box:last-child:hover {
background-color: red;
}
.window-header .right-side .btn-box .min {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNyAyIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZDNkM2QzO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS13aWR0aDoycHg7fTwvc3R5bGU+PC9kZWZzPjxsaW5lIGNsYXNzPSJhIiB4Mj0iMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiLz48L3N2Zz4=);
width: 15px;
height: 15px;
background-repeat: no-repeat;
position: relative;
top: 50%;
}
.window-header .right-side .btn-box.max .maxmize {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAzMCI+PGRlZnM+PHN0eWxlPi5hLC5je2ZpbGw6bm9uZTt9LmF7c3Ryb2tlOiNkM2QzZDM7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDoycHg7fS5ie3N0cm9rZTpub25lO308L3N0eWxlPjwvZGVmcz48ZyBjbGFzcz0iYSI+PHJlY3QgY2xhc3M9ImIiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgcng9IjUiLz48cmVjdCBjbGFzcz0iYyIgeD0iMSIgeT0iMSIgd2lkdGg9IjI4IiBoZWlnaHQ9IjI4IiByeD0iNCIvPjwvZz48L3N2Zz4=);
width: 13px;
height: 13px;
background-repeat: no-repeat;
position: relative;
top: 25%;
}
.window-header .right-side .btn-box.unmax .maxmize {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOSA0MyI+PGRlZnM+PHN0eWxlPi5he2ZpbGw6bm9uZTtzdHJva2UtbGluZWNhcDpyb3VuZDt9LmIsLmN7c3Ryb2tlOm5vbmU7fS5je2ZpbGw6I2QzZDNkMzt9PC9zdHlsZT48L2RlZnM+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMwOCAtMTkyKSI+PGcgY2xhc3M9ImEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxNyAxOTIpIj48cGF0aCBjbGFzcz0iYiIgZD0iTTUsMEgyNWE1LDUsMCwwLDEsNSw1VjI1YTUsNSwwLDAsMS01LDVIMTlWMTguMzMzYTQuMTA2LDQuMTA2LDAsMCwwLS4yLTEuNTU5LDIuMjUzLDIuMjUzLDAsMCwwLS44NTgtLjk3Nyw0LjQzNyw0LjQzNywwLDAsMC0yLjYzNC0uOEgwVjVBNSw1LDAsMCwxLDUsMFoiLz48cGF0aCBjbGFzcz0iYyIgZD0iTSA1IDIgQyAzLjM0NTc5MDg2MzAzNzEwOSAyIDIgMy4zNDU3OTA4NjMwMzcxMDkgMiA1IEwgMiAxMi45OTg2NTkxMzM5MTExMyBMIDE1LjI5NzA5NTI5ODc2NzA5IDEyLjk5ODY1OTEzMzkxMTEzIEMgMTUuMzA4MDE4Njg0Mzg3MjEgMTIuOTk4NTUwNDE1MDM5MDYgMTUuMzIyMjcwMzkzMzcxNTggMTIuOTk4NDYwNzY5NjUzMzIgMTUuMzM5Njk5NzQ1MTc4MjIgMTIuOTk4NDYwNzY5NjUzMzIgQyAxNS45MDQxNzA5ODk5OTAyMyAxMi45OTg0NjA3Njk2NTMzMiAxNy44MDA2MDE5NTkyMjg1MiAxMy4wODcwNzgwOTQ0ODI0MiAxOS4xNDYzMDEyNjk1MzEyNSAxNC4xOTM2OTEyNTM2NjIxMSBDIDE5LjUyMDg4MTY1MjgzMjAzIDE0LjQ1MDA5NjEzMDM3MTA5IDIwLjI0OTQ0ODc3NjI0NTEyIDE1LjA0NDU4OTk5NjMzNzg5IDIwLjY0OTU1OTAyMDk5NjA5IDE2LjAwNjAzMTAzNjM3Njk1IEMgMjEuMDM0MzEzMjAxOTA0MyAxNi45MzA1NjI5NzMwMjI0NiAyMS4wMjI2MjQ5Njk0ODI0MiAxNy45ODcwMTY2Nzc4NTY0NSAyMSAxOC4zOTU1MzgzMzAwNzgxMyBMIDIxIDI4IEwgMjUgMjggQyAyNi42NTQyMDkxMzY5NjI4OSAyOCAyOCAyNi42NTQyMDkxMzY5NjI4OSAyOCAyNSBMIDI4IDUgQyAyOCAzLjM0NTc5MDg2MzAzNzEwOSAyNi42NTQyMDkxMzY5NjI4OSAyIDI1IDIgTCA1IDIgTSA1IDAgTCAyNSAwIEMgMjcuNzYxNDE5Mjk2MjY0NjUgMCAzMCAyLjIzODU4MDcwMzczNTM1MiAzMCA1IEwgMzAgMjUgQyAzMCAyNy43NjE0MTkyOTYyNjQ2NSAyNy43NjE0MTkyOTYyNjQ2NSAzMCAyNSAzMCBMIDE5IDMwIEwgMTkgMTguMzMzMzMwMTU0NDE4OTUgQyAxOSAxOC4zMzMzMzAxNTQ0MTg5NSAxOS4wNjY4Njk3MzU3MTc3NyAxNy40MDgzNDk5OTA4NDQ3MyAxOC44MDMwNzAwNjgzNTkzOCAxNi43NzQ0NTk4Mzg4NjcxOSBDIDE4LjUzOTI3MDQwMTAwMDk4IDE2LjE0MDU2OTY4Njg4OTY1IDE3Ljk0NDc4OTg4NjQ3NDYxIDE1Ljc5Nzc2MDAwOTc2NTYzIDE3Ljk0NDc4OTg4NjQ3NDYxIDE1Ljc5Nzc2MDAwOTc2NTYzIEMgMTcuMDkzMTE4NjY3NjAyNTQgMTUuMDI3OTQ4Mzc5NTE2NiAxNS41NjgyOTY0MzI0OTUxMiAxNC45OTg0NTY5NTQ5NTYwNSAxNS4zMzk2OTQ5NzY4MDY2NCAxNC45OTg0NTY5NTQ5NTYwNSBDIDE1LjMyMDczMjExNjY5OTIyIDE0Ljk5ODQ1Njk1NDk1NjA1IDE1LjMxMDcwMDQxNjU2NDk0IDE0Ljk5ODY2MDA4NzU4NTQ1IDE1LjMxMDcwMDQxNjU2NDk0IDE0Ljk5ODY2MDA4NzU4NTQ1IEwgMCAxNC45OTg2NjAwODc1ODU0NSBDIDAgMTQuOTk4NjYwMDg3NTg1NDUgMCAxMS40Njc5NTA4MjA5MjI4NSAwIDUgQyAwIDIuMjM4NTgwNzAzNzM1MzUyIDIuMjM4NTgwNzAzNzM1MzUyIDAgNSAwIFoiLz48L2c+PGcgY2xhc3M9ImEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwOCAyMDUpIj48cGF0aCBjbGFzcz0iYiIgZD0iTTUsMEgyNWE1LDUsMCwwLDEsNSw1VjI1YTUsNSwwLDAsMS01LDVINWE1LDUsMCwwLDEtNS01VjVBNSw1LDAsMCwxLDUsMFoiLz48cGF0aCBjbGFzcz0iYyIgZD0iTSA1IDIgQyAzLjM0NTc5MDg2MzAzNzEwOSAyIDIgMy4zNDU3OTA4NjMwMzcxMDkgMiA1IEwgMiAyNSBDIDIgMjYuNjU0MjA5MTM2OTYyODkgMy4zNDU3OTA4NjMwMzcxMDkgMjggNSAyOCBMIDI1IDI4IEMgMjYuNjU0MjA5MTM2OTYyODkgMjggMjggMjYuNjU0MjA5MTM2OTYyODkgMjggMjUgTCAyOCA1IEMgMjggMy4zNDU3OTA4NjMwMzcxMDkgMjYuNjU0MjA5MTM2OTYyODkgMiAyNSAyIEwgNSAyIE0gNSAwIEwgMjUgMCBDIDI3Ljc2MTQxOTI5NjI2NDY1IDAgMzAgMi4yMzg1ODA3MDM3MzUzNTIgMzAgNSBMIDMwIDI1IEMgMzAgMjcuNzYxNDE5Mjk2MjY0NjUgMjcuNzYxNDE5Mjk2MjY0NjUgMzAgMjUgMzAgTCA1IDMwIEMgMi4yMzg1ODA3MDM3MzUzNTIgMzAgMCAyNy43NjE0MTkyOTYyNjQ2NSAwIDI1IEwgMCA1IEMgMCAyLjIzODU4MDcwMzczNTM1MiAyLjIzODU4MDcwMzczNTM1MiAwIDUgMCBaIi8+PC9nPjwvZz48L3N2Zz4=);
width: 15px;
height: 15px;
background-repeat: no-repeat;
position: relative;
top: 25%;
}
.window-header .right-side .btn-box .close {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMy40MTQgMTMuNDE0Ij48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZDNkM2QzO3N0cm9rZS1saW5lY2FwOnJvdW5kO308L3N0eWxlPjwvZGVmcz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjQyLjc5MyAtMTgyLjc5MykiPjxsaW5lIGNsYXNzPSJhIiB4Mj0iMTIiIHkyPSIxMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQzLjUgMTgzLjUpIi8+PGxpbmUgY2xhc3M9ImEiIHgxPSIxMiIgeTI9IjEyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDMuNSAxODMuNSkiLz48L2c+PC9zdmc+);
width: 12px;
height: 12px;
background-repeat: no-repeat;
position: relative;
position: relative;
top: 30%;
}
This is JS code
function init() {
const window = remote.getCurrentWindow();
document.getElementById("min-btn").addEventListener("click", function (e) {
window.minimize();
});
document.getElementById("max-btn").addEventListener("click", function (e) {
if (!window.isMaximized()) {
this.classList.remove('max')
this.classList.add('unmax')
window.maximize();
} else {
this.classList.remove('unmax')
this.classList.add('max')
window.unmaximize();
}
});
document.getElementById("close-btn").addEventListener("click", function (e) {
window.close();
});
//Listened to the application window sizes and if sizes changed, size icon is changed.
if (remote.getCurrentWindow().isMaximized()) {
document.getElementById("max-btn").classList.remove('max')
document.getElementById("max-btn").classList.add('unmax')
} else {
document.getElementById("max-btn").classList.remove('unmax')
document.getElementById("max-btn").classList.add('max')
}
remote.getCurrentWindow().on('resize', _.debounce(function () {
if (remote.getCurrentWindow().isMaximized()) {
document.getElementById("max-btn").classList.remove('max')
document.getElementById("max-btn").classList.add('unmax')
} else {
document.getElementById("max-btn").classList.remove('unmax')
document.getElementById("max-btn").classList.add('max')
}
}, 100))
};
document.onreadystatechange = function () {
if (document.readyState == "complete") {
init();
}
};

align items on stretch to the center of the parent div

I tried to create a menu that stretches to full height on mobile screens. For the parent container I use a flexbox with flex-direction column and stretch the items on full screen height.
$(document).ready(() => {
$("#btnMenu").click(() => {
toggleMenu();
});
$(".navbarLink").click(() => {
if ($("#navbarItems").hasClass("activeNavbar")) {
toggleMenu();
}
});
});
function toggleMenu() {
$("#navbarItems").toggleClass("activeNavbar");
toggleMenuBtn();
}
function toggleMenuBtn() {
$("#btnMenu").toggleClass("activeMenuBtn");
}
body {
margin: 0;
}
.link {
text-decoration: none;
}
#navbar {
height: 60px;
top: 0;
padding-left: 200px;
padding-right: 200px;
position: sticky;
background: #1e222a;
}
#navbarItems {
height: 100%;
display: flex;
align-items: center;
}
#logoLink {
display: flex;
align-items: center;
}
#navbarItems .navbarItem:not(:first-child) {
margin-left: 30px;
}
.navbarItem {
background: #1e222a;
}
.navbarLink {
color: #ffffff;
}
.navbarLink:hover {
color: #3abcf3;
}
#btnMenuContainer {
height: 100%;
display: none;
}
#btnMenu {
cursor: pointer;
}
.menuBtnBar {
width: 35px;
height: 5px;
margin: 6px 0;
background-color: #ffffff;
transition: 0.4s;
}
.activeMenuBtn #barTop {
transform: rotate(-45deg) translate(-9px, 6px);
}
.activeMenuBtn #barCenter {
opacity: 0;
}
.activeMenuBtn #barBottom {
transform: rotate(45deg) translate(-8px, -8px);
}
#media(max-width: 1200px) {
#navbar {
padding-left: 150px;
padding-right: 150px;
}
}
#media(max-width: 1100px) {
#navbar {
padding-left: 0;
padding-right: 0;
}
#btnMenuContainer {
display: flex;
align-items: center;
}
#btnMenu {
margin-left: 20px;
}
#navbarItems {
margin-left: 0;
display: none;
}
#navbarItems.activeNavbar {
display: flex;
flex-direction: column;
align-items: stretch;
height: 100vh;
}
#logoLink {
display: inline-block;
}
.navbarItem {
flex: 1 1 100%;
align-items: center;
justify-content: center;
text-align: center;
}
#navbarItems .navbarItem:not(:first-child) {
margin-left: 0;
}
#navbarItems .navbarItem:not(:last-child) {
border-bottom: 1px solid #676767;
}
.navbarLink {
width: 100%;
height: 100%;
display: inline-block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navbar">
<div id="btnMenuContainer">
<div id="btnMenu">
<div id="barTop" class="menuBtnBar"></div>
<div id="barCenter" class="menuBtnBar"></div>
<div id="barBottom" class="menuBtnBar"></div>
</div>
</div>
<div id="navbarItems">
<div class="navbarItem">
<a id="logoLink" class="link navbarLink" href="#">
<img class="img" src="https://cdn4.iconfinder.com/data/icons/32x32-free-design-icons/32/Ok.png">
</a>
</div>
<div class="navbarItem">
<a class="link navbarLink" href="#">
Link 2
</a>
</div>
<div class="navbarItem">
<a class="link navbarLink" href="#">
Link 3
</a>
</div>
</div>
</div>
When using align-items: stretch; how can I place the links (and the logo) back to center?
My second question is what can I use for height: 100vh; instead? I would like to keep it dynamic so maybe there is a better way than using a constant number?
It works fine. Check the code snippets and fiddle for further clarification.
Noe all links are center aligned and menu height takes the full height of the space available and there is no scroll any more.
My suggestion is to use 100vh for the height because it better than applying static value since 100vh is dynamic value.
https://jsfiddle.net/Sampath_Madhuranga/4uLb6rsw/7/
$(document).ready(() => {
$("#btnMenu").click(() => {
toggleMenu();
});
$(".navbarLink").click(() => {
if ($("#navbarItems").hasClass("activeNavbar")) {
toggleMenu();
}
});
});
function toggleMenu() {
$("#navbarItems").toggleClass("activeNavbar");
toggleMenuBtn();
}
function toggleMenuBtn() {
$("#btnMenu").toggleClass("activeMenuBtn");
}
body {
margin: 0;
}
.link {
text-decoration: none;
}
#navbar {
height: 60px;
top: 0;
padding-left: 200px;
padding-right: 200px;
position: sticky;
background: #1e222a;
}
#navbarItems {
height: 100%;
display: flex;
align-items: center;
}
#logoLink {
display: flex;
align-items: center;
}
#navbarItems .navbarItem:not(:first-child) {
margin-left: 30px;
}
.navbarItem {
background: #1e222a;
}
.navbarLink {
color: #ffffff;
}
.navbarLink:hover {
color: #3abcf3;
}
#btnMenuContainer {
height: 100%;
display: none;
}
#btnMenu {
cursor: pointer;
}
.menuBtnBar {
width: 35px;
height: 5px;
margin: 6px 0;
background-color: #ffffff;
transition: 0.4s;
}
.activeMenuBtn #barTop {
transform: rotate(-45deg) translate(-9px, 6px);
}
.activeMenuBtn #barCenter {
opacity: 0;
}
.activeMenuBtn #barBottom {
transform: rotate(45deg) translate(-8px, -8px);
}
#media(max-width: 1200px) {
#navbar {
padding-left: 150px;
padding-right: 150px;
}
}
#media(max-width: 1100px) {
#navbar {
padding-left: 0;
padding-right: 0;
}
#btnMenuContainer {
display: flex;
align-items: center;
}
#btnMenu {
margin-left: 20px;
}
#navbarItems {
margin-left: 0;
display: none;
}
#navbarItems.activeNavbar {
display: flex;
flex-direction: column;
align-items: stretch;
height: calc( 100vh - 60px);
}
#logoLink {
display: flex;
justify-content: center;
}
.navbarItem {
flex: 1 1 100%;
align-items: center;
justify-content: center;
text-align: center;
}
#navbarItems .navbarItem:not(:first-child) {
margin-left: 0;
}
#navbarItems .navbarItem:not(:last-child) {
border-bottom: 1px solid #676767;
}
.navbarLink {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navbar">
<div id="btnMenuContainer">
<div id="btnMenu">
<div id="barTop" class="menuBtnBar"></div>
<div id="barCenter" class="menuBtnBar"></div>
<div id="barBottom" class="menuBtnBar"></div>
</div>
</div>
<div id="navbarItems">
<div class="navbarItem">
<a id="logoLink" class="link navbarLink" href="#">
<img class="img" src="https://cdn4.iconfinder.com/data/icons/32x32-free-design-icons/32/Ok.png">
</a>
</div>
<div class="navbarItem">
<a class="link navbarLink" href="#">
Link 2
</a>
</div>
<div class="navbarItem">
<a class="link navbarLink" href="#">
Link 3
</a>
</div>
</div>
</div>
Thanks.
Let .navbarLink also have a flex layout.
.navbarItem {
flex: 1 1 100%;
}
.navbarLink {
height: 100%;
width: 100%;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
text-align: center;
}
By the way, here is a great resource that really helped me when I learned to use flexbox layouts. https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Follow this link https://flexboxfroggy.com/ there is a really nice game which will teach you flexbox while playing in no time. After that you will be able to fix your navigation.

Categories

Resources