How can I show second header when scroll down 60px? - javascript

.nav-header2{
background: purple;
display: flex;
justify-content: center;
align-items: center;
}
.header2-container{
width: 68vw;
height: 60px;
padding: 0 2vh;
border: 1px solid red;
border-radius: 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-header1{
background: lightblue;
display: flex;
justify-content: center;
align-items: center;
}
.header1-container{
width: 68vw;
height: 60px;
padding: 0 2vh;
border: 1px solid blue;
border-radius: 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
<!--header2 -->
<nav class="nav-header2">
<div class="header2-container">
<h1>header2<h2>
</div>
</nav>
<!-- header1 -->
<nav class="nav-header1">
<div class="header1-container">
<h1>header1<h2>
</div>
</nav>
I have two headers for my web page. I named header1 and header2.
I want to show header2 when scrolling down bigger than 60px and hide when scrolling is smaller than 60px.
if (scroll down bigger than 60px){
show header2
}else{
still show header1
}
I have tried many time, But I can't succeed.
Please help
Thank you so much!

Please check the code below when you scroll 60px and more the header 1 disappear and header 2 appear
window.addEventListener("scroll", () => {
if (scrollY >= 60) {
document.querySelector(".headerOne").style.display = "none";
document.querySelector(".headerTwo").style.display = "block";
} else {
document.querySelector(".headerTwo").style.display = "none";
document.querySelector(".headerOne").style.display = "block";
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: 60px;
background-color: gray;
}
.headerOne,
.headerTwo {
position: fixed;
top: 0;
left: 0;
background-color: white;
width: 100%;
font-size: 20px;
text-align: center;
height: 60px;
}
.headerTwo {
display: none;
}
<div class="headerOne">header 1</div>
<div class="headerTwo">header 2</div>
<section>section</section>
<section>section</section>

Related

How can I horizontally center these 3 buttons

At first there were 4 buttons I only wanted 3 so I removed the 4th one and that's why I want to make the remaining 3 look horizontally centered, it looks weird because of the 4th button's blank space. I tried a few things but they didn't work out.
var tabButtons = document.querySelectorAll(".tabContainer .buttonContainer button");
var tabPanels = document.querySelectorAll(".tabContainer .tabPanel");
function showPanel(panelIndex, colorCode) {
tabButtons.forEach(function(node) {
node.style.backgroundColor = "";
node.style.color = "";
});
tabButtons[panelIndex].style.backgroundColor = colorCode;
tabButtons[panelIndex].style.color = "white";
tabPanels.forEach(function(node) {
node.style.display = "none";
});
tabPanels[panelIndex].style.display = "block";
tabPanels[panelIndex].style.backgroundColor = colorCode;
}
showPanel(0, '#f44336');
.title {
color: #dc2d5e;
text-align: center;
}
.tabContainer {
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer {
height: 15%;
align-items: center;
align-content: center;
justify-content: center;
text-align: center;
}
.tabContainer .buttonContainer button {
width: 25%;
height: 100%;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover {
background-color: #d7d4d4;
}
.tabContainer .tabPanel {
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
You are really close, adding these two flex properties can obtain the desired solution:
.tabContainer .buttonContainer{
display: flex;
justify-content: space-between;
}
.title{
color: #dc2d5e;
text-align: center;
}
.tabContainer{
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer{
display: flex;
height: 15%;
align-items: center;
align-content: center;
justify-content: space-between;
text-align: center;
}
.tabContainer .buttonContainer button{
width: 25%;
height: 100%;
float: left;
border: none;
outline:none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover{
background-color: #d7d4d4;
}
.tabContainer .tabPanel{
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
This flexbox guide is my go-to any time I run into this type of issue!
You just need to add this to your css !
.buttonContainer{
display: flex;
}
Since there are only 3 buttons now, I would just make each one's width a third.
You can accomplish this by doing:
.tabContainer .buttonContainer button{
width: calc(100% / 3);
}
EDIT: So it would look like this:
var tabButtons = document.querySelectorAll(".tabContainer .buttonContainer button");
var tabPanels = document.querySelectorAll(".tabContainer .tabPanel");
function showPanel(panelIndex, colorCode) {
tabButtons.forEach(function(node) {
node.style.backgroundColor = "";
node.style.color = "";
});
tabButtons[panelIndex].style.backgroundColor = colorCode;
tabButtons[panelIndex].style.color = "white";
tabPanels.forEach(function(node) {
node.style.display = "none";
});
tabPanels[panelIndex].style.display = "block";
tabPanels[panelIndex].style.backgroundColor = colorCode;
}
showPanel(0, '#f44336');
.title {
color: #dc2d5e;
text-align: center;
}
.tabContainer {
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer {
height: 15%;
align-items: center;
align-content: center;
justify-content: center;
text-align: center;
}
.tabContainer .buttonContainer button {
width: calc(100% / 3);
height: 100%;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover {
background-color: #d7d4d4;
}
.tabContainer .tabPanel {
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
calc() is widely supported on modern browsers.

Warning: Failed prop type: Invalid prop `open` of type `function` supplied to `ForwardRef(Dialog)`, expected `boolean`. at Dialog

The idea is to show a District Overview in a dialog box and then display a table once the dialog box is closed. However, I cannot seem to get rid of the box when I click on close. The Dialog Box comes up when the By District Option is clicked(marked in Yellow) which then brings up a dropdown(marked in Red). Once a value in the dropdown is selected the Dialog Box comes up. Although the dialog box shows up, I cannot seem to close it somehow. The console gives the error I gave in the title. The screenshots and the code are below:
Here's the code:
import React, { useState } from "react";
import './advance_filter.css';
import DistrictFilter from "../../widgets/filter_dropdowns/district_filter/district_filter";
import Dialog from "#material-ui/core/Dialog";
import { DialogActions, DialogContent, DialogTitle } from "#material-ui/core";
const AdvanceFilterScreen = () => {
const [byDistrictFilter, setByDistrictFilter] = useState(false); //This is the hook that selects the By District option
const [district, setDistrict] = useState(''); //This selects the value from the Dropdown
const [districtDialogOpen, setDistrictDialogOpen] = useState(false); //This was meant for opening and closing the dialog box
const districtFilter = () => {
setByDistrictFilter(prev => !prev);
setFilterButtonValue('');
setDistrict('')
}
const openDialog = () => {
setDistrictDialogOpen(prev => !prev)
}
const closeDialog = () => {
setDistrictDialogOpen(prev => !prev);
}
return (
<div className="advanceFilterScreen">
<div className="navBarFilter">
<NavBar></NavBar>
</div>
<div className="chooseFilters">
<div className="chooseColumn">
<div className="caption">Choose Filters (Upto 5 filters at a time)</div>
<div className="filterOptions">
<div onClick={districtFilter}>
<div className={byDistrictFilter ? "districtSelectedFilter" : "byDistrictFilter"}>By District</div>
</div>
</div>
</div>
</div>
<div className={byDistrictFilter ? "filterDropdowns" : "noFilter"}>
<div className="filterClass">
{byDistrictFilter ? <div style={{ marginRight: "15px" }}>
{/* This shows the District Dropdown */}
<DistrictFilter setDistrict={setDistrict}></DistrictFilter>
</div> : null}
</div>
<div>
{district ? <Dialog open={openDialog} onClose={closeDialog}>
<DialogTitle className="districtOverview">{"District Overview"}</DialogTitle>
<DialogContent>
<div className="overAll">
{/* This component shows the overview on the Dialog Box */}
<DistrictTable district={district} setFilterButtonValue={setFilterButtonValue} ></DistrictTable>
</div>
</DialogContent>
<DialogActions>
<div className="closeButton" onClick={closeDialog}>Close</div>
</DialogActions>
</Dialog>
: <FilterSearchButton district={district}></FilterSearchButton>}
</div>
</div>
<div style={{ marginTop: "50px" }}>
<Table buttonValue={buttonValue}></Table>
</div>
</div>
);
};
export default AdvanceFilterScreen;
In case someone needs the CSS file for testing:
.advanceFilterScreen {
display: flex;
flex-direction: column;
}
.navBarFilter {
background-color: rgb(52, 171, 245);
}
.chooseFilters {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80px;
background-color: rgb(52, 171, 245);
}
.chooseColumn {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
width: 75%;
height: 100%;
}
.caption {
font-weight: bold;
margin-top: 10px;
padding-left: 10px;
color: white;
font-weight: bold;
}
.filterOptions {
display: flex;
width: 100%;
height: 100%;
padding: 0 5px;
}
.byNameFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.nameSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byDateFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.dateSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byCategoryFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.categorySelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byDistrictFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.districtSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byStatesFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.stateSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.bySerialNumberFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.serialNumberSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byIssueFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.issueSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.filterDropdowns {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 200px;
background-color: rgb(52, 171, 245);
/* margin-top: 10px; */
}
.noFilter {
display: none;
}
.filterClass {
display: flex;
justify-content: space-evenly;
align-items: center;
/* flex-direction: row; */
/* width: 100%;
height: 50px; */
/* background-color: yellow; */
}
.districtOverview {
display: flex;
justify-content: center;
align-items: center;
}
.overAll {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding-left: 15px;
padding-top: 5px;
/* background-color: red; */
}
.closeButton {
display: flex;
justify-content: flex-end;
padding-right: 30px;
align-items: center;
width: 200px;
height: 50px;
color: rgb(52, 171, 245);
/* font-weight: bold; */
cursor: pointer;
font-size: 20px;
}
/* .searchFilterButton {
display: flex;
justify-content: center;
align-items: center;
width: 150px;
height: 30px;
margin-top: 50px;
background-color: rgb(52, 171, 245);
box-shadow: 1px 2px 4px 1px gray;
border-radius: 5px;
cursor: pointer;
background-color: green;
color: white;
font-weight: bold;
} */
The open prop passed to dialog isn't meant to be a function. It should be a boolean. The trigger of the District Overview dialog should be the state of district, when district has a truthy value. So it's either you render using a tenary operator district ? /* dialog */ : /* filter button */ and have
the oepn prop set to true on initial render or you render the dialog immediately with the other nodes and set its open prop to open={Boolean(district)}
const districtFilter = () => {
setByDistrictFilter(prev => !prev);
setFilterButtonValue('');
}
const closeDialog = () => {
setDistrict('')
}
<div>
{district ? (
<Dialog open onClose={closeDialog}>
{/* ... */}
</Dialog>
) : (
<FilterSearchButton district={district}></FilterSearchButton>
)}
</div>
or
<div>
<Dialog open={Boolean(district)} onClose={closeDialog}>
{/* ... */}
</Dialog>
{district && <FilterSearchButton district={district}></FilterSearchButton>}
</div>

How to expand textarea upwards and its parent divs along with it

I'm creating a chat application(React). I'm having this textbox which I need to expand vertically upwards as user types. I tried doing it with position absolute but it takes it out of the normal flow. And this does not allow the parent div to move upwards. Is there a way that this can be done? If anyone could point me in the right direction that would be great. Thanks.
Here is the codepen link.
https://codepen.io/ghewadesumit/pen/zYzRjyY
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>
css
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
height: 52px;
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
We can use a Javascript ResizeObserver to tell us when the height of the input text has changed. Then we can scroll the window in such a way that the bottom of the input stays in the same position on the viewport - so the elements seem to grow upwards.
Note this snippet uses contenteditable on a div rather than a textarea as the growing/shrinking and text wrapping then happen automatically.
<style>
body {
height: 300vh;
}
.parent {
margin-top: 20vh; /* so we can see it growing not just disappearing */
background: pink;
}
.child {
background: #eeeeee;
}
</style>
<body>
<div class="parent">
Some stuff in the parent<br> here
<div class="child" contenteditable></div>
</div>
<script>
let prevH = 0;
const textArea = document.querySelector('.child');
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
let h = entry.contentRect.height;
let diff = h - prevH;
if (diff != 0) {
prevH = h;
window.scroll(0, prevH);
}
}
});
resizeObserver.observe(textArea);
</script>
</body>
Don't hard code the height of class .inputbox-wrapper instead remove height property from there or put height: auto(which is default value) so that container expand when the the text-area is expanded
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
height: auto;/*Change here*/
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>
The .inputbox-wrapper should have a min-height not a height if you set only a height, the container will not resize with the textbox.
On another note, if you want the textarea to expand vertically only, you can add resize: vertical; to .chat-input-box {
Textboxes can't expand their height automatically like this by default - you'll need to use a bit of Javascript.
One approach is to dynamically calculate the height of the textfield based on the number of line breaks inside it.
This example from CSS-Tricks has more details on the approach. I've implemented it on your code below.
You also need to change height to min-height on your inputbox-wrapper to allow it to expand as the textfield changes height.
let textarea = document.querySelector(".chat-input-box");
textarea.addEventListener("keyup", () => {
textarea.style.height = calcHeight(textarea.value) + "px";
});
function calcHeight(value) {
let numberOfLineBreaks = (value.match(/\n/g) || []).length;
// min-height + lines x line-height + padding + border
let newHeight = 20 + numberOfLineBreaks * 20 + 0 + 0;
// padding and border are both 0 here but have left in for reference
return newHeight;
}
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
min-height: 52px;
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>

How to prevent an accordion from closing on content selection?

I have a problem with JS, how can I prevent accordion from closing if I click on the content
You can find my code below; the code works fine; the only problem is when I select anything from the content "dropdown," the accordion close. I need that the accordion keeps open if I click on that.
I hope this makes sense.
I really appreciate any help
const accordion = document.getElementsByClassName ('media-box-actuaries_accordion');
for (i = 0; i<accordion.length; i++ ){
accordion[i].addEventListener('click', function(){
this.classList.toggle('active');
})
}
.media-box-actuaries_accordion {
position: relative;
margin-bottom: 20px;
text-decoration: none;
}
.media-box-actuaries_accordion {
position: relative;
margin-bottom: 20px;
}
.media-box-actuaries_accordion_content {
position: relative;
overflow: hidden;
display: none;
overflow-y: auto;
transition: all 0.5s ease-out;
}
.media-box-actuaries_accordion.active .media-box-actuaries_accordion_content {
height: 100%;
display: block;
transition: all 0.5s ease-out;
}
.media-box-actuaries .media-box-header {
min-height: 69px;
width: 100%;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: row;
flex-direction: row;
background-color: #f5f6f6;
border: 1px solid #e2e2e2 !important;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
}
/* accordion */
.media-box-actuaries .media-box-header-accordion {
min-height: 69px;
width: 100%;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: row;
flex-direction: row;
background-color: #f5f6f6;
border: 1px solid #e2e2e2 !important;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.media-box-actuaries .media-box-header.only {
padding: 0rem 2rem;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
justify-content: center;
align-items: baseline;
color: #00a3da;
border-radius: 3px;
border: 1px solid #e2e2e2;
}
.media-box-actuaries .media-box-header-accordion::before {
content: " \2304";
position: absolute;
right: 20px;
transform: translateY(50%);
font-size: 1.5em;
color: #00a3da;
}
.media-box-actuaries .media-box-actuaries_accordion.active .media-box-header-accordion::before {
content: "\2303";
transform: translateY(100%);
font-size: 1.5em;
}
.media-box-actuaries .media-box-header-accordion.only {
padding: 0rem 2rem;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
justify-content: center;
align-items: baseline;
color: #00a3da;
border-radius: 3px;
border: 1px solid #e2e2e2;
}
.media-box-actuaries .media-box-header-accordion__icon {
min-width: 75px;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 3px 0px 0px 3px;
border: 1px solid #e2e2e2;
border-right: none;
}
<div class="media-box-actuaries">
<div class="media-box-actuaries_accordion">
<div class="media-box-header-accordion">
<p>Add header content</p>
</div>
<div class="media-box-actuaries_accordion_content">
<p> Add content </p>
</div>
</div>
</div>
Do you mean like that? Reproduce repo
const accordion = document.getElementsByClassName ('media-box-header-accordion');
for (i = 0; i<accordion.length; i++ ){
accordion[i].addEventListener('click', function(){
this.parentNode.classList.toggle('active');
})
}
Your problem is caused by what's called event bubbling.
One solution would be to attach the event listener that toggles the active class to the accordion's header element (the element with the class .media-box-header-accordion), something like this:
const accordions = document.getElementsByClassName("media-box-actuaries_accordion");
for (i = 0; i < accordions.length; i++) {
const accordion = accordions[i];
const header = accordion.querySelector(".media-box-header-accordion");
header.addEventListener("click", function () {
accordion.classList.toggle("active");
});
}

Can I do a wipe transition using CSS?

I have the following snippet of example code (I am using React but do not feel like spending time sanitising the actual project code before posting that here):
let menuOpened = false;
document.getElementById('menu-button')
.addEventListener('click', function() {
menuOpened = !menuOpened;
document.getElementById('body').classList.toggle('menu-opened', menuOpened);
document.getElementById('menu').classList.toggle('menu-opened', menuOpened);
});
* {
box-sizing: border-box;
}
body {
margin: 0;
}
body.menu-opened {
overflow-y: hidden;
}
body > * {
width: 100vw;
}
header {
background-color: #6FC5C2;
display: flex;
height: 20vh;
position: sticky;
top: 0;
align-items: center;
justify-content: center;
}
nav {
background-color: #80CAF1;
display: flex;
height: 80vh;
left: 0;
opacity: 0;
padding: 1rem;
position: fixed;
top: 20vh;
transition: all 0.35s ease;
visibility: hidden;
z-index: 20;
align-items: center;
flex-direction: column;
justify-content: center;
}
nav.menu-opened {
opacity: 1;
visibility: visible;
}
a {
color: black;
font-weight: bold;
text-decoration: none;
}
a:not(:last-child) {
margin-bottom: 0.5rem;
}
main {
display: flex;
}
aside {
background-color: #9C9ECF;
display: flex;
flex-basis: 25%;
padding: 3rem 0.5rem;
text-align: center;
justify-content: center;
}
section {
background-color: #F8CFD7;
display: flex;
flex-basis: 75%;
padding: 2rem;
align-items: stretch;
flex-direction: column;
}
article {
border: ridge #80CAF1;
border-width: 3px 3px 0 3px;
display: flex;
font-size: 0.75rem;
min-height: 15vh;
padding: 1rem;
align-items: center;
}
article:last-child {
border-width: 3px;
}
footer {
background-color: #016CBA;
height: 30vh;
}
<body id="body">
<header>
<button id="menu-button" type="button">Menu</button>
</header>
<nav id="menu">
Link 1
Link 2
</nav>
<main id="main">
<aside>Filter Form</aside>
<section>
<article>Article A</article>
<article>Article B</article>
<article>Article C</article>
<article>Article D</article>
<article>Article E</article>
<article>Article F</article>
<article>Article G</article>
<article>Article H</article>
<article>Article I</article>
</section>
</main>
<footer id="footer"></footer>
</body>
Currently, when I click the button to open the navigation menu, the page will disable scrolling and the menu will fade in. When I click the button again, scrolling will be re-enabled and the menu will fade out.
What I actually want is a wipe transition instead of fading, like so:
Using the above image as an analogy, the main page content would be A, and the menu would be B. However, instead of horizontal I want the wipe to be vertical i.e. when I open the menu, the wipe will go from top to bottom, and when I close the menu, the wipe will go from bottom to top. The menu text should not be moving. I want to use the same transition duration and timing function as currently configured.
Is this possible without using JavaScript/React?
Another idea using clip-path
let menuOpened = false;
document.getElementById('menu-button')
.addEventListener('click', function() {
menuOpened = !menuOpened;
document.getElementById('body').classList.toggle('menu-opened', menuOpened);
document.getElementById('menu').classList.toggle('menu-opened', menuOpened);
});
* {
box-sizing: border-box;
}
body {
margin: 0;
}
body.menu-opened {
overflow-y: hidden;
}
body > * {
width: 100vw;
}
header {
background-color: #6FC5C2;
display: flex;
height: 20vh;
position: sticky;
top: 0;
align-items: center;
justify-content: center;
}
nav {
background-color: #80CAF1;
display: flex;
height: 80vh;
left: 0;
padding: 1rem;
position: fixed;
top: 20vh;
transition: all 0.8s ease;
z-index: 20;
align-items: center;
flex-direction: column;
justify-content: center;
clip-path:polygon(0 0,0% 0,-200px 100%,0 100%);
}
nav.menu-opened {
clip-path:polygon(0 0,calc(100% + 200px) 0,100% 100%,0 100%);
}
a {
color: black;
font-weight: bold;
text-decoration: none;
}
a:not(:last-child) {
margin-bottom: 0.5rem;
}
main {
display: flex;
}
aside {
background-color: #9C9ECF;
display: flex;
flex-basis: 25%;
padding: 3rem 0.5rem;
text-align: center;
justify-content: center;
}
section {
background-color: #F8CFD7;
display: flex;
flex-basis: 75%;
padding: 2rem;
align-items: stretch;
flex-direction: column;
}
article {
border: ridge #80CAF1;
border-width: 3px 3px 0 3px;
display: flex;
font-size: 0.75rem;
min-height: 15vh;
padding: 1rem;
align-items: center;
}
article:last-child {
border-width: 3px;
}
footer {
background-color: #016CBA;
height: 30vh;
}
<body id="body">
<header>
<button id="menu-button" type="button">Menu</button>
</header>
<nav id="menu">
Link 1
Link 2
</nav>
<main id="main">
<aside>Filter Form</aside>
<section>
<article>Article A</article>
<article>Article B</article>
<article>Article C</article>
<article>Article D</article>
<article>Article E</article>
<article>Article F</article>
<article>Article G</article>
<article>Article H</article>
<article>Article I</article>
</section>
</main>
<footer id="footer"></footer>
</body>
now, you use it with visibility yes?
don't use it!
use height: 0;
then when you want open it in js convert it to height: 100% or another size.
and use transition: height .5s; for open as an animation.
After fiddling around, I've finally found a solution that gives me the desired effect:
let menuOpened = false;
document.getElementById('menu-button')
.addEventListener('click', function() {
menuOpened = !menuOpened;
document.getElementById('body').classList.toggle('menu-opened', menuOpened);
document.getElementById('menu').classList.toggle('menu-opened', menuOpened);
});
* {
box-sizing: border-box;
}
body {
margin: 0;
overflow-x: hidden;
}
body.menu-opened {
overflow-y: hidden;
}
body > * {
width: 100vw;
}
header {
background-color: #6FC5C2;
display: flex;
height: 20vh;
position: sticky;
top: 0;
align-items: center;
justify-content: center;
}
nav {
background-color: #80CAF1;
clip-path: inset(0 0 80vh);
display: flex;
height: 80vh;
left: 0;
padding: 1rem;
position: fixed;
top: 20vh;
transition: clip-path 0.35s ease;
z-index: 20;
align-items: center;
flex-direction: column;
justify-content: center;
}
nav.menu-opened {
clip-path: inset(0);
}
a {
color: black;
cursor: pointer;
font-weight: bold;
text-decoration: none;
}
a:not(:last-child) {
margin-bottom: 0.5rem;
}
main {
display: flex;
}
aside {
background-color: #9C9ECF;
display: flex;
flex-basis: 25%;
padding: 3rem 0.5rem;
text-align: center;
justify-content: center;
}
section {
background-color: #F8CFD7;
display: flex;
flex-basis: 75%;
padding: 2rem;
align-items: stretch;
flex-direction: column;
}
article {
border: ridge #80CAF1;
border-width: 3px 3px 0 3px;
display: flex;
font-size: 0.75rem;
min-height: 15vh;
padding: 1rem;
align-items: center;
}
article:last-child {
border-width: 3px;
}
footer {
background-color: #016CBA;
height: 30vh;
}
<body id="body">
<header>
<button id="menu-button" type="button">Menu</button>
</header>
<nav id="menu">
<a>Link 1</a>
<a>Link 2</a>
</nav>
<main id="main">
<aside>Filter Form</aside>
<section>
<article>Article A</article>
<article>Article B</article>
<article>Article C</article>
<article>Article D</article>
<article>Article E</article>
<article>Article F</article>
<article>Article G</article>
<article>Article H</article>
<article>Article I</article>
</section>
</main>
<footer id="footer"></footer>
</body>
The trick is to use clip-path to create a mask over the menu.

Categories