I am making a login page using Vue.js v3. I have a button next to the password input field that allows users to show/hide their password. The issue is that the password show/hide button always makes the password input element longer, as opposed to fitting in with it on the right, which is the desired behavior.
Here is an example of the issue. I can't show all the classes, but the ones that affect this issue are below.
<template>
<div class="rel-position flex">
<div class="main-element accent box rel-position">
<form @submit.prevent="Login">
<div class="rel-position flex">
<select class="main-element rel-position clickible clickible-color login-input n-font">
<option value="Albany">Albany</option>
<option value="Walnut Creek">Walnut Creek</option>
</select>
<input class="main-element rel-position clickible login-input n-font" type="text" placeholder="Username" required v-model="username">
<input class="main-element rel-position clickible login-input n-font" :type="showPassword === true ? 'text' : 'password'" placeholder="Password" required v-model="password">
<button class="main-element rel-position clickible n-font" id="toggle-button" type="button" @click="showPassword = !showPassword">
<svg width="70" height="70" v-if="showPassword">
<!--svg would go here-->
</svg>
<svg width="70" height="70" v-else>
<!--SVG would go here -->
</svg>
</button>
<button class="main-element rel-position clickible clickible-color login-input n-font" type="submit">Login</button>
</div>
</form>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const username = ref('');
const password = ref('');
const showPassword = ref(false);
function Login() { // Function to log in to account
// Login code would go here
};
</script>
<style scoped>
.box {
margin-top: 5%;
margin-left: 10%;
margin-right: 10%;
margin-bottom: 5%;
width: 80%;
}
.flex {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
.login-input {
height: 5vh;
width: 35%;
margin-bottom: 5%;
}
#toggle-button {
display: flex;
height: 5%;
margin-bottom: 5%;
width: 10%;
justify-content: center;
align-items: center;
}
</style>
I have tried using different display modes and different flex layouts, and I looked around MDN for tips, but nothing seemed to work.
I think this is close to what you want
<template>
...
<div class="holder">
<input
class="main-element rel-position clickible n-font"
:type="showPassword === true ? 'text' : 'password'"
placeholder="Password"
required
v-model="password"
/>
<button
class="main-element rel-position clickible n-font"
id="toggle-button"
type="button"
@click="showPassword = !showPassword"
>
...
</button>
</div>
...
</template>
<style>
...
.holder {
display: flex;
width: 35%;
flex-direction: row;
align-items: center;
input {
width: 100%;
}
}
#toggle-button {
display: flex;
height: 5%;
margin-bottom: 5%;
width: 10%;
justify-content: center;
align-items: center;
margin-right: -13%;
margin-left: 3%;
}
</style>