【问题标题】:Using pure CSS to slide an arrow under a menu使用纯 CSS 在菜单下滑动箭头
【发布时间】:2016-11-14 15:34:22
【问题描述】:

当我悬停在菜单上时,我希望箭头会从左侧滑到我当前悬停的菜单项。

在 JavaScript 中,我会绑定一个事件以悬停并使用箭头元素的“左”属性进行播放,但我想知道我是否可以有一个纯 css3 动画解决方案。

箭头与此线程相似- Show border triangle in navbar using CSS

但我不希望它出现和隐藏 - 我希望箭头始终可见,并且它会根据我当前悬停的菜单从右向左滑动。

如果我在 JS 中完成,这就是它的样子:

var arrEle = $("#indication-mark-wrap");
var startHover = $(arrEle).css("left");
$("li").mouseenter(function() {
  var left = $(this).position().left;
  $(arrEle).css("left", left+30);
});

$("li").mouseleave(function() {
  $(arrEle).css("left", startHover);
});
ul {
  list-style-type: none;
  padding: 0px;
}

li {
  display: inline-block;
  width: 80px;
  color: white;
  background-color: black;
  height: 50px;
}

#indication-mark-wrap {
  position: absolute;
  left: 38px;
  top: 56px;
  background: wheat;
  -webkit-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
  -moz-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
  -o-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
  transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
  /* custom */
  -webkit-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
  -moz-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
  -o-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
  transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
  /* custom */
}

.indication-mark {
  position: relative;
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="menu">
  <ul>
    <li>Selection1</li>
    <li>Selection2</li>
    <li>Selection2</li>
  </ul>
</div>

<div id="indication-mark-wrap">
  <canvas width="20" height="20" class="indication-mark"></canvas>
</div>

Sample JSFiddle

【问题讨论】:

    标签: css animation hover


    【解决方案1】:

    更改标记后,您可以这样做。

    $(function(){
    $("li").click(function(){
      $(".active").removeClass("active");
      $(this).addClass("active");
    })
    });
    ul {
      list-style-type: none;
      padding: 0px;
    }
    
    li {
      background-color: black;
    }
    
    li:nth-child(-n+3) {
      display: inline-block;
      width: 80px;
      color: white;
      height: 50px;
    }
    
    #indication-mark-wrap {
      position: absolute;
      left: 35px;
      top: 56px;
      background: wheat;
      -webkit-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -moz-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -o-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      /* custom */
      -webkit-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -moz-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -o-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      /* custom */
    }
    
    .indication-mark {
      position: relative;
      display: block;
    }
    
    li:nth-child(2):hover ~ li #indication-mark-wrap {
      left: 118px;
    }
    li:nth-child(3):hover ~ li #indication-mark-wrap {
      left: 200px;
    }
     
    li:nth-child(1).active ~ li #indication-mark-wrap {
      left: 35px;
    }
    
    li:nth-child(2).active ~ li #indication-mark-wrap {
      left: 118px;
    }
    li:nth-child(3).active ~ li #indication-mark-wrap {
      left: 200px;
    }
    
    #indication-mark-wrap:before,
    #indication-mark-wrap:after {
      content: "";
      position: absolute;
      top: 15px;
      width: 0;
      height 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-bottom: 15px solid white;
    }
    #indication-mark-wrap:before {
      top: 14px;
      border-bottom-color: black;
    }
    .active {
      background-color: darkcyan;
    }
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <div class="menu">
      <ul>
        <li class="active">Selection1</li>
        <li>Selection2</li>
        <li>Selection2</li>
        <li class="test"><div id="indication-mark-wrap"></div></li>
      </ul>
    </div>

    仅限 CSS

    ul {
      list-style-type: none;
      padding: 0px;
    }
    li {
      background-color: black;
    }
    li:nth-child(-n+3) {
      display: inline-block;
      width: 80px;
      color: white;
      height: 50px;
    }
    li:nth-child(-n+3) label {
      display: inline-block;
      width: 100%;
      height: 100%;
      cursor: inherit;
    }
    
    #indication-mark-wrap {
      position: absolute;
      left: 35px;
      top: 56px;
      background: wheat;
      -webkit-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -moz-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -o-transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      transition: all 1000ms cubic-bezier(0.000, 0.000, 0.330, 0.990);
      /* custom */
      -webkit-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -moz-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      -o-transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      transition-timing-function: cubic-bezier(0.000, 0.000, 0.330, 0.990);
      /* custom */
    }
    
    .indication-mark {
      position: relative;
      display: block;
    }
    
    #s1, #s2, #s3 {
      display: none;
    } 
    #s1:checked ~ ul #indication-mark-wrap {
      left: 35px;
    }
    #s2:checked ~ ul #indication-mark-wrap {
      left: 118px;
    }
    #s3:checked ~ ul #indication-mark-wrap {
      left: 200px;
    }
    li:nth-child(-n+3):hover {
      background: darkgray;
      cursor: pointer;
    }
    #s1:checked ~ ul li:nth-child(1),
    #s2:checked ~ ul li:nth-child(2),
    #s3:checked ~ ul li:nth-child(3) {
      background-color: darkcyan;
      cursor: auto;
    }
    
    #indication-mark-wrap:before,
    #indication-mark-wrap:after {
      content: "";
      position: absolute;
      top: 15px;
      width: 0;
      height 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-bottom: 15px solid white;
    }
    #indication-mark-wrap:before {
      top: 14px;
      border-bottom-color: black;
    }
    <div class="menu">
      <input type="radio" id="s1" name="s123" checked="checked">
      <input type="radio" id="s2" name="s123">
      <input type="radio" id="s3" name="s123">
      <ul>
        <li><label for="s1">Selection1</label></li>
        <li><label for="s2">Selection2</label></li>
        <li><label for="s3">Selection3</label></li>
        <li class="test"><div id="indication-mark-wrap"></div></li>
      </ul>
    </div>

    【讨论】:

    • 我添加了对“活动”选项卡的支持,只有 javascript 用于单击,这是可以的,因为它是由引导选项卡添加的。现在它非常适合我的需求。
    • @ZivWeissman 更新了 2:nd 示例,仅使用 CSS 的活动选项卡(如果您想无脚本
    • 很好,我喜欢标签技巧... ;) 添加到样式 cursor:pointer(不是 .active),它是一个非常酷的 CSS 即插即用菜单!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多