Reputation: 329
I have style input field with HTML and CSS. If we focus on the input I'm shrinking the label with CSS. but If we click somewhere else the label does not shrink. So I'm checking for the input value with javascript and shrinking the lable if the input have value. but the current code only applies on the first input.
How can I fix this?
document.querySelector('.input-group .form-input').addEventListener('input', shrinkLabel);
function shrinkLabel(e) {
const input = e.target,
label = input.nextElementSibling;
if (input.value.length > 0) {
label.classList.add('shrink');
} else {
label.classList.remove('shrink');
}
}
.input-group {
position: relative;
margin: 1rem 0;
}
.input-group .form-input {
display: block;
background: none;
background-color: #fff;
color: #202124;
font-family: 'Poppins', sans-serif;
font-size: 16px;
padding: 13px 15px;
width: 100%;
border: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 5px;
margin: 0;
}
.input-group .form-input:focus {
outline: none;
border-color: #d80810;
}
.input-group .form-input:focus ~ .form-input-label {
font-size: 14px;
top: -12px;
color: #d80810;
}
.input-group .form-input-label {
background: #fff;
color: #80868b;
font-size: 16px;
position: absolute;
pointer-events: none;
padding: 0 7px;
left: 8px;
top: 15px;
-webkit-transition: 300ms ease all;
transition: 300ms ease all;
}
.input-group .form-input-label.shrink {
font-size: 14px;
top: -12px;
color: #d80810;
}
<div class="input-group mb-4">
<input
type="text"
name="username"
value=""
id="username"
class="form-input"
/>
<label for="username" class="form-input-label">Username</label>
</div>
<div class="input-group">
<input
type="password"
name="password"
value=""
id="password"
class="form-input"
/>
<label for="password" class="form-input-label">Password</label>
</div>
Upvotes: 1
Views: 1244
Reputation: 2763
if you a little bit modificate your inputs and put placeholder=" " then you can use pseudo class :placeholder-shown to catch not empty inputs and you can achieve you goal without js. JsBin
.input-group {
position: relative;
margin: 1rem 0;
}
.input-group .form-input {
display: block;
background: none;
background-color: #fff;
color: #202124;
font-family: 'Poppins', sans-serif;
font-size: 16px;
padding: 13px 15px;
width: 100%;
border: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 5px;
margin: 0;
}
.input-group .form-input:focus {
outline: none;
border-color: #d80810;
}
.input-group .form-input:focus ~ .form-input-label
{
font-size: 14px;
top: -12px;
color: #d80810;
}
.input-group .form-input:not(:placeholder-shown) ~ .form-input-label {
font-size: 14px;
top: -12px;
}
.input-group .form-input-label {
background: #fff;
color: #80868b;
font-size: 16px;
position: absolute;
pointer-events: none;
padding: 0 7px;
left: 8px;
top: 15px;
-webkit-transition: 300ms ease all;
transition: 300ms ease all;
}
.input-group input:not(:empty) + label {
font-size: 14px;
top: -12px;
color: #d80810;
}
<div class="input-group mb-4">
<input
type="text"
name="username"
placeholder=" "
value=""
id="username"
class="form-input"
/>
<label for="username" class="form-input-label">Username</label>
</div>
<div class="input-group">
<input
type="password"
name="password"
placeholder=" "
value=""
id="password"
class="form-input"
/>
<label for="password" class="form-input-label">Password</label>
</div>
Upvotes: 0
Reputation: 126
That's because document.querySelector returns only the first result. you should instead use document.querySelectorAll('.input-group .form-input') that will return a list of available inputs then, you should loop over that list and add the event listener to each of the inputs
const inputs = document.querySelectorAll('.input-group .form-input')
if (inputs && inputs.length) {
inputs.forEach(input => input.addEventListener('input', shrinkLabel));
}
function shrinkLabel(e) {
const input = e.target,
label = input.nextElementSibling;
if (input.value.length > 0) {
label.classList.add('shrink');
} else {
label.classList.remove('shrink');
}
}
.input-group {
position: relative;
margin: 1rem 0;
}
.input-group .form-input {
display: block;
background: none;
background-color: #fff;
color: #202124;
font-family: 'Poppins', sans-serif;
font-size: 16px;
padding: 13px 15px;
width: 100%;
border: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 5px;
margin: 0;
}
.input-group .form-input:focus {
outline: none;
border-color: #d80810;
}
.input-group .form-input:focus~.form-input-label {
font-size: 14px;
top: -12px;
color: #d80810;
}
.input-group .form-input-label {
background: #fff;
color: #80868b;
font-size: 16px;
position: absolute;
pointer-events: none;
padding: 0 7px;
left: 8px;
top: 15px;
-webkit-transition: 300ms ease all;
transition: 300ms ease all;
}
.input-group .form-input-label.shrink {
font-size: 5px;
top: -12px;
color: #d80810;
}
<div class="input-group mb-4">
<input type="text" name="username" value="" id="username" class="form-input" />
<label for="username" class="form-input-label">Username</label>
</div>
<div class="input-group">
<input type="password" name="password" value="" id="password" class="form-input" />
<label for="password" class="form-input-label">Password</label>
</div>
<div class="input-group">
<input type="text" name="other" value="" id="other" class="form-input" />
<label for="other" class="form-input-label">other</label>
</div>
Note: I've set the font size to a very small value to make sure the change is easily noticed
Upvotes: 0
Reputation: 3341
Use document.querySelectorAll()
. You would then need to add your event listener with a forEach
loop.
This example is from this MDN article
var highlightedItems = userList.querySelectorAll(".highlighted");
highlightedItems.forEach(function(userItem) {
deleteUser(userItem);
});
Upvotes: 1
Reputation: 10204
document.querySelector
returns the first Element
within the document that matches the specific selector.
So that addEventListener
will be applied on the first input
only.
To get all matched elements, it is needed to use document.querySelectorAll
.
document.querySelectorAll('.input-group .form-input').forEach((item) => {
item.addEventListener('input', shrinkLabel);
});
function shrinkLabel(e) {
const input = e.target,
label = input.nextElementSibling;
if (input.value.length > 0) {
label.classList.add('shrink');
} else {
label.classList.remove('shrink');
}
}
.input-group {
position: relative;
margin: 1rem 0;
}
.input-group .form-input {
display: block;
background: none;
background-color: #fff;
color: #202124;
font-family: 'Poppins', sans-serif;
font-size: 16px;
padding: 13px 15px;
width: 100%;
border: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 5px;
margin: 0;
}
.input-group .form-input:focus {
outline: none;
border-color: #d80810;
}
.input-group .form-input:focus ~ .form-input-label {
font-size: 14px;
top: -12px;
color: #d80810;
}
.input-group .form-input-label {
background: #fff;
color: #80868b;
font-size: 16px;
position: absolute;
pointer-events: none;
padding: 0 7px;
left: 8px;
top: 15px;
-webkit-transition: 300ms ease all;
transition: 300ms ease all;
}
.input-group .form-input-label.shrink {
font-size: 14px;
top: -12px;
color: #d80810;
}
<div class="input-group mb-4">
<input
type="text"
name="username"
value=""
id="username"
class="form-input"
/>
<label for="username" class="form-input-label">Username</label>
</div>
<div class="input-group">
<input
type="password"
name="password"
value=""
id="password"
class="form-input"
/>
<label for="password" class="form-input-label">Password</label>
</div>
Upvotes: 4
Reputation: 1367
document.querySelectorAll('.input-group .form-input').forEach(item => {
item.addEventListener('input', shrinkLabel);
});
.querySelectorAll
should work here!
Upvotes: 1