使用纯 CSS 在菜单下滑动箭头
Using pure CSS to slide an arrow under a menu
当我将鼠标悬停在菜单上时,我希望箭头会从左侧滑动到我当前悬停在其上的菜单项。
在 JavaScript 中,我会绑定一个事件来悬停并使用箭头元素的 "left" 属性,但我想知道我是否可以有一个纯 css3动画解决方案。
箭头类似于此线程-
但我不希望它出现和隐藏 - 我希望箭头始终可见,并且它会根据我当前悬停在其上的菜单从右向左滑动。
如果我用 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>
更改标记后,您可以这样做。
$(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 中,我会绑定一个事件来悬停并使用箭头元素的 "left" 属性,但我想知道我是否可以有一个纯 css3动画解决方案。
箭头类似于此线程-
但我不希望它出现和隐藏 - 我希望箭头始终可见,并且它会根据我当前悬停在其上的菜单从右向左滑动。
如果我用 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>
更改标记后,您可以这样做。
$(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>