How to create a text flow basic テキストが横方向に流れる基本アニメーションの作り方
Gradient text scrolls horizontally in an infinite loop with speed controlled via a custom property. グラデーションテキストを無限ループで横方向に流し、スピードをカスタムプロパティで制御します。
ライブデモ Live Demo
概要・用途・特徴Overview, Usage & Features
何ができるかWhat it does
Gradient text scrolls horizontally in an infinite loop with speed controlled via a custom property.
グラデーションテキストを無限ループで横方向に流し、スピードをカスタムプロパティで制御します。
どこで使うかWhere to use
hero section, micro interaction, visual feedback, brand expression
ヒーローセクション、ブランド表現、ティッカー表示、マイクロインタラクション
特徴Key features
Pure CSS @keyframes marquee animation with no JavaScript required. Gradient text via background-clip technique. Speed controlled entirely by a single CSS custom property (--flow-duration). Accessible: respects prefers-reduced-motion.
純粋なCSSアニメーション(@keyframes)のみでJavaScript不要。background-clipによるグラデーションテキスト。スピードはCSSカスタムプロパティ(--flow-duration)一つで制御。prefers-reduced-motionに対応。
調整可能パラメータ Adjustable Parameters
| Parameter | Default | Description |
|---|---|---|
--flow-duration | — | duration of a full loop (e.g., 8s, 18s) |
--flow-gradient | — | linear-gradient colors for the text |
--flow-gap | — | gap between repeating text segments |
prefers-reduced-motion | — | respect user settings by slowing/stopping the loop |
実装コード Implementation Code
// react/M-001.jsx
import { useState } from "react";
import "./M-001.css";
export default function TextFlowBasic() {
const [speed, setSpeed] = useState(12);
return (
<section className="text-flow-basic" style={{ ["--flow-duration"]: `${speed}s` }}>
<div className="text-flow-basic__viewport">
<Track label="Text Flow Basic · DevSnips · " />
<Track label="Text Flow Basic · DevSnips · " aria-hidden="true" />
</div>
<label className="text-flow-basic__label">
Speed (seconds)
<input
type="range"
min="6"
max="20"
value={speed}
onChange={(event) => setSpeed(Number(event.target.value))}
/>
<output>{speed}s</output>
</label>
</section>
);
}
function Track({ label, ...props }) {
return (
<div className="text-flow-basic__track" {...props}>
<span>{label}</span>
<span>{label}</span>
</div>
);
}
/* react/M-001.css */
:root {
--flow-gradient: linear-gradient(90deg, #7f5af0, #ffa7c4, #22d3ee);
}
.text-flow-basic {
background: #050714;
border-radius: 20px;
padding: 32px;
color: #fff;
}
.text-flow-basic__viewport {
overflow: hidden;
border-radius: 16px;
padding: 32px 0;
}
.text-flow-basic__track {
display: flex;
width: max-content;
gap: 48px;
animation: marquee var(--flow-duration, 12s) linear infinite;
}
.text-flow-basic__track span {
font-size: clamp(26px, 4vw, 48px);
background: var(--flow-gradient);
-webkit-background-clip: text;
color: transparent;
white-space: nowrap;
}
.text-flow-basic__label {
display: flex;
gap: 12px;
align-items: center;
margin-top: 20px;
}
@keyframes marquee {
to {
transform: translateX(-50%);
}
}
import { useState } from "react";
import "./M-001.css";
export default function TextFlowBasic() {
const [speed, setSpeed] = useState(12);
const label = "Text Flow Basic · Vibe UI Pattern Library · ";
const dynamicStyle = { "--flow-duration": `${speed}s` };
return (
<section className="text-flow-basic" style={dynamicStyle}>
<div className="text-flow-basic__viewport">
<Track label={label} />
<Track label={label} aria-hidden="true" />
</div>
<label className="text-flow-basic__label">
<span>Speed (seconds)</span>
<input
type="range"
min="6"
max="20"
value={speed}
onChange={(event) => setSpeed(Number(event.target.value))}
/>
<output>{speed}s</output>
</label>
</section>
);
}
function Track({ label, ...rest }) {
return (
<div className="text-flow-basic__track" {...rest}>
<span>{label}</span>
<span>{label}</span>
</div>
);
}
:root {
--flow-gradient: linear-gradient(90deg, #7f5af0, #ffa7c4, #22d3ee);
}
.text-flow-basic {
background: #050714;
border-radius: 24px;
padding: clamp(20px, 5vw, 36px);
color: #fff;
display: flex;
flex-direction: column;
gap: 20px;
}
.text-flow-basic__viewport {
overflow: hidden;
border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.1);
padding: clamp(18px, 4vw, 32px) 0;
}
.text-flow-basic__track {
display: flex;
width: max-content;
gap: 48px;
animation: marquee var(--flow-duration, 12s) linear infinite;
}
.text-flow-basic__track span {
font-size: clamp(28px, 6vw, 54px);
font-weight: 600;
white-space: nowrap;
background: var(--flow-gradient);
-webkit-background-clip: text;
color: transparent;
}
.text-flow-basic__label {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
font-weight: 600;
}
.text-flow-basic__label input[type="range"] {
flex: 1;
min-width: 160px;
}
@keyframes marquee {
to {
transform: translateX(-50%);
}
}
@media (prefers-reduced-motion: reduce) {
.text-flow-basic__track {
animation-duration: calc(var(--flow-duration, 12s) * 2);
}
}
仕組みとカスタマイズHow It Works & Customization
仕組みHow it works
Two identical <div> elements containing the same text are placed side-by-side in a flex container (width: max-content). The marquee @keyframes animates translateX from 0 to -50%, creating a seamless loop as the second copy slides into view exactly when the first exits.
同一テキストを持つ2つの<div>をflexコンテナに横並びに配置(width: max-content)。marqueeアニメーションでtranslateXを0から-50%まで動かすことで、1つ目が画面外に出るタイミングで2つ目がちょうど入ってきるシームレスなループを実現します。
カスタマイズ方法Customization
Change --flow-duration to control speed (lower = faster). Swap the --flow-gradient value to match your brand colors. Adjust font-size, font-weight, or gap to reshape the visual rhythm. Add aria-hidden="true" to the duplicate track to suppress screen reader repetition.
--flow-durationでスピード調整(小さいほど速い)。--flow-gradientをブランドカラーに変更。font-size・font-weight・gapで視覚的リズムを調整。複製トラックにaria-hidden="true"を追加してスクリーンリーダーの重複読み上げを防止。
注意点Caveats
Add prefers-reduced-motion support to pause or slow the animation for motion-sensitive users. Ensure text color has sufficient contrast against the background when gradient is not applied as a fallback.
prefers-reduced-motionで動きに敏感なユーザー向けにアニメーションを停止・減速させてください。グラデーションが適用されない場合のフォールバックとして、テキスト色と背景のコントラストを確保してください。
よくある質問 Frequently Asked Questions
How to customize the text flow basic? Text Flow Basicをカスタマイズするには?
Modify the CSS custom properties and class styles defined in the code section. Key adjustable values include colors, sizes, durations, and spacing. See the Adjustable Parameters section for specific variables.
コードセクションで定義されているCSSカスタムプロパティとクラススタイルを変更してください。色、サイズ、時間、間隔が主な調整可能値です。具体的な変数は調整可能パラメータセクションを参照してください。
How to use the text flow basic in React? ReactでText Flow Basicを使うには?
Import the provided React component and its CSS file. The component accepts props for customization. Check the React code section for the full implementation and available props.
提供されているReactコンポーネントとCSSファイルをインポートしてください。コンポーネントのpropsでカスタマイズできます。完全な実装と利用可能なpropsはReactコードセクションを参照してください。
What are the performance implications of text flow basic? Text Flow Basicのパフォーマンスへの影響は?
This implementation uses CSS transforms and opacity for animations, which are GPU-accelerated. It's lightweight and doesn't cause layout thrashing. Consider using prefers-reduced-motion for accessibility.
この実装はCSSのtransformとopacityを使用しており、GPUアクセラレーションされます。軽量でレイアウトスラッシングを引き起こしません。アクセシビリティのためにprefers-reduced-motionの使用を検討してください。
AIへの指示テンプレート AI Prompt Template
以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.