HTML https://monkeysatkeyboards.com/ en Optimizing images with CSS icon sprites https://monkeysatkeyboards.com/blog/optimizing-images-css-icon-sprites <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog-entry.html.twig x field--node--title.html.twig * field--node--blog-entry.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field--node--title.html.twig' --> <span class="field field--name-title field--type-string field--label-hidden">Optimizing images with CSS icon sprites</span> <!-- END OUTPUT from 'core/themes/classy/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog-entry.html.twig * field--node--body.html.twig * field--node--blog-entry.html.twig * field--body.html.twig x field--text-with-summary.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field--text-with-summary.html.twig' --> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'entity_embed_container' --> <!-- BEGIN OUTPUT from 'modules/contrib/entity_embed/templates/entity-embed-container.html.twig' --> <div data-embed-button="paragraphs" data-entity-label="Paragraphs" data-paragraph-id="8768ac79-e33a-407e-bb51-8c2a4900aa16" data-langcode="en" data-view-mode="embed" data-entity-embed-display="entity_reference:entity_reference_entity_view" data-entity-embed-display-settings="{&quot;view_mode&quot;:&quot;embed&quot;}" data-entity-type="embedded_paragraphs" data-entity-uuid="8768ac79-e33a-407e-bb51-8c2a4900aa16" class="embedded-entity"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--embedded-paragraphs--paragraph--embedded-paragraphs.html.twig * field--embedded-paragraphs--paragraph.html.twig * field--embedded-paragraphs--embedded-paragraphs.html.twig * field--paragraph.html.twig * field--entity-reference-revisions.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> <div class="field field--name-paragraph field--type-entity-reference-revisions field--label-hidden field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'paragraph' --> <!-- FILE NAME SUGGESTIONS: * paragraph--paragraph-embed--embed.html.twig * paragraph--paragraph-embed.html.twig * paragraph--embed.html.twig x paragraph.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/makv3/templates/paragraph.html.twig' --> <div class="parallax-wrapper"> <div class="parallax-base" style="background-image:url(/sites/default/files/2020-06/CSS-sprite-monkeys-at-keyboards-blackbg.png);field_parallax_extra_styles"> <div class="parallax-content-wrapper" style="min-height:375px;"> </div> </div> <figcaption></figcaption></div> <div class="paragraph paragraph--type--paragraph-embed paragraph--view-mode--embed" style="background-color:#e8f0f5;opacity:1;field_parallax_extra_styles"> </div> <!-- END OUTPUT from 'themes/custom/makv3/templates/paragraph.html.twig' --> </div> <!-- END OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> </div> <!-- END OUTPUT from 'modules/contrib/entity_embed/templates/entity-embed-container.html.twig' --> <figcaption> </figcaption><h2>Choosing the right icons</h2> <p>There are many choices for icons available in 2020. We can easily incorporate icons from <a href="https://fontawesome.com/">FontAwesome</a>, <a href="https://material.io/resources/icons/?style=baseline">Material UI</a> and other <a href="https://reactjs.org/">React</a> based user interfaces. We should always reach for these first when it is an option. Often, however, we want to customize things for our clients. For these cases we use CSS icon "sprites".</p> <p>We want to take advantage of the idea of loading multiple resources while minimizing network traffic to do it, similar to how there are multiple graphics in one FontAwesome font file. Fortunately, modern CSS makes this very easy, if perhaps a little bit verbose. We borrow a term from game development here, and we'll call the resulting <span class="wpseo-score-text">CSS icon</span> a "sprite". Our sprites will have multiple states for hovering and clicking or touching, and we will include all images and states in one file.</p> <h2><img alt="CSS icon grid" data-entity-type="file" data-entity-uuid="57a876df-4fb8-4154-8504-84d5e15ed72e" height="212" src="/sites/default/files/inline-images/CSS-sprite-grid-lines-monkeys-at-keyboards.png" width="281" class="align-left" loading="lazy" />Preparation</h2> <p>What we need to do first is very straightforward. Make a regular shaped grid in a graphics file and pack multiple icon images into each square of the grid. The resulting file can be loaded in one request by the browser, and then cached for subsequent page visits. We chose SVG format for our client <a href="https://monacaron.com/">Mona Caron</a>, since the resulting file size came out smallest when compared against PNG or JPEG. The Adobe Illustrator template attached to this post is arranged for square 50x50 graphics, but there is no requirement here that the icons be square. A tall or wide shape is fine, as long as it is consistent for the entire grid.</p> <h2>CSS code</h2> <p>Once we have the graphics grid, the following CSS ties everything together.</p> <p><code>.icon {<br />   display: inline-block;<br />   overflow: hidden;<br />   background-image: url(</code><code>/path/to/sprites.svg);<br />   background-repeat: none;<br />   text-indent: 10000px;</code><br /><code>  width: 50px;<br />   height: 50px;<br /> }<br /><br /> .icon.facebook { background-position: -100px 0; }<br /> .icon.facebook:hover { background-position: -100px -50px; }<br /> .icon.facebook:active { background-position: -100px -100px; }<br /> /* ... repeated for each sprite ... */</code></p> <p>The positions in the grid are encoded into the <code>background-position </code>CSS property. The values are negative because we are shifting the image up and left from the (0, 0) origin. A <code>background-position</code> value of 0 0 would show the icon in the upper left corner of the grid image.</p> <h2>HTML code</h2> <p>Now to include this in our HTML we can write.</p> <p>&lt;i class="icon facebook"&gt;&lt;/i&gt;</p> <p>This will add a 50x50 Facebook icon to our page with hover and click states.</p> <h2>CSS icon results in practice</h2> <p>We have reduced the number of server connections here from twelve to one, a 91.6% reduction of traffic.</p> <p>This can translate to a significant significant time savings for people with limited bandwidth or on mobile devices.</p> <div class="callout icon comment">Let's discuss:  <a href="https://join.slack.com/t/monkeysatkeyboards/shared_invite/zt-f2gedl1y-3yWEJgUH939nhvoEgveOZA">Slack</a>,  <a href="https://www.facebook.com/MonkeysAtKeyboards">Facebook</a>, or  <a href="https://twitter.com/Monkey_Keyboard">Twitter</a>.</div> <div> </div> </div> <!-- END OUTPUT from 'core/themes/classy/templates/field/field--text-with-summary.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog-entry.html.twig x field--node--uid.html.twig * field--node--blog-entry.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field--node--uid.html.twig' --> <span class="field field--name-uid field--type-entity-reference field--label-hidden"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/user/username.html.twig' --> <a title="View user profile." href="/users/fletch" lang="" about="/users/fletch" typeof="schema:Person" property="schema:name" datatype="" class="username">Fletch</a> <!-- END OUTPUT from 'core/themes/classy/templates/user/username.html.twig' --> </span> <!-- END OUTPUT from 'core/themes/classy/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog-entry.html.twig x field--node--created.html.twig * field--node--blog-entry.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field--node--created.html.twig' --> <span class="field field--name-created field--type-created field--label-hidden">Tue, 06/23/2020 - 12:27</span> <!-- END OUTPUT from 'core/themes/classy/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-attach--blog-entry.html.twig * field--node--field-attach.html.twig * field--node--blog-entry.html.twig * field--field-attach.html.twig * field--file.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> <div class="field field--name-field-attach field--type-file field--label-above"> <div class="field__label">Attached files</div> <div class="field__items"> <div class="field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'file_link' --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/file-link.html.twig' --> <span class="file file--mime-application-octet-stream file--general"> <a href="/sites/default/files/CSS-sprite-grid-50-pixels-square-monkeys-at-keyboards.ait" type="application/octet-stream">CSS-sprite-grid-50-pixels-square-monkeys-at-keyboards.ait</a></span> <!-- END OUTPUT from 'core/themes/classy/templates/field/file-link.html.twig' --> </div> </div> </div> <!-- END OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog-entry.html.twig * field--node--field-tags.html.twig * field--node--blog-entry.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> <div class="field field--name-field-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><a href="/taxonomy/term/96" hreflang="en">CSS</a></div> <div class="field__item"><a href="/taxonomy/term/97" hreflang="en">CSS icon</a></div> <div class="field__item"><a href="/taxonomy/term/98" hreflang="en">HTML</a></div> <div class="field__item"><a href="/taxonomy/term/95" hreflang="en">Web content</a></div> </div> <!-- END OUTPUT from 'core/themes/classy/templates/field/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: x links--node.html.twig x links--node.html.twig * links.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/classy/templates/content/links--node.html.twig' --> <!-- END OUTPUT from 'core/themes/classy/templates/content/links--node.html.twig' --> Tue, 23 Jun 2020 19:27:20 +0000 Fletch 397 at https://monkeysatkeyboards.com