CodePen实例分析 --- 悬停按钮

 

CodePen实例分析 --- 悬停按钮

网站链接 : https://codepen.io/kathykato/pen/rZRaNe

效果展示 :

鼠标悬浮

HTML 基本布局

     <!--采用div布局, 整个按钮包在一个div容器中-->
  <div id="container">
         <button class="learn-more">
             <!--左边的箭头-->
             <span class="circle" aria-hidden="true">
                 <span class="icon arrow"></span>
             </span>
             <!--右边的内容-->
             <span class="button-text"> Learn More</span>
         </button>
     </div>

CSS渲染

整体设置

 /*让所有的元素都使用 border-box [设置的 边框(margin) 和 内边距(padding) 的值是包含在 width 内],包括 伪类 before, after
 
 before,after 默认的display 是 inline,
 但难免有人会把它变成 block 来用,这时候统一box-sizing 会好操作一些。
 
 引自: https://www.zhihu.com/question/23143701*/
 * {
     box-sizing: border-box;
 }
 *::after, *::before {
     box-sizing: border-box;
 }
 body {
     font-family: "Mukta", sans-serif;
     /*关于 lrem, 没有找到相关内容, 但根据后面的换算, 这里应该是等效于
    font-size: 16px; */
     font-size: lrem;
     /* 1.5 是相对值, 根据换算, 相当于 1.5 * 16 = 24px
    引自: https://zhidao.baidu.com/question/337951150.html
    实际上确实是24px */
     line-height: 1.5;
     display: flex;
     align-items: center;
     justify-content: center;
     margin: 0;
     /*100% 视口高度*/
     min-height: 100vh;
     background-color: #f3f8fa;
 }

按钮设置

 button {
     position: relative;
     display: inline-block;
     cursor: pointer;
     vertical-align: middle;
 
     /* 把button的外观消除
    可参考: https://jingyan.baidu.com/article/fc07f989404c3812ffe519e1.html */
     outline: none;
     border: 0;
     text-decoration: none;
     background: transparent;
     padding: 0;
     
     font-size: inherit;
     font-family: inherit;
 }

rem 与 px 的换算

之前默认的 font-size 是 16px, 则 1rem = 16px

width: 16px * 12rem = 192px

引自: http://caibaojian.com/rem-and-px.html

 .learn-more {
     width: 12rem;
     /* 默认原来的行高 --- 24px */
     height: auto;
 }

设置圆形

transition 过渡属性详解: https://www.cnblogs.com/xiaohuochai/p/5347930.html#anchor1

 /* 设置圆形形状 */
 .circle {
     transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1);
     position: relative;
     /* 设置为block属性之后, 就可以设置宽高了 */
     display: block;
     margin: 0;
     width: 3em;
     height: 3em;
     background: #282936;
     /* 理论上, 只要border-radius > ((48px / 2px) / 16px) = 1.5rem 即可 */
     border-radius: 1.625rem;
 }
 
 /* 设置圆形位置 */
 .icon {
     transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1);
     /* position属性详解: https://www.cnblogs.com/Altriacabur/p/15869473.html */
     position: absolute;
     top: 0;
     bottom: 0;
     /*上下居中 左右为0 */
     margin: auto;
     background: #fff;
 }

设置悬浮后出现的横线

横线右侧端点不在中间位置, 而在偏右的位置( 由上面的设置可知, 圆的直径为3em )

 .arrow {
     transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1);
     /* "继承" 了.icon的position, 所以可以使用left */
     left: 0.625rem;
     width: 1.125rem;
     height: 0.125rem;
     background: none;
 }

设置箭头

箭头的设置巧妙地运用了正方形的两条边, 直接用伪类设置了一个正方形

调整位置后的伪类

 /* 伪类的用法: https://blog.csdn.net/u013594477/article/details/80393667 */
 .arrow::before {
     /* 原本伪类在横线的最左端 0*0, 设置position: absolute;之后, 就跳到横线中央 0*0
    关于这个变化, 我没有找到合适的解释,但我的想法是因为设置position属性之后, 伪类脱
    离了文档流,漂浮到.arrow前面了(此时伪类和.arrow已经不在一个平面了, 或许这就是所谓"层叠"的真谛吧)
    */
     position: absolute;
     content: "";
     /* 调整伪类的位置 */
     top: -0.25rem;
     right: 0.0625rem;
     
     width: 0.625rem;
     height: 0.625rem;
     border-top: 0.125rem solid #fff;
     border-right: 0.125rem solid #fff;
     /* 旋转中心默认为正方形中心 */
     transform: rotate(45deg);
 }

设置按钮的文字内容

 

 .button-text {
     transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1);
     /* 脱离文档流, 实现层叠 */
     position: absolute;
     /* 相对button的位置进行调整
    position属性详解: https://www.cnblogs.com/Altriacabur/p/15869473.html
    详情参看 absolute 一条
    */
     top: 0;
     left: 0;
     right: 0;
     bottom: 0;
     /* 垂直水平居中 */
     padding: 0.75rem 0;
     text-align: center;
     
     margin: 0 0 0 1.85rem;
     color: #282936;
     font-weight: 700;
     line-height: 1.6;
     text-transform: uppercase;
 }

其实如果可以精准把控的话, 也用不到水平垂直居中和内外边距, 但是咱能不算还是不算的好, 也避免维护的麻烦, 但是为了深入理解CSS的布局, 也可以自己算一下, 我这就算了个大概, 大家不用较真

 .button-text {
     transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1);
     position: absolute;
     top: 0.75em;
     left: 3em;
     color: #282936;
     font-weight: 700;
     line-height: 1.6;
     text-transform: uppercase;
 }

设置过渡效果

 button:hover .circle {
     width: 100%;
 }
 
 button:hover .arrow {
     /* 原来是background: none; 没显示*/
     background-color: #fff;
     /* 鼠标悬浮后, .arrow::before也会向右移动一段距离, 所以让arrow也跟上
    但是我也不知道它为啥会移动, 移动了多少
    但如果改变上面的width的话, .arrow::before的移动距离也没有发生肉眼可见的改变
    */
     transform: translate(1rem, 0);
 }
 
 button:hover .button-text {
     color: #fff;
 }

@support

 /* 当浏览器支持display:grid这个CSS属性时才应用其中的样式
    @support CSS3引入的新规则之一, 检测当前浏览器是否支持某个CSS属性并加载具体样式.
    比较鸡肋, 较高级浏览器才支持@support, 但高级的浏览器支持大部分CSS属性
    可以用来检测浏览器是不是"低级"浏览器
 
  引自: https://blog.csdn.net/liangtaox8/article/details/101107512
 */
 /* 这一段不要也可以, 但是似乎grid比flex高级一些, 但是兼容性不太好 */
 @supports (display: grid) {
     body {
         display: grid;
         grid-template-columns: repeat(4, 1fr);
         grid-gap: 0.625rem;
         grid-template-areas: ". main main ." ". main main .";
    }
 
     #container {
         grid-area: main;
         align-self: center;
         justify-self: center;
    }
 }

 

posted @ 2022-02-08 18:41  Altriacabur  阅读(67)  评论(0)    收藏  举报