从句子过渡到一个词

时间:2017-11-17 20:25:01

标签: css css3 css-transitions

我想要实现的是以元素中心悬停单词的方式为元素宽度设置几个单词的动画,其余部分平滑地超出边界。我还会在HTML中尽可能保持清晰,而不是使用固定像素数量的边距/宽度来定位元素。

我心中的糟糕草图在这里:

* {
  transition: all 1.5s;
}

div {
  min-width: 150px;
  width: 30%;
  height: 25px;
  line-height: 25px;
  background: orange;
  text-align: center;
  overflow: hidden;
}

div:hover {
  background: white;
  word-spacing: 300px;
}

a:hover::after,
a:hover::before {
  content: ' ';
}
<div>
  <a class="afirst" href="">First</a> & <a class="asecond" href="">Second</a>
</div>

悬停时的每个单词都应该转到中心位置(当其他单词消失时,可能不会显示那些“跳跃”)。你有什么想法?我很确定我尝试使用字间距的方式是错误的。

3 个答案:

答案 0 :(得分:2)

问题在于,当增加单词间距时,文本会转到新行并创建此跳转内容。所以你可以添加white-space: nowrap,你也可以使用padding-left来推送文本并将其放在中心:

&#13;
&#13;
div {
  min-width: 150px;
  width: 180px;
  height: 25px;
  line-height: 25px;
  background: orange;
  text-align: center;
  overflow: hidden;
  transition: all 0.5s;
  box-sizing: border-box;
  white-space: nowrap;
}

div:hover {
  word-spacing: 80px;
  padding-left: 80px;
  background: white;
}
&#13;
<div>
  <a class="afirst" href="">First</a> & <a class="asecond" href="">Second</a>
</div>
&#13;
&#13;
&#13;

实际上,单词间距应用于div,因此您无法将鼠标悬停在单词上。在第一个单词上应用此技术也更容易,因为第二个单词将被溢出隐藏,但我不确定如何使用单词间距对第二个单词执行相同操作。

这是关于如何在没有字间距的情况下如何做的另一个想法。我使用了一些填充动画和伪元素来隐藏第一个单词。

&#13;
&#13;
div {
  min-width: 150px;
  width: 180px;
  height: 25px;
  line-height: 25px;
  background: orange;
  text-align: center;
  overflow: hidden;
  transition: all 0.5s;
  box-sizing: border-box;
  white-space: nowrap;
}

.afirst,
.asecond {
  position:relative;
  display: inline-block;
  transition: all 0.5s;
}

.afirst:hover {
  padding: 0 44%;
  background: white;
}
.asecond:hover {
  padding: 0 50% 0 0;
  background: white;
}
.asecond:hover::before {
  content:" ";
  position:absolute;
  left:-50%;
  width:50%;
  top:0;
  bottom:0;
  z-index:99;
  background:#fff;
}
&#13;
<div>
  <a class="afirst" href="">First</a> & <a class="asecond" href="">Second</a>
</div>
&#13;
&#13;
&#13;

我认为您可以使用左侧的:before 元素和右侧的:after 元素来隐藏其他所有内容,从而推广此解决方案。

这是一个包含多个单词的示例(但没有正确地给出中心对齐,仍然需要改进):

&#13;
&#13;
div {
  min-width: 150px;
  height: 25px;
  line-height: 25px;
  background: orange;
  text-align: center;
  overflow: hidden;
  transition: all 0.5s;
  box-sizing: border-box;
  white-space: nowrap;
}

.word {
  position: relative;
  display: inline-block;
  transition: all 0.5s;
}

.word:hover {
  background: white;
  padding: 0 40%;
}

.word:hover::before {
  content: " ";
  position: absolute;
  left: -50%;
  width: 50%;
  top: 0;
  bottom: 0;
  z-index: 99;
  background: #fff;
}

.word:hover::after {
  content: " ";
  position: absolute;
  right: -50%;
  width: 50%;
  top: 0;
  bottom: 0;
  z-index: 99;
  background: #fff;
}
&#13;
<div>
  <a class="word" href="">First</a> &
  <a class="word" href="">Second</a> &
  <a class="word" href="">third</a> &
  <a class="word" href="">Fourth</a>
</div>
&#13;
&#13;
&#13;

另一种具有完美居中效果的解决方案,但其他词语的动画效果较少:

&#13;
&#13;
div {
  position:relative;
  height: 25px;
  width:500px;
  margin:0 auto;
  line-height: 25px;
  background: orange;
  text-align: center;
  overflow: hidden;
  transition: all 0.5s;
  box-sizing: border-box;
  white-space: nowrap;
}

.word {
  position: relative;
  z-index:9;
  display: inline-block;
  transition: all 0.5s;
}

.word:hover {
  position:absolute;
  right:0;
  left:0;
  top:0;
  bottom:0;
  text-align:center;
  background: white;
  z-index:99;
}
&#13;
<div>
  <a class="word" href="">First</a> &
  <a class="word" href="">Second</a> &
  <a class="word" href="">third</a> &
  <a class="word" href="">Fourth</a>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

此版本使用 Flex Box ,适用多项不使用固定宽度

我一直在玩这个问题的主要原因是没有使用固定宽度的物品。特别是那些后来排队并试图将物品推向左边的人。

解决方案:弹性框order

您可以用数字方式设置弹性项目的顺序,因此只需在悬停时将其设置为-1即可将悬停项目放在列表的第一位,这样就可以消除向左弯曲项目的问题。

动画可能不像您正在寻找的那样流畅,因为您只能按整数转换顺序。因此,它会立即与宽度一起设置,然后其他属性转换。

&#13;
&#13;
div.outer {
  width: 50vw;
  height: 30px;
  background: orange;
  text-align: center;
  overflow: hidden;
  position: relative;
  padding: 0;
}

div.inner {
  position: relative;
  margin: 0 auto;
  height: 30px;
  width: 50vw;
  display: flex;
  justify-content: center;
  align-items: center;
  background: transparent;
  flex-wrap: wrap;
}

span {
   order: 1;
   padding: 0 3px;
   flex-shrink:1;
}

a {
  z-index: 0;
  order: 1;
  height: 30px;
  line-height: 30px;
  flex-grow: 0;
  flex-shrink: 1;
  transition: background .5s, flex-grow .25s, flex-shrink .25s;
 }

a:hover {
  z-index: 10;
  width: 50vw;
  order: -1;
  flex-grow: 1;
  background: #eee;
}
&#13;
<div class="outer">
  <div class="inner">
    <a href="">First</a>
    <span>&amp;</span>
    <a href="">Second</a>
    <span>&amp;</span>
    <a href="">Third</a>  
  </div>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

这并不完美,但我认为它非常接近实现您的目标。使用一点点jQuery对于数学来说是必要的(但不是动画本身)。

希望这能让你更进一步!

&#13;
&#13;
function reset() {
  // reset all spans
  $('.animate span').css('transform', '');
  $('.animate span.active').removeClass('active');
}

$('.animate').on('mouseover', 'span:not(.active)', function() {
  reset();

  // set current hovered word to active
  $(this).addClass('active');

  // slide over previous/next words
  $(this).prevAll().css('transform', 'translateX(-100vw)');
  $(this).nextAll().css('transform', 'translateX(100vw)');

  // determine offset for center of hovered word
  var center = (window.innerWidth / 2) - ($(this).offset().left + ($(this).width() / 2));
  // slide current word to center
  $(this).css('transform', 'translateX(' + center + 'px)');
});

// when leaving animate section, reset
$('.animate').mouseleave(reset);
&#13;
.animate {
  background-color: orange;
  color: white;
  font-family: sans-serif;
  text-align: center;
  transition: .5s background-color, .5s color;
}

.animate:hover {
  background-color: white;
  color: orange;
}

span {
  display: inline-block;
  transition: 3s transform;
}

a {
  color: inherit;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="animate">
  <span><a href="#">First</a></span> <span>&amp;</span> <span><a href="#">Second</a></span> <span>&amp;</span> <span><a href="#">Third</a></span> <span>and</span> <span><a href="#">Fourth</a></span>
</div>
&#13;
&#13;
&#13;