如何让父元素(span)在CSS中对子元素(input)进行变换?

How to make the parent element (span) transform over the child element (input) in CSS?

我想给输入框做一个炫酷的效果。我希望这发生:

当用户点击输入框时,输入框的顶部(border-top)优雅地移动到输入框的底部(border-bottom)。

但是,我很快了解到您不能将元素 border-top 移动到 border-bottom 的位置。

所以我制定了一个可行的解决方案(有点)!通过将输入放置在 span 元素内,我能够将 span 的 border-top 向下转换,以产生输入边框顶部向下移动的错觉。 唯一的问题是,当 span 的边框移到输入框上方时,您将无法再看到它,因为输入框的 z-index 更大(我猜)。

这是我的解决方案:


<!DOCTYPE html>
<html>
<head>
<style>

/* input box - no border, no ouline, and a transition to move up (to cancel out the transtion made by the parent).*/
input{
    border: 1px solid transparent;
    outline: none;
    transition: transform 2s;
 }

/* span - red border and a transition to move down */
span{
    display: inline-block;
    content: '';
    border-top: 1px solid red;
    transition: transform 2s;
}

/* on focus of the child element of span - transform span down */

span:focus-within{
transform: translate(0%, 30px);
}

/* while active or focused on input - transform input up*/
input:active, input:focus {
transform: translate(0%, -30px);

}


</style>
</head>
<body>

<span>

<input type='text' placeholder='john doe'/>

</span>


</body>
</html>

所以,很自然地,我认为解决方案是为 span 元素授予更高的 z-index。 问题是,如果我这样做,那么整个事情就会中断,因为 input 是 span 的子项...因此,如果 span 具有更高的索引,那么我将永远无法在输入框中输入任何文本。

如下图:


<!DOCTYPE html>
<html>
<head>
<style>

/* input box - no border, no ouline, and a transition to move up (to cancel out the transtion made by the parent).*/
input{
    border: 1px solid transparent;
    outline: none;
    transition: transform 2s;
    position: relative;
      z-index: -1;


}

/* span - red border and a transition to move down */
span{
    display: inline-block;
    content: '';
    border-top: 1px solid red;
    transition: transform 2s;
    position: relative;
    z-index: 1;

}

/* on focus of the child element of span - transform span down */

span:focus-within{
transform: translate(0%, 30px);
}

/* while active or focused on input - transform input up*/
input:active, input:focus {
transform: translate(0%, -30px);

}


</style>
</head>
<body>

<span>

<input type='text' placeholder='john doe'/>

</span>


</body>
</html>

请有人告诉我如何能够与输入框交互并让 span 边框在输入框上明显地滑动?

添加背景:对输入框透明。

无需尝试切换两个项目的位置,您可以使用 :before 渲染一行。这样可以防止红线的位置改变输入的位置。

<!DOCTYPE html>
<html>
<head>
<style>

/* input box - no border, no outline */
input{
    border: 1px solid transparent;
    outline: none;
 }

span{
    position: relative
}

/* red border and a transition to move up */
span:before{
    height: 0;
    position: absolute;
    width: 100%;
    display: block;
    content: ' ';
    border-top: 1px solid red;
    transition: top 1s;
    top: 0;
}

/* on focus of the span - transform line down */
span:focus-within:before{
    transition: top 1s;
    top: 100%;
}

</style>
</head>
<body>

<span>

<input type='text' placeholder='john doe'/>

</span>


</body>
</html>

您可以将 inputspan 嵌套到 div 标记中,并相对于 div 从上到下转换跨度

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
  <style>
    input:focus {
      border: none !important;
      outline: none !important;
    }
    
    #inp:focus~span {
      top: 100%
    }
  </style>
</head>
<body class="bg-gray-900">
  <div id="input-wrapper" class="relative w-64">
    <input id="inp" class="block w-full px-2 py-4" placeholder="what need to be done">
    <span class="absolute w-full top-0 block duration-300 left-0 border border-solid border-green-500"></span>
  </div>

</body>
</html>

这是答案,有点像 no-brainer,使输入背景颜色透明。

<!DOCTYPE html>
<html>
<head>
<style>

/* input box - no border, no ouline, and a transition to move up (to cancel out the transtion made by the parent).*/


input{
    border: 1px solid grey;
    outline: none;
    transition: transform 1s;
    background-color: transparent;
    color: black;
    z-index: -1;*/


}

/* span - red border and a transition to move down */
span{
    display: inline-block;
    content: '';
    border-top: none;
    transition: transform 1s;
}

/* on focus of the child element of span - transform span down */

span:focus-within{
    border-top: 1px solid grey;
transform: translate(0%, 20px);
}

/* while active or focused on input - transform input up*/
input:active, input:focus {
border: 1px solid transparent;
transform: translate(0%, -20px);

}


</style>
</head>
<body>
<div>
<span>

<input type='text' placeholder='john doe'/>

</span>
</div>


</body>
</html>

但是,这只有在您希望输入框的背景与页面的背景相同时才有效。如果没有,您可以将其包装在另一个 span 或 div 标记中,如下所示:

<!DOCTYPE html>
<html>
<head>
<style>

/* input box - no border, no ouline, and a transition to move up (to cancel out the transtion made by the parent).*/
body{
background-color: grey;
}

input{
    border: 1px solid white;
    outline: none;
    transition: transform 1s;
    background-color: transparent;
    color: white;
    z-index: -1;*/


}

/* span - red border and a transition to move down */
span{
    display: inline-block;
    content: '';
    border-top: none;
    transition: transform 1s;
}

/* on focus of the child element of span - transform span down */

span:focus-within{
    border-top: 1px solid white;
transform: translate(0%, 20px);
}

/* while active or focused on input - transform input up*/
input:active, input:focus {
border: 1px solid transparent;
transform: translate(0%, -20px);

}

div{
background-color: black;
display:inline-block; 
}

</style>
</head>
<body>
<div>
<span>

<input type='text' placeholder='john doe'/>

</span>
</div>


</body>
</html>