This article introduces you to the article about how to use pure CSS to achieve the train is moving, there is a good reference value, I hope to help the needy friends.
Effect Preview
Code interpretation
Defines the DOM, which contains 2 elements, train
represents a train, track
represents a railroad track, and contains 3 <span>
representing 3 sleepers.
<p class= "Loader" > <p class= "Train" ></p> <p class= "track" > <span></ span> <span></span> <span></span> </p></p>
Center display:
body{ margin:0; HEIGHT:100VH; Display:flex; Align-items:center; Justify-content:center; Background:linear-gradient (#666, #333);}
Define Container Dimensions:
. loader { width:8em; Height:10em; font-size:20px;}
Draw the train first.
Draw the outline of a train:
. train { width:6em; Height:6em; Color: #444; Background: #bbb4ab; Border-radius:1em; position:relative; Left:1em;}
Use:: Before pseudo-elements to draw the window:
. train::before { content: '; Position:absolute; width:80%; Height:2.3em; Background-color:currentcolor; Border-radius:0.4em; Top:1.2em; left:10%;}
Re-use:: After pseudo-elements draw the lights on the window:
. train::after { content: '; Position:absolute; width:25%; Height:0.4em; Background-color:currentcolor; Border-radius:0.3em; Top:0.4em; Left:calc ((100%-25%)/2);}
Draw the headlights with a radial gradient:
. Train { background: radial-gradient (circle at 20% 80%, CurrentColor 0.6em, Transparent 0.6em), Radial-gradient (circle at 80% 80%, CurrentColor 0.6em, Transparent 0.6em), #bbb;}
Next, draw rails and sleepers.
Defines the width of the rails, slightly wider than the train:
. track { width:8em;}
To draw a railroad track with pseudo-elements:
. track { position:relative;}. Track::before,.track::after { content: '; Position:absolute; Width:0.3em; Height:4em; Background-color: #bbb; Border-radius:0.4em;}
Place the rails on both sides and form near-large, small visual effects:
. track::before,.track::after { transform-origin:bottom;}. Track::before { left:0; Transform:skewx ( -27deg);}. track::after { right:0; Transform:skewx (27deg);}
Draw the sleepers, which are the closest effect to the observer, the current 3 sleepers are overlapping:
. Track span { width:inherit; Height:0.3em; Background-color: #bbb; Position:absolute; Top:4em;}
Animate the Rails:
. Track span { animation:track-animate 1s linear infinite;} @keyframes track-animate { 0% { transform:translatey ( -0.5em) ScaleX (0.9); Filter:opacity (0); } 10%, 90% { filter:opacity (1); } 100% { Transform:translatey ( -4em) ScaleX (0.5); Filter:opacity (0);} }
Set the animation delay for the other 2 sleepers so that the rails look like they never go through:
. Track Span:nth-child (2) { animation-delay: -0.33s;}. Track Span:nth-child (3) { animation-delay: -0.66s;}
Finally, add animation to the train, which looks like a slight wobble on the road:
. Train { animation:train-animate 1.5s infinite Ease-in-out;} @keyframes Train-animate { 0, 100% { transform:rotate (0deg); } 25%, 75% { transform:rotate (0.5deg); } 50% { transform:rotate ( -0.5deg); }}
Done!