CSS – 带有不同字符串大小的居中对齐打字动画

huangapple go评论52阅读模式
英文:

CSS - Centrally justified typing animation with varying string sizes

问题

我正在尝试为我的作品集网站创建一个打字动画效果。我有两个问题,它们是:

  1. 在打字动画进行时,文本在水平方向上会抖动,我认为这是因为我的打字动画导致被“打字”的文本的宽度动态变化,但我尝试过的所有修复方法都没有解决这个问题。

  2. 我正在尝试使打字动画居中对齐,而不是居左对齐。这个问题是,每个字符串的长度都不同,所以如果我正确定位一个字符串,其后的其他字符串将显得不协调。在任何文档编辑器中居中对齐文本时,字符串的开头和打字光标都会随着字符串变长而相互移动相同的距离。但我不确定如何实现这一点。

英文:

I'm trying to creating a typing animation effect for a portfolio website. I have two issues, which are:

  1. The text jitters horizontally as the typing animation progresses, i'm assuming this is due to the fact that my typing animation is causing the width of the animated the text being "typed" to change dynamically, but none of the fixes I have tried have resolved the issue.

  2. I'm trying to get the typing animation to be justified to the center instead of the left. The problem with this is, each string is different in length and so If I correctly position one string, the others following it will look out of place. When typing centrally justified text in any document editor, both the start of the string and the typing cursor move away from each other equal amounts as the string gets longer. But i'm not sure how to achieve this.

CSS – 带有不同字符串大小的居中对齐打字动画

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

* {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}


.main {
    overflow:hidden
}


.home__container {
    row-gap:4rem;
    padding-top:2rem
}

.home__data {
    row-gap:1.5rem
}

.home__title {
    text-align:center;
    font-size:var(--biggest-font-size);
    letter-spacing:.3px;
    margin-bottom:.5rem
}

.section__border {
    border-bottom:1px solid var(--title-color);
    padding-bottom:3.5rem
}

.container {
    max-width:1024px;
    margin-inline:1.5rem
}

.grid {
    display:grid;
    gap:1.5rem
}

.type {
  display: inline-block;
}

.type&gt;span {
  display: grid;
  overflow: hidden;
  height: 1.2em;
}

.type span span {
  width: 0%;
  max-width: max-content;
  overflow: hidden;
  height: inherit;
  word-break: break-all;
  animation: c 0.5s infinite steps(1), t 2s linear infinite alternate, m 12s steps(3) infinite;
}

.type span span:before {
  content: &quot; &quot;;
  display: inline-block;
}

@keyframes t {
  90%,
  100% {
    width: 100%
  }
}

@keyframes c {
  0%,
  100% {
    box-shadow: 5px 0 0 #0000
  }
  50% {
    box-shadow: 5px 0 0 rgb(255, 255, 255)
  }
}

@keyframes m {
  100% {
    transform: translateY(-300%)
  }
}

<!-- language: lang-html -->

&lt;main class=&quot;main&quot;&gt;
  &lt;section class=&quot;home section&quot; id=&quot;home&quot;&gt;
    &lt;div class=&quot;home__container container grid section__border&quot; id=&quot;maincard&quot;&gt;
      &lt;div class=&quot;home__data grid&quot;&gt;
        &lt;h1 class=&quot;home__title&quot;&gt;Hello World, I&amp;#x27;m Dan &lt;br /&gt;&lt;span class=&quot;type&quot;&gt;
                        &lt;span&gt;
                          &lt;span&gt;Software Engineer&lt;/span&gt;
          &lt;span&gt;Computer geek&lt;/span&gt;
          &lt;span&gt;Coffee lover&lt;/span&gt;
          &lt;/span&gt;
          &lt;/span&gt;&lt;br /&gt;
        &lt;/h1&gt;

<!-- end snippet -->

答案1

得分: 2

我建议使用transformclip-path的组合来进行动画效果。以下是一个示例,如果您有三行文本 + 在您的许可下,添加了光标 🙂:

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.home-title {
  --line-height: 20px;
  --animation-duration: 8s;
  --lines: 3;
  --type-steps: 12;
  display: grid;
  justify-content: center;
  font-family: monospace;
  font-size: 16px;
  line-height: var(--line-height);
}

.type-wrapp {
  height: var(--line-height);
  display: grid;
  overflow: hidden;
}

.type {
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: type-translate var(--animation-duration) steps(var(--lines)) infinite;
}

.type span {
  white-space: nowrap;
  animation: type var(--animation-duration) steps(var(--type-steps)) infinite;
  position: relative;
  padding-right: 2px;
}

/* 光标 */

.type span:after {
  content: '';
  border-left: solid 2px currentColor;
  inset: 0;
  position: absolute;
  animation:
    cursor var(--animation-duration) steps(var(--type-steps)) infinite,
    cursor-blink calc(var(--animation-duration) / var(--type-steps)) steps(2) infinite;
}

@keyframes type-translate {
  100% {
    transform: translateY(-100%);
  }
}

/*
Keyframes for three phrases, taking into account the pause.
If there are more or fewer phrases, the keyframes will be different.
*/

@keyframes type {
  11.111%,
  22.222%,
  44.444%,
  55.555%,
  77.777%,
  88.888% {
    transform: translateX(0);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
  }
  0%,
  33.333%,
  66.666%,
  99.999% {
    transform: translateX(50%);
    clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
  }
}

/* 光标动画 */

@keyframes cursor {
  11.111%,
  22.222%,
  44.444%,
  55.555%,
  77.777%,
  88.888% {
    transform: translateX(calc(100% - 2px));
  }
  0%,
  33.333%,
  66.666%,
  99.999% {
    transform: translateX(-2px);
  }
}

@keyframes cursor-blink {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<h1 class="home-title">
  Hello World, I'm Dan
  <br>
  <span class="type-wrapp">
    <span class="type">
      <span>Software Engineer</span>
      <span>Computer geek</span>
      <span>Coffee lover</span>
    </span>
  </span>
</h1>
英文:

I suggest for animation using a combination of transform and clip-path.
Below is an example if you have three lines + with your permission, added the cursor 🙂:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
.home-title {
--line-height: 20px;
--animation-duration: 8s;
--lines: 3;
--type-steps: 12;
display: grid;
justify-content: center;
font-family: monospace;
font-size: 16px;
line-height: var(--line-height);
}
.type-wrapp {
height: var(--line-height);
display: grid;
overflow: hidden;
}
.type {
display: flex;
flex-direction: column;
align-items: center;
animation: type-translate var(--animation-duration) steps( var(--lines) ) infinite;
}
.type span {
white-space: nowrap;
animation: type var(--animation-duration) steps( var(--type-steps) ) infinite;
position: relative;
padding-right: 2px;
}
/* cursor */
.type span:after {
content: &#39;&#39;;
border-left: solid 2px currentColor;
inset: 0;
position: absolute;
animation:
cursor var(--animation-duration) steps( var(--type-steps) ) infinite,
cursor-blink calc( var(--animation-duration) / var(--type-steps) ) steps(2) infinite
;
}
@keyframes type-translate {
100% {
transform: translateY(-100%);
}
}
/*
Keyframes for three phrases, taking into account the pause.
If there are more or fewer phrases, the keyframes will be different.
*/
@keyframes type {
11.111%,
22.222%,
44.444%,
55.555%,
77.777%,
88.888% {
transform: translateX(0);
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
0%,
33.333%,
66.666%,
99.999% {
transform: translateX(50%);
clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
}
}
/* cursor animation */
@keyframes cursor{
11.111%,
22.222%,
44.444%,
55.555%,
77.777%,
88.888% {
transform: translateX( calc(100% - 2px) );
}
0%,
33.333%,
66.666%,
99.999% {
transform: translateX(-2px);
}
}
@keyframes cursor-blink {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

<!-- language: lang-html -->

&lt;h1 class=&quot;home-title&quot;&gt;
Hello World, I&#39;m Dan
&lt;br&gt;
&lt;span class=&quot;type-wrapp&quot;&gt;
&lt;span class=&quot;type&quot;&gt;
&lt;span&gt;Software Engineer&lt;/span&gt;
&lt;span&gt;Computer geek&lt;/span&gt;
&lt;span&gt;Coffee lover&lt;/span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;/h1&gt;

<!-- end snippet -->

答案2

得分: 0

如果在您的姓名后关闭h1标签并将旋转文本的外部容器更改为div,抖动就会消失:

<h1 class="home__title">Hello World, I'm Dan</h1>
<div class="type">
  <span>
    <span>Software Engineer</span>
    <span>Computer geek</span>
    <span>Coffee lover</span>
  </span>
</div>

对于间距,您可以在父div上使用flexbox:

<div class="parent">
  <h1 class="home__title">Hello World, I'm Dan</h1>
  <div class="type">
    <span>
      <span>Software Engineer</span>
      <span>Computer geek</span>
      <span>Coffee lover</span>
    </span>
  </div>
</div>
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

您可以使用justify-content和align-items将元素垂直和水平居中,flex-direction会将输入文本放在h1下方。

英文:

If you close the h1 tag after your name and change the outer container of the rotating text to a div the jitters go away:

&lt;h1 class=&quot;home__title&quot;&gt;Hello World, I&#39;m Dan&lt;/h1&gt;
&lt;div class=&quot;type&quot;&gt;
&lt;span&gt;
&lt;span&gt;Software Engineer&lt;/span&gt;
&lt;span&gt;Computer geek&lt;/span&gt;
&lt;span&gt;Coffee lover&lt;/span&gt;
&lt;/span&gt;
&lt;/div&gt;

for the spacing, you can use flexbox on the parent div:

&lt;div class=parent&gt;
&lt;h1 class=&quot;home__title&quot;&gt;Hello World, I&#39;m Dan&lt;/h1&gt;
&lt;div class=&quot;type&quot;&gt;
&lt;span&gt;
&lt;span&gt;Software Engineer&lt;/span&gt;
&lt;span&gt;Computer geek&lt;/span&gt;
&lt;span&gt;Coffee lover&lt;/span&gt;
&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
.parent {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
You use the justify-content and align-items to center elements vertically and horizontally, and flex direction will put the typing text below the h1.
</details>

huangapple
  • 本文由 发表于 2023年7月7日 06:01:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632764.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定