在 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 过渡期间绘制边框颜色 的相关文章

  • Bootstrap 中的垂直菜单

    有没有办法使用任何引导类来创建垂直菜单 不是下拉菜单 侧边栏上完全独立的垂直菜单 我可以使用我的 css 创建一个 但只是想知道引导程序中是否有任何内置类 或者可以使用顶部栏通过任何 hack 来完成吗 这个问题现在已经很老了 但如果有人看
  • 浮动的垂直对齐方式:左div的

    我有大约 10 个宽度相等但高度不同的 div 我希望它们尽可能紧密地组合在一起 当设置为向左浮动时 它们不会垂直彼此对齐 而是与上面 行 的底部对齐 我在下面模拟了一个小例子 想要去掉空白 你有什么建议吗 我仅限于使用这种格式 因为内容是
  • 常见的 Web UI 样式

    在接下来的几天里 我必须向我的一位客户展示一个 Web 应用程序的原型 问题是我不太擅长 CSS 最糟糕的是我几乎对得到的结果不满意 编写业务逻辑对我来说没有任何挑战 但 UI 设计却占用了我 80 以上的时间 我不需要什么令人惊叹的东西
  • 如何更改同一行元素的位置

    我有一个包含 3 个元素的块 最小值 产品库存 最大值 我需要做的就是找到一种方法将产品库存调整到两个值之间 我的猜测是问题应该出在这些线上 div class max inline parent div class inline bloc
  • Openlayers3:中止绘制交互

    我在 html 中使用绘制交互来手动绘制路线 manual route creation event createRoute click function remove previous interactions map removeInt
  • 弹性项目的等高子项

    我在创建 Flexbox 响应式网格时遇到问题 希望有人能给我指出正确的方向 我想要所有的 blockdiv 的高度相等 并且 bottomdiv 绝对定位到底部 这实际上在当前的解决方案中有效 但是当 的时候h2标题太长 达到了2行 我想
  • 淡化背景但不淡化文本

    我已经对 div 应用了 CSS 淡入 淡出解决方案 在很大程度上我对此感到满意 但是我只想将其应用于背景 而不是文本 我需要文本始终完全不透明 参见示例 http jsfiddle net howiepaul gUAPV 33 http
  • 将背景图像保留在底部

    我一直在研究将图像保留在底部页面的解决方案 我目前得到的代码是 footer background image url images footer png background repeat repeat x position absolu
  • 如何使用CSS使整个div在悬停时改变颜色?

    我有以下内容 div class sidebar nav span2 div class sidebar link span Link 1 span div div class sidebar link span Link 2 span d
  • 当外部 div 动画时,Div 内的 Div 隐藏

    我有一个高度为 0 的父 div 和一个子 div 但在顶部使用 z index 我想要这个子 div 在单击时扩展父 div 的高度 效果确实很好 但是内部 div 消失在与父 div 平行的其他 div 后面 当动画完成时 它会再次显示
  • 为什么百分比边距会导致换行?

    div style background color dd3fb8 a style margin left 10 a a a b a a c a div 在上面的示例中 字母 c 将在新行上 但如果我将 margin left 设置为px单
  • “-webkit-text-fill-color”和“颜色”之间的区别?

    我试图理解之间的区别 webkit text fill color只是简单地color 功能上有什么区别吗 据我所知 它们是完全相同的 有什么事情你可以用其中一个来做 而另一个却不能做吗 来自WebKit 博客 http www webki
  • CSS:滚动条从窗口下方几个像素开始

    我想修复我的标题 标题始终位于页面顶部 并且我的整个内容 包括页脚在内的所有内容 都可以滚动 标题高度为 60 px 如下所示 将其固定在顶部不是问题 我想解决的问题 仅使用CSS 是让滚动条从距顶部 60 像素以下的位置开始 正如您所看到
  • 将 div 的内容垂直居中(不是按行高)

    我有一个 div 我需要将其内容垂直居中 div Free coffee for all the people who visit my restaurant div coffee line height 235px width 300px
  • 使用 CSS3 计算值

    CSS3有没有办法实现这一点 height 100 110px 我的背景 你不能用纯 CSS 来计算它 正如 Litek 提到的 它不适用于所有浏览器 但是有一种组织方法可以处理这个问题 但是您需要将元素包装在另一个浏览器中 body he
  • 如何根据 URL 路径添加 CSS 类?

    如何根据我所在的路径将 CSS 类添加到 div 中 包括如果我在其中包含 则不应该出现问题 div class popup ul li a href vs Example 1 a li li a href bod Example 2 a
  • 垂直对齐 li 内的图像和文本

    我试图将列表元素中的图像和一些文本垂直对齐到中间 但没有运气 eg ul li img src somepath sometext li li img src somepath2 sometext2 li ul 我该怎么做 谢谢 假设您的列
  • 避免使用 Grunt cssmin 任务来删除重复条目

    在我的 Gruntfile 中 我使用 cssmin grunt contrib cssmin 任务 就像是 cssmin css src dist styles css dest dist styles min css 问题是 style
  • 使用 JavaScript 在空闲时隐藏鼠标光标

    是否可以使用JavaScript来设置cursor属性的属性none如果鼠标在一定时间内处于非活动状态 例如五秒 请将其设置回auto当它再次活跃时 EDIT 我意识到none不是有效值cursor财产 尽管如此 许多网络浏览器似乎都支持它
  • 如何隐藏表格行溢出?

    我有一些 html 表 其中文本数据太大而无法容纳 因此 它垂直扩展单元格以适应这种情况 因此 现在存在溢出的行的高度是数据量较小的行的两倍 这是无法接受的 如何强制表格具有相同的行高1em 这是一些重现该问题的标记 表格应该只有一行的高度

随机推荐