A11yAdvent Day 7: Page Title in SPA

Single-page applications (SPA for short) have been all the hype for the last decade or so. The idea is that we can avoid reloading the entire page when navigating within a site and instead update only the moving parts (usually the content area). This comes from a great premise: faster interactions, no unnecessary HTTP roundtrips, less used bandwidth.

The thing we usually don’t think about is that many assistive technologies such as screen-readers have been initially authored with the “original web” in mind and rely on page (re)loads to announce the page context, namely the page title (hold by the element).

When building a SPA—no matter the framework—it is important to do some work to announce the title when following router links. Two things need to happen:

  1. The title of the new view/page needs to be announced.
  2. The focus needs to be preserved or moved to a proper place.

A nice solution is to have a visually hidden element at the top of the page which receives the new title when navigating, and move the focus on that element so the content is read. Ideally, the skip link lives right after that node so the flow goes like this:

  1. Press a link in the content area that causes a router change.
  2. The view gets loaded.
  3. The title for that view gets rendered in the invisible node.
  4. The focus gets move to that node so its content is announced.
  5. Tabbing once gets to the skip link, so getting back to the content area is fast and convenient.

Here is how our HTML should look like:

body>
p tabindex="-1" class="sr-only">p>
a href="#main" class="sr-only sr-only--focusable">Skip to contenta>

body>

And our unflavoured JavaScript. Note that this is no specific framework—it’s just a made-up API to illustrate the concept.

const titleHandler = document.querySelector('body > p')

router.on('page:change', ({ title }) => {
// Render the title of the new page in the


titleHandler.innerText = title
// Focus it—note that it *needs* `tabindex="-1"` to be focusable!
titleHandler.focus()
})

You can find a more in-depth tutorial for React with react-router and react-helmet on this blog. The core concept should be the same no matter the framework.

Note that if you have can guarantee there is always a relevant

element (independently of loading states, query errors and such), another possibly simpler solution would be to skip that hidden element altogether, and focus the

element instead (still with tabindex="-1").


This content originally appeared on Hugo “Kitty” Giraudel and was authored by Hugo “Kitty” Giraudel

Single-page applications (SPA for short) have been all the hype for the last decade or so. The idea is that we can avoid reloading the entire page when navigating within a site and instead update only the moving parts (usually the content area). This comes from a great premise: faster interactions, no unnecessary HTTP roundtrips, less used bandwidth.

The thing we usually don’t think about is that many assistive technologies such as screen-readers have been initially authored with the “original web” in mind and rely on page (re)loads to announce the page context, namely the page title (hold by the </code> element).</p> <p>When building a SPA—no matter the framework—it is important to do some work to announce the title when following router links. Two things need to happen:</p> <ol> <li>The title of the new view/page needs to be announced.</li> <li>The focus needs to be preserved or moved to a proper place.</li> </ol> <p>A nice solution is to have a <a href="https://hugogiraudel.com/2020/12/03/a11y-advent-hiding-content">visually hidden</a> element at the top of the page which receives the new title when navigating, and move the focus on that element so the content is read. Ideally, the <a href="https://hugogiraudel.com/2020/12/06/a11y-advent-skip-to-content">skip link</a> lives right after that node so the flow goes like this:</p> <ol> <li>Press a link in the content area that causes a router change.</li> <li>The view gets loaded.</li> <li>The title for that view gets rendered in the invisible node.</li> <li>The focus gets move to that node so its content is announced.</li> <li>Tabbing once gets to the skip link, so getting back to the content area is fast and convenient.</li> </ol> <p>Here is how our HTML should look like:</p> <pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">tabindex</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>-1<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sr-only<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>…<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#main<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sr-only sr-only--focusable<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Skip to content<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><br> <span class="token comment"><!-- Rest of the page --></span><br><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span></code></pre> <p>And our unflavoured JavaScript. Note that this is no specific framework—it’s just a made-up API to illustrate the concept.</p> <pre class="language-js"><code class="language-js"><span class="token keyword">const</span> titleHandler <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'body > p'</span><span class="token punctuation">)</span><br><br>router<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'page:change'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> title <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br> <span class="token comment">// Render the title of the new page in the <p></span><br> titleHandler<span class="token punctuation">.</span>innerText <span class="token operator">=</span> title<br> <span class="token comment">// Focus it—note that it *needs* `tabindex="-1"` to be focusable!</span><br> titleHandler<span class="token punctuation">.</span><span class="token function">focus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre> <p>You can find a more in-depth <a href="https://hugogiraudel.com/2020/01/15/accessible-title-in-a-single-page-react-application/">tutorial for React with <code>react-router</code> and <code>react-helmet</code></a> on this blog. The core concept should be the same no matter the framework.</p> <div class="Info"><p>Note that if you have can guarantee there is <strong>always</strong> a relevant <code><h1></code> element (independently of loading states, query errors and such), another possibly simpler solution would be to skip that hidden element altogether, and focus the <code><h1></code> element instead (still with <code>tabindex="-1"</code>).</p> </div> <p class="syndicated-attribution"><br>This content originally appeared on <a href="https://hugogiraudel.com/2020/12/07/a11y-advent-page-title-in-spa/" target="_blank">Hugo “Kitty” Giraudel</a> and was authored by Hugo “Kitty” Giraudel<br></p> <br> <style> .ap-print-btn-comment { display:none; } .single .ap-print-btn-comment { display:block; } #respond { visibility:hidden; } .entry-content .ap-print-btn { display:none!important; } .entry-content .singleshow .ap-print-btn { display:block!important; } /* #respond { display:none; } */ </style> <script> function showhidecommentbox() { var x = document.getElementById("respond"); if (x.style.visibility === "visible") { x.style.visibility = "hidden"; } else { x.style.visibility = "visible"; } /* if (x.style.display === "block") { x.style.display = "none"; } else { x.style.display = "block"; } */ } </script> <div class="singleshow"> <a href="?printer_app=1" class="ap-print-btn" style=" padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Print</a> <a onclick="pop()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Share</a> <a onclick="popcomment()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Comment</a> <a onclick="popcite()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Cite</a> <a onclick="popupload()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Upload</a> <a onclick="poptranslate()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Translate</a> <a onclick="popupdates()" class="ap-print-btn ap-print-btn-comment" style="cursor:pointer; padding: 15px; margin-top: 10px; width: 140px; text-align: center; border-radius: 3px; font-size: 14px; box-shadow: none !important; background-color: #e2f1f8; color: #3a7d8c;float:left; margin-right:10px;text-decoration: none;">Updates</a> <script> function pop() { var popup = document.getElementById('sharepopup'); popup.classList.toggle('show'); } function popcite() { var popup = document.getElementById('citationarea'); popup.classList.toggle('show'); } function popupload() { var popup = document.getElementById('uploadarea'); popup.classList.toggle('show'); } function popupdates() { var popup = document.getElementById('updatesarea'); popup.classList.toggle('show'); } function poptranslate() { var popup = document.getElementById('translatearea'); popup.classList.toggle('show'); } function popupdates() { var popup = document.getElementById('updatesarea'); popup.classList.toggle('show'); } function popcomment() { var popup = document.getElementById('commentarea'); popup.classList.toggle('show'); var x = document.getElementById("respond"); if (x.style.visibility === "visible") { x.style.visibility = "hidden"; } else { x.style.visibility = "visible"; } } </script> <style> .show{ display: grid !important; grid-template-columns: 70px auto; width: 100%; height: 100%; } #respond { margin-left: -40px; } .popup { display: inline-block; } .popup .popuptext { visibility: hidden; background-color: #e2f1f8; color: #fff; border-radius: 3px; padding:10px; position:relative; margin:10px 0; } .popuptext { background-color: #e2f1f8; color: #fff; border-radius: 3px; padding:10px; position:relative; margin:10px 0; } .popup { width: 100%; } .popup .show { visibility: visible; } #commentarea{ display: none; } #citationarea { display: none; } #commentarea .show{ display: inline !important; visibility: visible !important; background-color: #ffdb14; } #citationarea { display: none; } #citationarea .show { display: inline !important; visibility: visible !important; background-color: #ffdb14; } #uploadarea { display: none; } #uploadarea .show { display: inline !important; visibility: visible !important; background-color: #ffdb14; } #updatesarea { display: none; } #updatesarea .show { display: inline !important; visibility: visible !important; background-color: #ffdb14; } #translatearea { display: none; } #translatearea .show { display: inline !important; visibility: visible !important; background-color: #ffdb14; } .sharedashicons { color: white; text-decoration: none; padding: 5px 0; } #translatearea textarea { max-width: 580px; min-width: 100% !important; } .mediashareentry a { color: white; } .mediashareentry{ min-width: 400px; } #uploadarea { min-width: 400px !important; font-size: 1.4rem; } #file-form { min-width: 400px; } .singleshow { max-width: 600px; } .citationblock::selection { background: #ffdb14; /* WebKit/Blink Browsers */ color: #e2f1f8; } .citationblock::-moz-selection { background: #ffdb14; /* Gecko Browsers */ color: #000000; } b .citationblock::selection { background: #ffdb14; /* WebKit/Blink Browsers */ color: #000000; } b .citationblock::-moz-selection { background: #ffdb14; /* Gecko Browsers */ color: #000000; } #wp-content-wrap, #post_tags, #title, #post_image select, #post_image { margin-top: 33px; margin-bottom: 33px; } #async-upload { border: none !important; } #async-upload-wrap input { color: #3a7d8c; z-index: 999 !important; display: inherit; margin-top: 22px; border-color: ##3a7d8c; border: 1px solid; } #submit { color: #3a7d8c !important; } </style> <div class="popup"> <span class="popuptext" id="sharepopup"> <div class="sharelogo" id="emailsharelogo"><a href="mailto:info@example.com?&subject=A11yAdvent Day 7: Page Title in SPA&body=https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/"><span class="sharedashicons dashicons dashicons-email"></span></a></div> <div class="sharelogo" id="facebooksharelogo"><a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/"><span class="sharedashicons dashicons dashicons-facebook"></span></a></div> <div class="sharelogo" id="twittersharelogo"><a target="_blank" href="https://twitter.com/intent/tweet?url=https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/&text=A11yAdvent Day 7: Page Title in SPA"><span class="sharedashicons dashicons dashicons-twitter"></span></a></div> <div class="js-emailcopybtn sharelogo" id="urlsharelogo"><span class="sharedashicons dashicons dashicons-admin-links" onclick="setClipboard('https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/')"></span></div> <style> #sharepopup { display: flex; justify-content: center; /* Aligns icons in the center */ gap: 10px; /* Adjust the space between icons */ flex-wrap: nowrap; /* Prevents icons from wrapping to the next line */ } .sharing-icons a:hover { background-color: #ddd; } </style> <script> function setClipboard(value) { navigator.clipboard.writeText(value).then(function() { // You can replace this alert with a more subtle notification if preferred alert('Link copied to clipboard!'); }, function(err) { // Fallback for browsers where clipboard API is not available // Creating a temporary textarea element to use the older execCommand const textarea = document.createElement('textarea'); textarea.value = value; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); alert('Link copied to clipboard!'); }); } </script> </span> </div> <div class="commentpopup" style"width: 100%;"> <span class="" id="commentarea"> <img src="https://www.radiofree.org/wp-content/plugins/print-app/icon.jpg" width="100%"> <div class="comments-wrapper"> </div><!-- .comments-wrapper --> </span> </div> <div class="citationpopup" style"width: 100%;"> <span class="popuptext" id="citationarea"> <span class=“citestyle”>APA</span> <div class="citationblock" id="content-1"><p> Hugo “Kitty” Giraudel | Sciencx (2020-12-07T00:00:00+00:00) <i>A11yAdvent Day 7: Page Title in SPA</i>. Retrieved from <a href="https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/">https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/</a></div> <span class=“citestyle”>MLA</span><div class="citationblock" id="content-2">" » A11yAdvent Day 7: Page Title in SPA." Hugo “Kitty” Giraudel | Sciencx - Monday December 7, 2020, https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/</div> <span class=“citestyle”>HARVARD</span><div class="citationblock" id="content-3">Hugo “Kitty” Giraudel | Sciencx Monday December 7, 2020 » A11yAdvent Day 7: Page Title in SPA., viewed ,<https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/></div> <span class=“citestyle”>VANCOUVER</span><div class="citationblock" id="content-4">Hugo “Kitty” Giraudel | Sciencx - » A11yAdvent Day 7: Page Title in SPA. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/</div> <span class=“citestyle”>CHICAGO</span><div class="citationblock" id="content-5">" » A11yAdvent Day 7: Page Title in SPA." Hugo “Kitty” Giraudel | Sciencx - Accessed . https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/</div> <span class=“citestyle”>IEEE</span><div class="citationblock" id="content-6">" » A11yAdvent Day 7: Page Title in SPA." Hugo “Kitty” Giraudel | Sciencx [Online]. Available: https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/. [Accessed: ]</div> <span class=“citestyle”>rf:citation</span><div class="citationblock" id="content-7"> » A11yAdvent Day 7: Page Title in SPA | Hugo “Kitty” Giraudel | Sciencx | https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/ | </div> </span> </div> <div class="citationpopup" style="width: 100%;"> <span class="popuptext" id="uploadarea" style="width: 100%;"> <p>Please <a href="https://www.scien.cx/wp-login.php?redirect_to=https%3A%2F%2Fwww.scien.cx%2F2020%2F12%2F07%2Fa11yadvent-day-7-page-title-in-spa%2F">log in</a> to upload a file.</p> </span> </div> <div class="updatespopup" style="width: 100%;"> <span class="popuptext" id="updatesarea" style="width: 100%;"> <br><br><br> <span style="min-width:200px;font-size:17px; padding:30px;">There are no updates yet. <br>Click the Upload button above to add an update.</span> </span> </div> <style>#translationcontainer {padding: 22px;}</style><div class="translatepopup" style"width: 100%;padding:22px;"> <span class="popuptext" id="translatearea"> <container id="translationcontainer" class="translationcontainer"> <p>You must be logged in to translate posts. Please <a href="https://www.scien.cx/wp-login.php?redirect_to=https%3A%2F%2Fwww.scien.cx%2F2020%2F12%2F07%2Fa11yadvent-day-7-page-title-in-spa%2F">log in</a> or <a href="https://www.scien.cx/wp-login.php?action=register">register</a>.</p> </container> </span> </div> </div><!-- .entry-content --> <nav class="pagination-single border-color-border"> <a class="previous-post" href="https://www.scien.cx/2020/12/06/static-web-apps-on-devops-labs/"> <span class="arrow">←</span> <span class="title"><span class="title-inner">Static Web Apps on DevOps Labs</span></span> </a> <a class="next-post" href="https://www.scien.cx/2020/12/07/live-first-time-casual-hindi-talks/"> <span class="arrow">→</span> <span class="title"><span class="title-inner">Live First Time : Casual Hindi Talks</span></span> </a> </nav><!-- .single-pagination --> </div><!-- .post-inner --> </article><!-- .post --> <div class="related-posts section-inner"> <h2 class="related-posts-title heading-size-3">Related Posts</h2> <div class="posts"> <div class="posts-grid related-posts-grid grid mcols-1 tcols-2 tlcols-3 dcols-4"> <div class="grid-item"> <article class="preview preview-post post-275978 post type-post status-publish format-standard hentry" id="post-275978"> <figure class="preview-media"> <iframe width="100%" height="198" src="https://www.youtube.com/embed/cz2Gl4p_G8o" frameborder=\"0\" allowfullscreen></iframe> </figure> <figure class="preview-media"> </figure> <header class="preview-header"> <h2 class="preview-title heading-size-3"><a href="https://www.scien.cx/2021/10/22/lockdowns-to-end-in-new-zealand-when-90-fully-vaccinated/">Lockdowns to end in New Zealand when 90% fully vaccinated</a></h2> <div class="post-meta-wrapper post-meta-archive"> <ul class="post-meta color-accent"> <li class="post-date"> <a class="meta-wrapper" href="https://www.scien.cx/2021/10/22/lockdowns-to-end-in-new-zealand-when-90-fully-vaccinated/"> <span class="meta-icon"> <span class="screen-reader-text">Post date</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> October 22, 2021 </span> </a> </li> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post author</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> By <a href="https://www.scien.cx/author/al-jazeera-english/">Al Jazeera English</a> </span> </li> </ul> </div> </header><!-- .preview-header --> </article><!-- .preview --> </div><!-- .grid-item --> <div class="grid-item"> <article class="preview preview-post post-288650 post type-post status-publish format-standard hentry" id="post-288650"> <figure class="preview-media"> </figure> <figure class="preview-media"> </figure> <header class="preview-header"> <h2 class="preview-title heading-size-3"><a href="https://www.scien.cx/2021/11/08/bash-script-to-make-ecs-exec-aws-ecs-execute-command-useful/">Bash script to make ECS Exec (aws ecs execute-command) useful</a></h2> <div class="post-meta-wrapper post-meta-archive"> <ul class="post-meta color-accent"> <li class="post-date"> <a class="meta-wrapper" href="https://www.scien.cx/2021/11/08/bash-script-to-make-ecs-exec-aws-ecs-execute-command-useful/"> <span class="meta-icon"> <span class="screen-reader-text">Post date</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> November 8, 2021 </span> </a> </li> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post author</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> By <a href="https://www.scien.cx/author/yuki777/">yuki777</a> </span> </li> </ul> </div> </header><!-- .preview-header --> </article><!-- .preview --> </div><!-- .grid-item --> <div class="grid-item"> <article class="preview preview-post post-221083 post type-post status-publish format-standard hentry category-beginners category-go category-tutorial category-webdev" id="post-221083"> <figure class="preview-media"> <div class="owl-carousel owl-theme gal-item" id="owl-221083"> <div class="item" style="background-image: url('https://res.cloudinary.com/practicaldev/image/fetch/s--uWEPsu1G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/dj5iihhqv/image/upload/v1630186890/Kapture_2021-08-28_at_22.39.53-min_ex0qg2.gif')"><a href="https://www.scien.cx/2021/08/28/image-compression-with-golang/"></a></div> </div> <script> $('#owl-221083').owlCarousel({ loop:true, margin:10, nav:true, items: 1, }); </script> </figure> <figure class="preview-media"> </figure> <header class="preview-header"> <h2 class="preview-title heading-size-3"><a href="https://www.scien.cx/2021/08/28/image-compression-with-golang/">Image Compression with Golang</a></h2> <div class="post-meta-wrapper post-meta-archive"> <ul class="post-meta color-accent"> <li class="post-date"> <a class="meta-wrapper" href="https://www.scien.cx/2021/08/28/image-compression-with-golang/"> <span class="meta-icon"> <span class="screen-reader-text">Post date</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> August 28, 2021 </span> </a> </li> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post author</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> By <a href="https://www.scien.cx/author/francisco-mendes/">Francisco Mendes</a> </span> </li> <li class="post-categories meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post categories</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="20" height="19" viewBox="0 0 20 19"><path fill="" d="M2.8,1.85 C2.275329,1.85 1.85,2.27532949 1.85,2.8 L1.85,15.4 C1.85,15.9246705 2.275329,16.35 2.8,16.35 L17.2,16.35 C17.724671,16.35 18.15,15.9246705 18.15,15.4 L18.15,5.5 C18.15,4.97532949 17.724671,4.55 17.2,4.55 L9.1,4.55 C8.8158,4.55 8.550403,4.40796403 8.392757,4.17149517 L6.845094,1.85 L2.8,1.85 Z M17.2,2.85 C18.663555,2.85 19.85,4.03644541 19.85,5.5 L19.85,15.4 C19.85,16.8635546 18.663555,18.05 17.2,18.05 L2.8,18.05 C1.336445,18.05 0.15,16.8635546 0.15,15.4 L0.15,2.8 C0.15,1.33644541 1.336445,0.15 2.8,0.15 L7.3,0.15 C7.5842,0.15 7.849597,0.292035965 8.007243,0.528504833 L9.554906,2.85 L17.2,2.85 Z" /></svg> </span> <span class="meta-text"> In <a href="https://www.scien.cx/category/beginners/" rel="category tag">beginners</a>, <a href="https://www.scien.cx/category/go/" rel="category tag">go</a>, <a href="https://www.scien.cx/category/tutorial/" rel="category tag">tutorial</a>, <a href="https://www.scien.cx/category/webdev/" rel="category tag">webdev</a> </span> </li> </ul> </div> </header><!-- .preview-header --> </article><!-- .preview --> </div><!-- .grid-item --> <div class="grid-item"> <article class="preview preview-post post-83582 post type-post status-publish format-standard hentry category-innovation category-javascript category-programming category-software-development category-web-development" id="post-83582"> <figure class="preview-media"> <div class="owl-carousel owl-theme gal-item" id="owl-83582"> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/1024/1*uBSQ-Fbj5k4dqgWpveig0Q.png')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/1024/1*j4iUaH8PDDDckaooQovsZw.jpeg')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/972/1*9g22cdZjdXeaAZMMOIuYsw.png')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/1024/1*ooUBwsEX5RlXpM40bW4zKQ.jpeg')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/proxy/1*JLkB6aSk-U2VaotgidO2Vg.gif')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/1024/1*AWTs4UYl4QfnJrtHAkBl6Q.jpeg')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> <div class="item" style="background-image: url('https://cdn-images-1.medium.com/max/1024/1*lZRsTanAWuIEI3oTLsZalA.jpeg')"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"></a></div> </div> <script> $('#owl-83582').owlCarousel({ loop:true, margin:10, nav:true, items: 1, }); </script> </figure> <figure class="preview-media"> </figure> <header class="preview-header"> <h2 class="preview-title heading-size-3"><a href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/">4 Bit Use-Cases: Build Like the Best Teams</a></h2> <div class="post-meta-wrapper post-meta-archive"> <ul class="post-meta color-accent"> <li class="post-date"> <a class="meta-wrapper" href="https://www.scien.cx/2021/04/12/4-bit-use-cases-build-like-the-best-teams/"> <span class="meta-icon"> <span class="screen-reader-text">Post date</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> April 12, 2021 </span> </a> </li> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post author</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> By <a href="https://www.scien.cx/author/jonathan-saring/">Jonathan Saring</a> </span> </li> <li class="post-categories meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Post categories</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="20" height="19" viewBox="0 0 20 19"><path fill="" d="M2.8,1.85 C2.275329,1.85 1.85,2.27532949 1.85,2.8 L1.85,15.4 C1.85,15.9246705 2.275329,16.35 2.8,16.35 L17.2,16.35 C17.724671,16.35 18.15,15.9246705 18.15,15.4 L18.15,5.5 C18.15,4.97532949 17.724671,4.55 17.2,4.55 L9.1,4.55 C8.8158,4.55 8.550403,4.40796403 8.392757,4.17149517 L6.845094,1.85 L2.8,1.85 Z M17.2,2.85 C18.663555,2.85 19.85,4.03644541 19.85,5.5 L19.85,15.4 C19.85,16.8635546 18.663555,18.05 17.2,18.05 L2.8,18.05 C1.336445,18.05 0.15,16.8635546 0.15,15.4 L0.15,2.8 C0.15,1.33644541 1.336445,0.15 2.8,0.15 L7.3,0.15 C7.5842,0.15 7.849597,0.292035965 8.007243,0.528504833 L9.554906,2.85 L17.2,2.85 Z" /></svg> </span> <span class="meta-text"> In <a href="https://www.scien.cx/category/innovation/" rel="category tag">innovation</a>, <a href="https://www.scien.cx/category/javascript/" rel="category tag">JavaScript</a>, <a href="https://www.scien.cx/category/programming/" rel="category tag">programming</a>, <a href="https://www.scien.cx/category/software-development/" rel="category tag">software-development</a>, <a href="https://www.scien.cx/category/web-development/" rel="category tag">web-development</a> </span> </li> </ul> </div> </header><!-- .preview-header --> </article><!-- .preview --> </div><!-- .grid-item --> </div><!-- .posts-grid --> </div><!-- .posts --> </div><!-- .related-posts --> </main><!-- #site-content --> <script type="text/javascript"> jQuery(document).ready(function($){ // using jQuery if( $(document).find('.wp-block-video video').length ) { $(document).find('.wp-block-video video').mediaelementplayer(/* Options */); } if( $(document).find('.wp-block-audio audio').length ) { $(document).find('.wp-block-audio audio').mediaelementplayer(/* Options */); } //$(window).load(function(){ $('.wp-block-audio figcaption').each(function(){ var htm = $(this).html(); $(this).html('<div>' +htm+ '</div>'); }); //}); }); </script> <div class="wdg-bottom"></div> <footer id="site-footer" role="contentinfo"> <div class="footer-inner section-inner"> <!-- .footer-credits --> </div><!-- .footer-bottom --> </footer><!-- #site-footer --> <script type="text/javascript" defer src="https://www.scien.cx/wp-content/plugins/koko-analytics/assets/dist/js/script.js?ver=1.3.14" id="koko-analytics-js"></script> <script> var p_id = null; var p_link = null; var click = 1; jQuery(function(){ jQuery('li.menu-item-has-children > a:first-child').on('click',function(event){ event.preventDefault() var link = jQuery(this).attr('href'); var id = jQuery(this).parent().attr('id'); if(p_id == null){ p_id = id; p_link = link; jQuery(this).next('ul').toggle(300); if(click == 1){ click = 2 } } else if(p_id != id){ p_id = id; p_link = link; jQuery(this).next('ul').toggle(300); if(click == 1){ click = 2 } } else if(p_id == id){ if(click == 2){ console.log('go') window.location.href = link } } //Hide menu when clicked outside jQuery(this).next('ul').onclick(function(){ var thisUI = jQuery(this); jQuery('html').click(function(){ thisUI.hide(); jQuery('html').unbind('click'); }); }); }); }); </script> <script> jQuery('.myLinkToTop').click(function () { jQuery('html, body').animate({scrollTop:jQuery(document).height()}, 'slow'); return true; }); jQuery('.myMenuLink').click(function () { jQuery('html, body').animate({scrollTop:0}, 'slow'); return true; }); </script> <script> jQuery(".left-footer-menu .header-toggles").on("click",function(){ jQuery(".left-footer-menu .menu-modal.cover-modal").toggleClass("t_menu") }) jQuery(".left-footer-menu .menu-modal-toggles").on("click",function(){ jQuery(".left-footer-menu .menu-modal.cover-modal").removeClass("t_menu") }) // jQuery(".left-footer-menu .menu-item .sub-menu-toggle").on("click",function(){ // jQuery(this).toggleClass("active"); // jQuery(this).parent().parent().parent().find("ul.sub-menu").toggle() // }) /////////////////////////// //this hides images that do not load properly on the homepage $("img").error(function (){ $(this).hide(); // or $(this).css({'display','none'}); }); </script> </body> </html>