2

I'm trying to animate a <p> tag on its sibling <input>'s focus but it won't work.

I've made a codepen bellow.

I also don't want to use Javascript for the solution.

https://codepen.io/ItsBrianAgar/pen/YrGVxW?editors=0100

HTML

<html lang="en"></html>
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,700,900" rel="stylesheet"/>
  <link href="assets/css/main.css" type="text/css" rel="stylesheet"/>
  <title>myCoffee</title>
</head>
<body>
  <main class="appContainer">
    <div class="app">
      <div class="sectionLogin">
        <div class="logo"><img src="assets/images/logo.svg" alt="logo"/></div>
        <div class="inputLogin">
          <div class="textField"></div>
          <div class="textField">
            <p id="username">Username</p>
            <input type="text" name="username"/>
          </div>
          <div class="textField">
            <p id="password">Password</p>
            <input type="password" name="password"/>
          </div>
        </div>
        <div class="btnLogin">
          <button>LOGIN</button>
        </div>
        <div class="btnSignup">
          <button>SIGN UP</button>
        </div>
      </div>
    </div>
  </main>
</body>

CSS

  input[name="username"]:focus ~ #username {
    perspective: 1000;
    transform: translate3d(-50%, 30px, 0);
    opacity: 0;
    transition: all 150ms ease-out; }
  input[name="password"]:focus ~ #password {
    perspective: 1000;
    transform: translate3d(-50%, 30px, 0);
    opacity: 0;
    transition: all 150ms ease-out; }
voloshin
  • 536
  • 7
  • 17
Brian Agar
  • 33
  • 5

2 Answers2

3

It doesn't work because ~ selector works in other way. It selects all the siblings that comes after main selector. In your case <p> comes before <input>.

To make it working you should make a little replacing in your html:

<div class="textField">
  <input type="text" name="username"/>
  <p id="username">Username</p>
</div>

I know that it may break the layout, but you're able to use position: absolute; to fix it.

voloshin
  • 536
  • 7
  • 17
  • Thanks! was about to rip my hair out. – Brian Agar Sep 22 '17 at 10:52
  • You're welcome. Btw, you could use another selector to make this work (replacement is still required): `input[name="username"]:focus + #username`. It selects *only* the first sibling that comes after. – voloshin Sep 22 '17 at 10:55
2

To use + / ~ the p element must next to the input.

Here is the working demo:

.box {
padding: 30px;
}
.textField {
position: relative; 
}
input {
padding: 10px; 
width: 200px;
border-color: transparent transparent red transparent;
outline: none;
}
p{
margin: 0;
position: absolute;
bottom: 3px;
transition: all linear 0.25s;
}
input:focus + P {
font-size: 12px;
bottom: 30px;
}
<div class="box">
<div class="textField">
<input type="text" name="password"/>
 <p id="password">Password</p>
</div>
</div>
Satheesh Kumar
  • 2,205
  • 1
  • 16
  • 31