{"id":5281,"date":"2025-03-05T15:14:19","date_gmt":"2025-03-05T20:14:19","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=5281"},"modified":"2025-03-05T16:31:25","modified_gmt":"2025-03-05T21:31:25","slug":"movies-as-images","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/movies-as-images\/","title":{"rendered":"Movies as Images"},"content":{"rendered":"\n<p>Animated GIFs just suck for web performance, so don&#8217;t put them on websites. To <a href=\"https:\/\/calendar.perfplanet.com\/2017\/animated-gif-without-the-gif\/\">quote Colin Bendell<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Animated GIFs are terrible for web performance. They are HUGE in size, impact cellular data bills, require more CPU and memory,\u00a0cause repaints, and are battery killers.\u00a0<\/p>\n<\/blockquote>\n\n\n\n<p>So if you need that same <em>behavior<\/em> of automatically playing silent moving images, we&#8217;ve learned to do to use a <code>&lt;video><\/code> instead:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span> <span class=\"hljs-attr\">autoplay<\/span> <span class=\"hljs-attr\">loop<\/span> <span class=\"hljs-attr\">muted<\/span> <span class=\"hljs-attr\">inline<\/span> \n  <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/assets.codepen.io\/3\/fire-ring.mp4\"<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>That&#8217;s&#8230; <em>attribute soup<\/em>. But it works. Plus there is a very good chance the <code>.mp4<\/code> is <em>way<\/em> smaller in file size than the GIF would be.<\/p>\n\n\n\n<p class=\"learn-more\">My vote would be to always include <code>controls<\/code> as another attribute on there. Yes it adds some UI over the image, but that UI allows the user to hit a stop button, which is an accessibility feature and one I use often to stop forever-playing anyway. If you don&#8217;t, at least wire up some CSS or JavaScript that stops the playing on click.<\/p>\n\n\n\n<p>Since 2017, Safari has supported this alternate approach:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/assets.codepen.io\/3\/fire-ring.mp4\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\"<\/span> \/&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Just an <code>&lt;img><\/code> tag! No attributes to remember and get right, and it has the exact same behavior. <em>Except<\/em> the fact that there is no way to pause it, which is a bummer. <\/p>\n\n\n\n<p>There are various ways to ship MP4-as-img by falling back to other techniques. When I started writing this and testing things out I was all prepared to try those and be annoyed at non-Safari browsers for not supporting this idea. But I&#8217;ve changed my tune. The fact that the <code>&lt;video><\/code>-based technique works fine across browsers and has a clear path toward pausing the movement makes me feel like MP4-as-img is just a sub-part technique and probably shouldn&#8217;t be used at all.<\/p>\n\n\n\n<p>Examples:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_QwWvrqw\" src=\"\/\/codepen.io\/anon\/embed\/QwWvrqw?height=590&amp;theme-id=47434&amp;slug-hash=QwWvrqw&amp;default-tab=result\" height=\"590\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed QwWvrqw\" title=\"CodePen Embed QwWvrqw\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Safari made .mp4 file work in img tags in HTML back in 2017, but no other browser followed suite. Should they have? <\/p>\n","protected":false},"author":1,"featured_media":5286,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[133,70,193],"class_list":["post-5281","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-images","tag-performance","tag-video"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/03\/Movies-as-Images.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=5281"}],"version-history":[{"count":2,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5281\/revisions"}],"predecessor-version":[{"id":5285,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5281\/revisions\/5285"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/5286"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=5281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=5281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=5281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}