A tram drawn with CSS
| The tram | |
| HTML | |
| The body | |
| The pantographs | |
| The movement |
The tram
A tram that rides back and forth under its wire, drawn with HTML blocks and CSS only, no pictures:
HTML
Every part is an empty div; the CSS gives it size, colour and place:
<div class="tram-scene"> <div class="wire"></div> <div class="tram"> <div class="pantograph left"></div> <div class="pantograph right"></div> <div class="top"> <div class="window" style="left:2%"></div> … six more windows … </div> <div class="bottom"><div class="ad">Your ad here</div></div> <div class="wheels"></div> </div> </div>
The body
The tram is position: absolute inside the scene, and its parts are absolute inside the tram, counted from its bottom: the wheels at 0, the green part at 30px, the yellow part with the windows at 80px. Percentages keep the windows in place whatever the width:
.tram { position: absolute; top: 60px; width: 20%; height: 180px; } .top { position: absolute; bottom: 80px; width: 100%; height: 50px; background: yellow; border-radius: 10px 10px 0 0; } .window { position: absolute; top: 10%; height: 80%; width: 11%; background: blue; border-radius: 5px; } .bottom { position: absolute; bottom: 30px; width: 100%; height: 50px; background: green; } .wheels { position: absolute; bottom: 0; width: 100%; height: 30px; background: #e8c60b; }
The pantographs
Each pantograph is a diamond: a triangle pointing up from the bottom border, and a triangle pointing down from the top border of its ::after. How border triangles work is in CSS test: shapes.
.pantograph { position: absolute; top: 0; width: 0; height: 0; border: 25px solid transparent; border-bottom-color: #000; border-top: 0; } .pantograph::after { content: ""; position: absolute; left: -25px; top: 25px; width: 0; height: 0; border: 25px solid transparent; border-top-color: #000; border-bottom: 0; }
The movement
A keyframes animation moves the tram from the left edge to 80% and back in 50 seconds. linear keeps the speed even; the original version of this drawing listed a thousand keyframes for the same result. For visitors who asked their system for less motion the tram stands still:
.tram { animation: tram-move 50s linear infinite; } @keyframes tram-move { 0% { left: 0; } 50% { left: 80%; } 100% { left: 0; } } @media (prefers-reduced-motion: reduce) { .tram { animation: none; } }
Article authors: Andrei Olegovich, Klavdiya Kondakova