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>
Related
.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>
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>
I am trying to make a simple demo li elements Which is horizontal center followed by Play or Pause button (see attached image ).I am able to make this using Flexbox properties. but facing few issue
Issue:
My li elements are moving or changing it position when I hover the Button.
conditions
we can't give hardcoded width to TEXT or hover text or PLAY or PAUSE .Text can be as big as possible ?
here is my code
https://jsbin.com/kobezulipe/edit?html,css,output
li {
list-style:none;
}
.abc{
display: flex;
align-items: center;
margin: 0 auto;
width: 100%;
justify-content: center;
}
.list{
overflow: hidden;
left: 0;
list-style: none;
display: -ms-flexbox;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
text-align: center;
padding: 0;
margin: 0;
}
.list li{
width: 52px;
margin: 0 9px;
}
.list li button{
border: 1px solid #3A3631;
width: 52px;
}
.p{
position: relative;
height: 100%;
display: flex;
align-self: center;
align-items: center;
width: initial;
left: 18px;
margin-bottom: 0;
}
.container {
padding: 8px;
border: 1px solid;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all 0.2s linear;
}
.text {
display: none;
}
.button {
border: 0;
background: transparent;
box-sizing: border-box;
width: 0;
height: 20px;
border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
cursor: pointer;
border-style: solid;
border-width: 10px 0 10px 20px;
padding: 0
}
.button.paused {
border-style: double;
border-width: 0px 0 0px 20px;
}
.button:hover {
border-color: transparent transparent transparent #404040;
}
.container:hover span {
display: inline;
}
<div class="abc">
<ul class='list'>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
</ul>
<div class="p">
<div class="container">
<button class='button'>
</button>
<span class="text">Play</span>
</div>
</div>
</div>
Attached expected output
Answer pic
It's moving because the flexbox in .abc justify-content: center. When the width of the button changes, everything moves to stay centered.
If you change that to start it will not move.
Alternatively, if you don't want the content to move and you want to keep it centered, and you can't use a hard-coded width, you can try using an overlay. It won't move when you hover, though it might cover up anything next to it:
add a second button next to the first one. remove the text from the original.
set this button to position: absolute so it's positioned above the layout. the parent is already position: relative
only display the overlay during .p:hover. Hide the original button with visibility: hidden so it keeps its width and height.
Example:
li {
list-style:none;
}
.abc{
display: flex;
align-items: center;
margin: 0 auto;
width: 100%;
justify-content: center;
}
.list{
overflow: hidden;
left: 0;
list-style: none;
display: -ms-flexbox;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
text-align: center;
padding: 0;
margin: 0;
}
.list li{
width: 52px;
margin: 0 9px;
}
.list li button{
border: 1px solid #3A3631;
width: 52px;
}
.p{
position: relative;
height: 100%;
display: flex;
align-self: center;
align-items: center;
width: initial;
left: 18px;
margin-bottom: 0;
}
.container {
display: inline-flex;
}
.container, .overlay {
padding: 8px;
border: 1px solid;
align-items: center;
justify-content: center;
}
.overlay {
position: absolute;
left: 0;
top: 0;
flex-direction: row;
display: none;
transition: all 0.2s linear;
}
.p:hover .overlay {
display: inline-flex;
}
.p:hover .container {
visibility: hidden;
}
.text {
white-space: nowrap;
}
.button {
border: 0;
background: transparent;
box-sizing: border-box;
width: 0;
height: 20px;
border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
cursor: pointer;
border-style: solid;
border-width: 10px 0 10px 20px;
padding: 0
overflow: visible;
}
.button.paused {
border-style: double;
border-width: 0px 0 0px 20px;
}
.button:hover {
border-color: transparent transparent transparent #404040;
}
.container:hover span {
display: inline;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="abc">
<ul class='list'>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
</ul>
<div class="p">
<div class="container">
<button class='button'>
</button>
</div>
<div class="overlay">
<button class='button'>
</button>
<span class="text">Play, this can be very long</span>
</div>
</div>
</div>
</body>
With #kid-jokers answer you can add white-space: nowrap; to container div to allow words to span on one line.
var btn = document.querySelector(".button");
btn.addEventListener('click',function(){
btn.classList.toggle('paused');
document.querySelector(".button");
})
li {
list-style:none;
}
.abc{
display: flex;
align-items: center;
margin: 0 auto;
width: 100%;
justify-content: center;
}
.list{
overflow: hidden;
left: 0;
list-style: none;
display: -ms-flexbox;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
text-align: center;
padding: 0;
margin: 0;
}
.list li{
width: 52px;
margin: 0 9px;
}
.list li button{
border: 1px solid #3A3631;
width: 52px;
}
.p{
position: relative;
height: 100%;
display: flex;
align-self: center;
align-items: center;
width: 52px;
left: 18px;
margin-bottom: 0;
}
.container {
padding: 8px;
border: 1px solid;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all 0.2s linear;
}
.text {
display: none;
}
.button {
border: 0;
background: transparent;
box-sizing: border-box;
width: 0;
height: 20px;
border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
cursor: pointer;
border-style: solid;
border-width: 10px 0 10px 20px;
padding: 0
}
.button.paused {
border-style: double;
border-width: 0px 0 0px 20px;
}
.button:hover {
border-color: transparent transparent transparent #404040;
}
.container:hover span {
display: block;
white-space: nowrap;
}
<div class="abc">
<ul class='list'>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
<li><button><span></span></button></li>
</ul>
<div class="p">
<div class="container">
<button class='button'>
</button>
<span class="text">Play WHAM! - Jitterbug</span>
</div>
</div>
</div>
new answer: ↓
i rewrote the html. and the .p is positioned relative to the .list.
var btn = document.querySelector(".button");
btn.addEventListener("click", function () {
btn.classList.toggle("paused");
document.querySelector(".button");
});
li {
list-style: none;
}
.abc {
display: flex;
align-items: center;
margin: 0 auto;
width: 100%;
justify-content: center;
}
.list {
/* overflow: hidden; */
left: 0;
list-style: none;
display: -ms-flexbox;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
text-align: center;
padding: 0;
margin: 0;
position: relative;
}
.list li {
width: 52px;
margin: 0 9px;
}
.list li button {
border: 1px solid #3a3631;
width: 52px;
}
.p {
position: relative;
height: 100%;
display: flex;
align-self: center;
align-items: center;
width: initial;
/* left: 18px; */
margin-bottom: 0;
position: absolute;
right: -18px;
transform: translateX(100%);
}
.container {
padding: 8px;
border: 1px solid;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all 0.2s linear;
}
.text {
display: none;
}
.button {
border: 0;
background: transparent;
box-sizing: border-box;
width: 0;
height: 20px;
border-color: transparent transparent transparent #202020;
transition: 100ms all ease;
cursor: pointer;
border-style: solid;
border-width: 10px 0 10px 20px;
padding: 0;
}
.button.paused {
border-style: double;
border-width: 0px 0 0px 20px;
}
.button:hover {
border-color: transparent transparent transparent #404040;
}
.container:hover span {
display: inline;
}
<div class="abc">
<ul class="list">
<li>
<button><span></span></button>
</li>
<li>
<button><span></span></button>
</li>
<li>
<button><span></span></button>
</li>
<li>
<button><span></span></button>
</li>
<div class="p">
<div class="container">
<button class="button"></button>
<span class="text">Play longer longer longer</span>
</div>
</div>
</ul>
</div>
hope it can help you。
you can change the .p {width: initial;} to .p {width: 52px;}
JavaScript Noob
On the footer of the site I'm trying to display the contact info with a popup like form
whenever I copied the code to new page or new device the button clicked opens the form
but then the form closes immediately
Is there a way to fix this?
<button class="open-button" onclick="openForm()">
Contact Us</button>
<div class="form-popup">
<form class="form-container" id="myForm">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>
<script>
function openForm() {
//openForm().stopPropagation();
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
}
</script>
And the CSS part:
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.form-container {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
I've already tried Google search solutions to no avail.
Also different methods from other helpful sites but every time I change something the button doesn't work at all.
After click on button the element with .form-popup class does not show because in your CSS you have set display:none:
.form-popup {
display: none;
....
}
So you need to set display:flex or block for .form-popup too.
Here is working sample:
function openForm() {
document.getElementById("myForm").parentElement.style.display = "flex";
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
document.getElementById("myForm").parentElement.style.display = "none";
}
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.form-container {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
<button class="open-button" onclick="openForm()">
Contact Us
</button>
<div class="form-popup">
<form class="form-container" id="myForm">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>
#Alireza Ahmadi
Reposting the new code...
function openForm() {
document.getElementById("myForm").parentElement.style.display = "flex";
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
document.getElementById("myForm").parentElement.style.display = "none";
}
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.div-form {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
<button class="open-button" onclick="openForm()">
Contact Us</button>
<div class="form-popup">
<div class="div-form" id="myForm">
<form class="form-container">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>
</div>
Right now the button doesn't do anything the page only shows that is refreshing
Guys need some help im trying to figure out how can i execute multiple events on single click i am able to change the image on my gallery but i wanted to add some text label on each Img click i need to change each H3 and replace whenever i click the other image, i need to do a multiple event on single click
const current = document.querySelector('#current');
const imgs = document.querySelectorAll('.imgs img');
const main = document.querySelector('#main-info h3');
const info = document.querySelector('.info');
imgs.forEach(img => img.addEventListener('click', imgClick));
function imgClick(e) {
current.src = e.target.src;
}
body {
font-family: Arial, Helvetica, sans-serif;
font: 15px/1.5;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 90%;
margin: auto;
overflow: hidden;
}
header {
display: flex;
justify-content: space-between;
padding-top: 5px;
background-color: #567890;
min-height: 130px;
border-bottom: 3px #e0480c solid;
padding: 0 20px 0 0;
}
header #branding {
float: left;
margin: 0;
}
header #branding img {
margin: 0;
padding: 0;
}
header ul {
margin: 0;
padding: 0;
}
header li {
display: inline;
float: left;
padding: 0 20px 0 20px;
margin-top: 50px;
}
header a {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
font-size: 16px;
}
header a:hover {
color: #b9b8b9;
opacity: 1;
}
header nav {
float: right;
padding-bottom: 50px;
}
.current a {
color: #e0480c;
font-weight: bold;
}
#showcase {
min-height: 400px;
background: linear-gradient(rgba(0, 0, 50, 0.5), rgba(0, 0, 50, 0.5)),
url(/img/enseymada.jpg) no-repeat 0 -400px;
text-align: center;
background-size: cover;
opacity: 0.9;
}
#showcase .main-info {
margin-top: 100px;
margin-bottom: 10px;
justify-content: center;
font-size: 50px;
font-weight: 600;
color: #fffcff;
}
#showcase p {
font-size: 20px;
font-weight: 200;
color: #ccc;
}
.topinfo {
text-align: center;
justify-content: center;
}
.info2 {
text-align: center;
justify-content: center;
}
footer {
width: 100%;
bottom: 0;
position: relative;
}
.foot {
background: #e24305;
color: #fff;
height: 10px;
margin: 0;
width: 100%;
text-align: center;
padding: 7px 10px;
justify-content: center;
align-items: center;
}
.main-img img,
.imgs img {
margin: auto;
width: 100%;
background: cover;
border-radius: 10%;
}
.imgs {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 5px;
background: cover;
cursor: pointer;
}
.wrapper {
border: #444 solid 3px;
max-width: 800px;
margin: auto;
height: 100%;
padding: 5px;
align-items: center;
justify-content: center;
overflow: hidden;
}
.newsletter {
margin-bottom: 100px;
padding: 0;
width: 100%;
height: 80px;
align-items: center;
justify-content: center;
background-color: #567890;
}
.newsletter h1 {
float: left;
color: #ffffff;
}
.newsletter .btn {
display: inline;
margin: 20px 5px;
padding: 10px;
background-color: #444;
color: #fff;
border: none;
}
.newsletter #subscribe {
padding: 10px;
margin-left: 10px;
border: none;
}
<div class="wrapper">
<div class="main-img">
<h3 id="main-info">Classic Enseymada</h3>
<img src="img/image2.jpg" id="current">
</div>
<div class="imgs">
<img src="img/image2.jpg">
<div class="info">
<img src="img/image3.jpg">
<h3>Nuttela</h3>
</div>
<img src="img/image4.jpg">
<img src="img/image6.jpg">
<img src="img/image7.jpg">
<img src="img/image8.jpg">
</div>
</div>
<footer><div class="foot">Copyright © Abby Cook's 2020</div></footer>
<script src="./js/main.js"></script>
</body>
</html>
I am assuming that you want to pass more arguments to your imgClick function.
One way to do it is to use anonymous functions, something like this should do the trick :
imgs.forEach(img => img.addEventListener('click', function(e){
imgClick(e, 'param1', 'param2',);
}));
function imgClick(e, param1, param2,) {
current.src = e.target.src;
// your code
}
Add then your code in the function.