在 CSS 过渡期间绘制边框颜色

2024-04-25

button {
  background: none;
  border: 0;
  box-sizing: border-box;
  margin: 1em;
  padding: 1em 2em;
  box-shadow: inset 0 0 0 2px #f45e61;
  color: #f45e61;
  font-size: inherit;
  font-weight: 700;
  position: relative;
  vertical-align: middle;
}
button::before, button::after {
  box-sizing: inherit;
  content: " ";
  position: absolute;
  width: 100%;
  height: 100%;
}
.draw {
  transition: color 0.25s;
}
.draw::before, .draw::after {
  border: 2px solid transparent;
  width: 0;
  height: 0;
  transition: width 1.25s ease-out 1.25s, height 1.25s ease-out 1.25s;

}
.draw::before {
  top: 0;
  left: 0;
}
.draw::after {
  bottom: 0;
  right: 0;
}
.draw:hover {
  color: #60daaa;
}
.draw:hover::before, .draw:hover::after {
  width: 100%;
  height: 100%;
}
.draw:hover::before {
  border-top-color: #60daaa;
  border-right-color: #60daaa;
  transition: width 0.25s ease-out, height 0.25s ease-out 0.25s;
}
.draw:hover::after {
  border-bottom-color: #60daaa;
  border-left-color: #60daaa;
  transition: border-color 0s ease-out 0.5s, width 0.25s ease-out 0.5s, height 0.25s ease-out 0.75s;
}
<section class="buttons">
  <button class="draw">Draw</button>
</section>

我有一支工作笔(https://codepen.io/anon/pen/vdgdxO https://codepen.io/anon/pen/vdgdxO),在悬停(右上左下)时更改元素的边框颜色,并进行一些过渡以使其平滑。

我希望能够在几秒钟后“反转”边框颜色变化。基本上,我想在相反的颜色改变时改变边框颜色:

  • 顶部边框改变颜色
  • 右边框改变颜色
  • border-bottom 改变颜色,border-top 返回原来的颜色
  • border-left 改变颜色,border-right 返回原来的颜色
  • border-top 改变颜色,border-bottom 恢复原来的颜色
  • 右边框改变颜色,左边框恢复原来的颜色 ETC。

现在我只解决了颜色变化,但我不知道如何“反转”它。我也希望这种过渡永远循环,但我不知道从哪里开始。有什么建议么?


我会使用多个linear-gradient and a complex动画(通过动画每个动画的大小/位置)以获得最终结果。如果您掌握了窍门,您可以轻松调整不同的值以获得您想要的任何动画。

.draw {
  padding: 20px 50px;
  outline:none;
  border: none;
  box-shadow: none;
  background-image: 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61), 
  
  linear-gradient(#60daaa, #60daaa), 
  linear-gradient(#60daaa, #60daaa), 
  linear-gradient(#60daaa, #60daaa), 
  linear-gradient(#60daaa, #60daaa);
  
  background-position: 0 0, 0 0, 0 100%, 0 100%, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 0% 3px, 0% 3px, 3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  background-color:transparent;
  background-repeat:no-repeat;
  transition:0.2s linear;
}

.draw:hover {
  background-position: 0 100%, 0 0, 0 100%, 100% 0, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  animation: animate 1.4s linear infinite 0.2s;
}

@keyframes animate {
  0% {
  background-position: 0 100%, 0 0, 0 100%, 100% 0, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  }
  40% {
  background-position: 0 100%, 100% 0, 100% 100%, 100% 0, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 100%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  }
  60% {
  background-position: 0 100%, 100% 0, 100% 100%, 100% 100%, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 0% 3px, 100% 3px,3px 100%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  }
  70% {
  background-position: 0 100%, 100% 0, 0% 100%, 100% 100%, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 100%, 0% 3px, 100% 3px,3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  }
  80% {
  background-position: 0% 0%, 0% 0, 0% 100%, 100% 100%, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 100%, 0% 3px, 0% 3px,3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;
  }
  100% {
  background-position: 0% 0%, 0 0, 0 100%, 100% 100%, 
                       0 0, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%,  
                   3px 100%, 100% 3px, 100% 3px,3px 100%;  
  }
}
<button class="draw">Draw</button>

它是如何工作的?

结构:我们有 8 个linear-gradient。 4 将简单地创建初始边框并且不会移动(它们放置在底层),4 将用于绘制在初始边框上方创建动画的线(它们放置在顶层)。

该顺序很重要,因为在背景属性中,每个渐变都有 8 个值。您会注意到3px值将简单地指定每个渐变的宽度或高度(类似于border-width)并且在动画过程中它不会改变。

动画:我将调整每个渐变的位置/大小来创建动画。它分为两部分:一个小过渡和一个大动画。转换仅用于创建动画的初始状态,这就是为什么用于转换的持续时间与动画的延迟相同。

  1. 第一步是制作动画top border 从左到右。为此,渐变应位于(0,0) [top,left]大小为0% 3px [width height]。然后我只需将大小更改为100% 3px我将获得所需的动画(前面描述的 3px 不会改变)。

  2. 现在,要为第二个边框设置动画,我们也执行相同的操作。我们需要一个位于(100%,0) [top,right]大小为3px 0% [width height]我们的动画3px 100%:

  1. 现在,由于我们有两个边框,我们需要为第三个边框设置动画并隐藏第一个边框。我不会详细介绍第三个边框,因为它与上面的边框类似,所以让我们看看如何隐藏顶部边框。第一个直观的想法是简单地将其大小设置回0% 3px但这只会创建反向动画,因此我们将有一个右到左动画很糟糕。这里的技巧是调整渐变的位置,使其(100%,0) [top,right]代替(0,0)因为当渐变大小为 100% 时,两个位置是等效的(因此我们在为第二个动画设置动画时在上一步中执行此操作)。现在,我们可以将尺寸放回0% 3px我们将会有一个左到右动画片:
  1. 我们继续相同的逻辑,直到回到初始状态并指定infinite在动画属性中我们将获得所需的效果。

所以主要的想法是有一个大小等于 0% 的渐变,我们在给定方向上将其动画到全尺寸 (100%),然后我们更改其位置(这不会对全尺寸产生任何影响),然后进行动画将其大小恢复为 0。我们将其与我们拥有的 4 个渐变混合。

UPDATE

为了避免与所有这些渐变混淆,这里进行了更新,我在静态边框中使用了伪元素,因此我们只为动画保留 4 个渐变:

.draw {
  position:relative;
  padding: 20px 50px;
  outline:none;
  border: none;
  box-shadow: none;
  background-image: 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61), 
  linear-gradient(#f45e61, #f45e61);
  
  background-position: 0 0, 0 0, 0 100%, 0 100%;
  background-size: 3px 0%, 0% 3px, 0% 3px, 3px 0%;
  background-color:transparent;
  background-repeat:no-repeat;
  transition:0.2s linear;
}
.draw:before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  right:0;
  left:0;
  bottom:0;
  border:3px solid #60daaa;
}

.draw:hover {
  background-position: 0 100%, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%;
  animation: animate 1.4s linear infinite 0.2s;
}

@keyframes animate {
  0% {
  background-position: 0 100%, 0 0, 0 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%;
  }
  40% {
  background-position: 0 100%, 100% 0, 100% 100%, 100% 0;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 100%;
  }
  60% {
  background-position: 0 100%, 100% 0, 100% 100%, 100% 100%;
  background-size: 3px 0%, 0% 3px, 100% 3px,3px 100%
  }
  70% {
  background-position: 0 100%, 100% 0, 0% 100%, 100% 100%;
  background-size: 3px 100%, 0% 3px, 100% 3px,3px 0%;
  }
  80% {
  background-position: 0% 0%, 0% 0, 0% 100%, 100% 100%;
  background-size: 3px 100%, 0% 3px, 0% 3px,3px 0%;
  }
  100% {
  background-position: 0% 0%, 0 0, 0 100%, 100% 100%;
  background-size: 3px 0%, 100% 3px, 0% 3px,3px 0%  
  }
}
<button class="draw">Draw</button>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CSS 过渡期间绘制边框颜色 的相关文章

  • 在 Chrome 中,应用于包含图像的锚点的轮廓高度不正确

    对于我正在开发的网站 我希望当链接聚焦 悬停 活动时 链接周围会出现虚线轮廓 我希望文本和图像链接发生这种情况 我遇到的问题是 虽然我的代码在 Firefox 和 IE 中运行良好 但在 Chrome 7 0 517 41 中 虚线轮廓与我
  • 图像下方不需要的边距

    我有一个图像和一个 div 我想将其放置在其下方 这是小提琴 http jsfiddle net d3Mne 1 http jsfiddle net d3Mne 1 问题是两者之间存在差距 此下边距仅出现在图像中 有什么办法可以去除吗 Se
  • 在响应模式下使用 CSS 更改元素顺序

    图1为桌面模式 下面两张图片和文字 总共三个div 图 2 是我希望它在移动浏览器 例如手机 中的显示方式 关于如何实现这一点有什么想法吗 我愿意接受任何建议 这个想法是让文本显示在图像上方 以最好地说明这两个图像的描述 在桌面版本中将文本
  • CSS3 转换会立即发生吗?

    我有一个名为 artwork需要动画化 artwork webkit transition all 20s ease in transition all 20s ease in width 75 display block margin 0
  • 如何设置引导开关的 css 颜色?

    如何在此引导开关中将蓝色更改为另一种颜色 我尝试更改输入元素的颜色和背景颜色 但它没有更改开关颜色 这是 html 和 bootstraplink https getbootstrap com docs 4 2 components for
  • CSS:多属性选择器

    我想设置 电子邮件 和 密码 类型的表单输入样式 但不设置其他任何样式 我正在想象类似以下的事情 input type email type password 然而 属性选择器的工作方式似乎将其解释为 输入 其中类型同时是 电子邮件 and
  • Firefox 忽略背景大小的 css

    尝试使用背景大小 CSS 规则缩小图像 但 Firefox 3 5 似乎会忽略该规则 CSS privatejoker background aqua url styles images home privatejoker png no r
  • React Native 上的文本缩进

    我需要缩进 React Native 段落的第一行 但使用常见的csstext indent财产 textIndent 与 React Native 不兼容 伪元素选择器也不兼容 例如 first line 有什么方法可以做到这一点而不用将
  • 如何设置旋转元素背面的样式?

    我有一个figure它是可旋转的 通过用户输入任意角度 该旋转明显地使用transition财产 当该元件旋转超过 90 度 90 度时 元件的背面可见 我想对元素的通常隐藏的一面进行与正面不同的设计 但我不确定如何实现这一点 figure
  • 响应式导航栏隐藏其下方的元素

    我创建了一个响应式导航栏 但它使下面的元素 Flexslider 插件 消失 在我制作导航栏之前 下面的 Flexslider 可以正常显示 但现在不行 导航栏的 z index 为 2 所以我不知道问题是什么 我应该如何 更改什么才能允许
  • 是否有针对 CSS 位置和可点击区域的 Android 浏览器错误的解决方法?

    当您有一些可点击的内容时 例如 a a
  • 使用滤镜将css3灰色图像转为蓝色?

    我正在尝试将灰色图像变为更蓝色的色调 真的不知道如何为此设置滤镜或是否可能 该图像只有一种颜色 cacaca 其余部分透明 我正在尝试使用相同的图像进行一些叠加 以便它仅突出显示那些彩色部分而不是透明区域 一直在尝试其中的一些 但没有取得多
  • 为开槽元素中的后代元素设置样式

    是否可以选择开槽元素中的后代元素 像这样的例子 slotted div p color blue div p test p div 这不起作用 不 您只能选择顶级节点 slotted slotted 中的选择器只能是复合选择器 https
  • 由于 MIME 类型不受支持,拒绝应用样式

    我不断收到一条错误消息 指出 MIME 类型 text html 不可执行或不是受支持的样式表 MIME 类型 并且启用了严格的 MIME 检查 我的链接代码是
  • 两个 Div 之间的固定宽度间隙

    有谁知道如何修复两个 div 之间的间隙 我有一个主要内容 Div 里面有两个带有图片的 Div 视图的宽度为 768 像素 当我开始拉伸视图时 两张图片开始相互远离 但理想情况下 主要内容 Div 应该在周围有空白的情况下拉伸 并且图片之
  • 通过 JavaScript 检测浏览器换行

    我需要 javascript 来检测每个浏览器包装的文本行并将其包装到 span class line 我读过一些关于测量每个单词的 y 轴的文章 但还没有看到可靠的解决方案 这是我到目前为止所拥有的 看到它Jsfiddle http js
  • 在 IE 8 及以下版本中动态添加 @font-face 规则

    我使用 IE stylesheet addRule 方法添加 font face 规则 但是 符号对于该方法的 选择器 参数来说是不允许的字符 因此我收到 无效参数 错误 s addrule font face font family Fo
  • CALayer边框奇怪问题

    我正在向 CALayer 添加边框 但有一些奇怪的行为 在我应用的边框之后出现模糊边框 参见屏幕截图 这是我的代码 void configureLabel self hidden YES self textAlignment NSTextA
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 为什么元素上的负底部边距会降低该元素父元素的高度?

    这可能是由于边距折叠造成的 我知道边距折叠 至少知道它如何影响相邻元素 但我不明白当涉及负边距时它如何在嵌套元素上工作 例如 在此标记和随附的 CSS 中 Markup div class parent div class child Ch

随机推荐