Website jumps around when virtual keyboard is up

92 Views Asked by At

I have a login page. ( used in full screen mode like a PWA. Added to home screen )

When the user clicks on one of the input boxes the virtual keyboard pops up. When the user finishes typing the username he either wants to click away from the box to be able to click to the login button or wants to click to the password input box. When the user clicks away the virtual keyboard hides but bring the page with itself to the bottom. And if the user clicks again, the website jumps back to it's normal position.

Here is a gif demonstrating the problem:

enter image description here

Here is a snippet:

var usernameEl = document.querySelector("#username");
var passwordEl = document.querySelector("#password");
var loginBtnEl = document.querySelector(".login-btn");

function pwVisibilityEvent(){
    let pwShowBtn = document.querySelector(".pw-show-btn");
    pwShowBtn.addEventListener("click",function(e){
        pwShowBtn.classList.toggle("visible");
        if( pwShowBtn.classList.contains("visible") ){
            passwordEl.setAttribute("type","text");
        }else{
            passwordEl.setAttribute("type","password");
        }
    },false);
}
pwVisibilityEvent();
*{
    box-sizing: border-box;

    --light-base-color: #183153;
    --dark-base-color: white;
    --hitec-base-color: #34bdeb;
    
    --bg-color: #f8f7f5;
    --dark-bg-color: #222222;

    --header-bg-color: #34bdeb;
    --dark-header-bg-color: #087195;

    --pw-show-bg-color: #34bdeb;
    --dark-pw-show-bg-color: #087195;

    --input-color: dimgray;
    --dark-input-color: #34bdeb;

    --input-placeholder-color: #69696996;
    --dark-input-placeholder-color: #34bdebc0;

    --login-btn-bg-color: #34bdeb;
    --dark-login-btn-bg-color: #087195;
}

body {
    position: relative;
    width: 100%;
    padding: 0px;
    margin: 0px;
    height: 100vh;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 35px;
}

html{
    background-color: var(--bg-color);
}

html.dark-theme {
    background-color: var(--dark-bg-color);
}

.header {
    margin-bottom: 30px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 10px;
}

span.header-text {
    font-size: 1.5em;
    color: var(--header-bg-color);
}

html.dark-theme span.header-text {
    color: var(--dark-header-bg-color);
}

.logo-wrapper {
    width: 100px;
    height: 100px;
    border-radius: 0.5em;
    overflow: hidden;
    box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
}

.logo-wrapper img{
    width: 100%;
    height: 100%;
}

form.login {
    width: 80%;
    max-width: 500px;
}

span.made-by-wrap {
    position: absolute;
    bottom: 5px;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 5px;
    font-weight: bold;
}

button.pw-show-btn {
    width: 55px;
    height: 30px;
    border: none;
    transition: color 0.2s ease;
    background-color: var(--pw-show-bg-color);
    color: white;
    border-radius: 0.3em;
    cursor: pointer;
}

html.dark-theme button.pw-show-btn {
    background-color: var(--dark-pw-show-bg-color);
}

button.pw-show-btn.visible{
    background-color: orangered;
}

button.pw-show-btn svg{
    width: 100%;
    height: 100%;
}

button.pw-show-btn span {
    width: 100%;
    height: 100%;
}

button.pw-show-btn .pw-locked{
    display: block;
}
button.pw-show-btn .pw-unlocked{
    display: none;
}

button.pw-show-btn.visible .pw-locked{
    display: none;
}
button.pw-show-btn.visible .pw-unlocked{
    display: block;
}

input {
    padding: 10px;
    font-size: 1em;
    border: none;
    background-color: white;
    border-radius: 0.5em;
    box-shadow: rgb(0 0 0 / 5%) 1.95px 1.95px 2.6px;
    width: 100%;
    color: var(--input-color);
    transition: box-shadow 0.2s ease;
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
    transition: background-color 5000s ease-in-out 0s;
    -webkit-text-fill-color: #34bdeb !important;
    opacity:1;
}

input:focus-visible{
    border: none;
    outline: none;
    box-shadow: rgba(0, 0, 0, 0.315) 1.95px 1.95px 2.6px;
}

input::placeholder{
    color: var(--input-placeholder-color);
    font-size: 0.9em;
}


html.dark-theme input {
    background-color: #222222;
    box-shadow: rgb(0 0 0 / 78%) 0px 1px 2.6px;
    color: var(--dark-input-color);
}

html.dark-theme input::placeholder{
    color: var(--dark-input-placeholder-color);
}

.fields {
    width: 100%;
    margin: 40px 0px;
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.pw-field {
    display: flex;
    gap: 10px;
    justify-content: center;
    align-items: center;
}

.form-field {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

span.error-label {
    padding-left: 10px;
    font-size: 0.95em;
    color: orangered;
}

button.login-btn {
    cursor: pointer;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    border: none;
    padding: 10px;
    border-radius: 0.5em;
    background-color: var(--login-btn-bg-color);
    font-size: 1.1em;
    color: white;
    transition: background-color 0.2s ease;
    box-shadow: rgb(0 0 0 / 5%) 1.95px 1.95px 2.6px;
}

html.dark-theme button.login-btn {
    box-shadow: rgb(0 0 0 / 72%) 1.95px 1.95px 2.6px;
    background-color: var(--dark-login-btn-bg-color);
}

button.login-btn.error{
    animation: shakeOnErr .1s ease;
    background-color: #be0000 !important;
}


@keyframes shakeOnErr{
    0%{
        transform: translate(-10px);
    }
    50%{
        transform: translate(10px);
    }
    100%{
        transform: translate(0px);
    }
}

span.made-by {
    color: #df609f;
}

.made-by-link {
    color: #34bdeb;
    padding: 5px;
    transition: font-size 0.2s ease;
}

.made-by-link:hover{
    font-size: larger;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>HsH Login</title>

    <link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png">
    <link rel="manifest" href="/assets/hsh.webmanifest">
    <link rel="mask-icon" href="/assets/icons/safari-pinned-tab.svg" color="#5bbad5">
    <meta name="msapplication-TileColor" content="#da532c">
    <meta name="theme-color" content="#ffffff">
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    
    <link rel="stylesheet" href="/pages/login/css/style.css">

    <script type="module" src="/pages/login/bundle/login.bundle.js"></script>
</head>
<body>
    
    <form action="" class="login">

        <div class="header">
            <div class="logo-wrapper">
                <img src="/assets/icons/android-chrome-256x256.png" alt="logo" class="logo">
            </div>
            <span class="header-text">Test</span>
        </div>

        <div class="fields">
            <div class="form-field">
                <input type="text" lang="Username" name="username" class="username" id="username" placeholder="Username">
                <span id="usernameErr" class="error-label"></span>
            </div>
            <div class="form-field">
                <div class="pw-field">
                    <input type="password" lang="Password" name="password" class="password" id="password" placeholder="Password">
                    <button class="pw-show-btn" type="button">
                        <span class="pw-locked">
                            <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9.76406 5.29519C10.4664 5.10724 11.2123 5 12 5C18.3636 5 22 12 22 12C22 12 21.171 13.5958 19.612 15.2635M4.34912 8.77822C2.8152 10.4307 2 12 2 12C2 12 5.63636 19 12 19C12.8021 19 13.5608 18.8888 14.2744 18.6944M11.5 14.9585C10.4158 14.7766 9.52883 14.0132 9.17071 13M12.5 9.04148C13.7563 9.25224 14.7478 10.2437 14.9585 11.5M3 3L21 21" stroke="#001A72" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </span>
                        <span class="pw-unlocked">
                            <svg version="1.1" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 512 512">
                                <g><g>
                                    <path d="m499.4,250.8c-51-86.3-143.6-140.4-243.4-140.4s-192.5,54.1-243.4,140.4c-2.1,3.1-2.1,7.3 5.32907e-15,10.4 51,86.3 143.6,140.4 243.4,140.4s192.5-54.1 243.4-140.4c2.1-3.1 2.1-7.3 0-10.4zm-243.4,130c-90.5,0-174.8-47.8-221.6-124.8 46.8-77 131.1-124.8 221.6-124.8s174.8,47.8 221.6,124.8c-46.8,77-131.1,124.8-221.6,124.8z"/>
                                    <path d="m256,162.4c-52,0-93.6,41.6-93.6,93.6 0,52 41.6,93.6 93.6,93.6s93.6-41.6 93.6-93.6c0-52-41.6-93.6-93.6-93.6zm0,166.4c-40.6,0-72.8-32.3-72.8-72.8s32.3-72.8 72.8-72.8 72.8,32.3 72.8,72.8-32.2,72.8-72.8,72.8z"/>
                                    <path d="m256,214.4v20.8c11.4,0 20.8,9.4 20.8,20.8s-9.4,20.8-20.8,20.8-20.8-9.4-20.8-20.8h-20.8c0,22.9 18.7,41.6 41.6,41.6 22.9,0 41.6-18.7 41.6-41.6s-18.7-41.6-41.6-41.6z"/>
                                </g></g>
                            </svg>
                        </span>
                    </button>
                </div>
                <span id="passwordErr" class="error-label"></span>
            </div>
        </div>

        <div class="form-field">
            <button type="submit" class="login-btn" lang="Login">Login</button>
        </div>

    </form>

    <span class="made-by-wrap">
        <!-- <span class="made-by">Made by</span> -->
        <a href="https://www.google.com" class="made-by-link">test.hu</a>
    </span>

</body>
</html>

I have the same problem on other pages, where this exact same problem occours on any input field on mobile.

0

There are 0 best solutions below