# entry

guid: https://christitus.com/windows-inside-linux/
title: Setting up Windows inside Linux
link: https://christitus.com/windows-inside-linux/
hash: ��n69!�;�;P�3
attributes: {"enclosures":[]}
content:
<p>Running Windows inside of Linux is essential for those that are trying to convert to Linux. There will always be a transition period and need to fallback to Windows. It is also nice to have for many Windows only programs that you may need while inside Linux.</p>
<p>If you haven’t ever installed QEMU before, here is an article to get that setup @ <a href="https://christitus.com/vm-setup-in-linux/">https://christitus.com/vm-setup-in-linux/</a></p>
<h2 data-sanitized-id="optimizing-windows-vm">Optimizing Windows VM</h2>
<p>First you need to install the VirtIO tools, which can be difficult to track down. My favorite way is to run the exe file from <a href="https://github.com/virtio-win/virtio-win-pkg-scripts">https://github.com/virtio-win/virtio-win-pkg-scripts</a> but many guides use the iso file also provided at this link.</p>
<p>Another good resource for obtaining VirtIO drivers is from the proxmox wiki <a href="https://pve.proxmox.com/wiki/Windows_VirtIO_Drivers">https://pve.proxmox.com/wiki/Windows_VirtIO_Drivers</a></p>
<h3 data-sanitized-id="enable-qemu-guest-agent">Enable QEMU Guest Agent</h3>
<p>Now you need to modify the VM to make use of the guest agent drivers. We need to add the qemu agent channel. Add Hardware -&gt; Channel and copy these settings</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/qemu/guest-agent.webp" alt="guest-agent" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="passing-devices-through">Passing Devices Through</h2>
<p>There are two main devices that you may want to pass through to a Windows VM. Hard Drives and Graphics Cards. Passing through a hard drive will give a good uplift in processing power and general VM response. The graphics card is very technical and frankly not recommended, but can be doable on some systems.</p>
<h3 data-sanitized-id="dedicated-hard-drive">Dedicated Hard Drive</h3>
<p>Simply select Add Hardware -&gt; Storage and copy these settings</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/qemu/hdd.webp" alt="hdd" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="dedicated-graphics-card">Dedicated Graphics Card</h3>
<p>This is referred to as PCI Passthrough and can be dicey on some systems. I’ve had some motherboards that can’t do this and others that can. The best guide and scripts I’ve found are from HikariKnight and his GitHub @ <a href="https://github.com/HikariKnight/quickpassthrough">https://github.com/HikariKnight/quickpassthrough</a></p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/6KqqNsnkDlQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/clickpaste/
title: ClickPaste the Best Program You Never Heard Of
link: https://christitus.com/clickpaste/
hash: ����=����)?3
attributes: {"enclosures":[]}
content:
<p>This program is free and open source, while being absolutely a life saver. I use it for VNC sessions and when dealing with VMs through my host computer.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">No more typing crap out when I use VNC or VM Sessions on the Host. Thanks ClickPaste (Free and Open Source)<br><br>GitHub Link: &lt;<a href="https://t.co/S3M69kQF3s">https://t.co/S3M69kQF3s</a>&gt;</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1572985183594242048?ref_src=twsrc%5Etfw">September 22, 2022</a></blockquote>

<p>GitHub Link: <a href="https://github.com/Collective-Software/ClickPaste">https://github.com/Collective-Software/ClickPaste</a></p>
<h2 data-sanitized-id="install">Install</h2>
<p>Simply extract the zip file from <a href="https://github.com/Collective-Software/ClickPaste/releases">https://github.com/Collective-Software/ClickPaste/releases</a> and run ClickPaste.exe</p>
<h3 data-sanitized-id="running-at-startup">Running at Startup</h3>
<p>The best way I’ve found is to create a shortcut to ClickPaste.exe then drag&amp;drop that into shell:startup</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/startup.webp" alt="startup" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="usage">Usage</h2>
<p>First of course, you need to have some text in your clipboard. Then:</p>
<ol>
<li>Click the target notification icon to begin:</li>
</ol>
<p><a href="https://github.com/Collective-Software/ClickPaste/blob/master/doc/ClickToTarget.webp"><img loading="lazy" src="https://github.com/Collective-Software/ClickPaste/raw/master/doc/ClickToTarget.webp" alt="Click to choose a target" data-sanitized-class="img-fluid"> </a></p>
<ol start="2">
<li>Click to choose a location you want to paste the text:</li>
</ol>
<p><a href="https://github.com/Collective-Software/ClickPaste/blob/master/doc/ClickToPaste.webp"><img loading="lazy" src="https://github.com/Collective-Software/ClickPaste/raw/master/doc/ClickToPaste.webp" alt="Click to choose a location to paste" data-sanitized-class="img-fluid"> </a></p>
<ol start="3">
<li>Your clipboard contents should be typed as keystrokes onto the window you selected:</li>
</ol>
<p><a href="https://github.com/Collective-Software/ClickPaste/blob/master/doc/Pasted.webp"><img loading="lazy" src="https://github.com/Collective-Software/ClickPaste/raw/master/doc/Pasted.webp" alt="Your clipboard is typed as keystrokes onto the window you selected" data-sanitized-class="img-fluid"> </a></p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/i7cgD_KCh10?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/be-a-better-programmer/
title: Be a Better Programmer
link: https://christitus.com/be-a-better-programmer/
hash: �W������g2a�����
attributes: {"enclosures":[]}
content:
<p>Many people want to be a programmer, but often find themselves flailing around in the dark. These are the things I’ve done to help aid myself in coding more, learning new things, and just becoming a better programmer.</p>
<h2 data-sanitized-id="use-github-daily">Use GitHub DAILY!</h2>
<p>Ok, maybe you don’t have to use GitHub specifically but choose a platform or host your own git and use it as much as you can. Finish a feature or part of a project… COMMIT IT! This makes it very easy when you leave and come back to the project.</p>
<p>Collaborators can find your project and contribute or even fix errors you have made, which helps you improve quickly.</p>
<h2 data-sanitized-id="track-your-progress">Track Your Progress</h2>
<p>I’m constantly bouncing around and when I started I was getting discouraged. I’d start a project, move on or get busy, and not look at it again or even code for weeks!</p>
<p>To fix this, I ended up using a free tool called wakatime. This showed me what projects I was spending time on, editors I used, languages, and spit it all out on a dashboard.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/wakatime.webp" alt="wakatime" data-sanitized-class="img-fluid"> </p>
<p>Check out my GitHub page @ <a href="https://github.com/christitustech">https://github.com/christitustech</a> for all my stats and share yours down below in the comments! I am extremely competitive and I code more knowing I have people watching my progress.</p>
<p><em>Note: As a bonus, check out my hidden profile readme @ <a href="https://github.com/christitustech/christitustech">https://github.com/christitustech/christitustech</a> and steal my auto generated setup!</em></p>
<h2 data-sanitized-id="setup-your-ideal-workflow">Setup Your Ideal Workflow</h2>
<p>You have to like your work or at least enjoy parts of it. I follow this phrase and make sure I find something I do daily that I enjoy.</p>
<blockquote>
<p>“Focus on the Journey, not the destination. Joy is not found in finishing an activity, but doing it!” - Greg Anderson</p>
</blockquote>
<p>It’s not to say that you will enjoy everything, because on the flip side of that phrase I made my own.</p>
<blockquote>
<p>“You have to shovel a little shit in every job” - Chris Titus</p>
</blockquote>
<p>The point being is there will be things you will hate, but just make sure it’s not all bad. For example, I love VIM as it makes me just feel cool even though sometimes I am slower than if I just used VSCODE with the proper extension. The reason I do this is because of two reasons:</p>
<ol>
<li>Eventually I will optimize VIM enough that I’m faster than VSCODE</li>
<li>I just feel awesome typing and coding in VIM</li>
</ol>
<p>This isn’t a advertisement for you to use VIM! In fact, I’d recommend you NOT use VIM unless these things interest you and you want to go down that rabbit hole. It depends on you!</p>
<p>Focus on what works for you and what you enjoy as far as an environment. This is more about how you <em>FEEL</em> than practical application. The better you feel in your workflow, the better your work product!</p>
<h2 data-sanitized-id="set-goals">Set Goals</h2>
<p>If you are going to improve in anything you need to have a goal. For me it is all about putting in the time consistently. That is true with everything in life that you go to learn. <strong>MORE TIME = BETTER RESULTS</strong></p>
<p>Example Goals:</p>
<ul>
<li>3 hours of coding per day</li>
<li>500 Git Contributions in 2022</li>
</ul>
<p>Once you set these goals look at how you are doing. I recommend both short term and long term goals like I listed above.</p>
<p>Now, go code!</p>


guid: https://christitus.com/macos-on-linux/
title: Macos on Linux
link: https://christitus.com/macos-on-linux/
hash: S�R |AP��-�KB
attributes: {"enclosures":[]}
content:
<p>This shows you all the steps to install a MacOS VM in Linux QEMU using Virtual Machine Manager or virt-manager.</p>
<p>Newer Source, but not as polished: <a href="https://github.com/kholia/OSX-KVM">https://github.com/kholia/OSX-KVM</a>
Mac KVM Repository: <a href="https://github.com/foxlet/macOS-Simple-KVM">https://github.com/foxlet/macOS-Simple-KVM</a></p>
<h2 data-sanitized-id="requirements">Requirements</h2>
<ul>
<li>A modern Linux distribution. E.g. Ubuntu 20.04 LTS 64-bit or later.</li>
<li>QEMU &gt;= 4.2.0</li>
<li>A CPU with Intel VT-x / AMD SVM support is required (<code>grep -e vmx -e svm /proc/cpuinfo</code>)</li>
</ul>
<h2 data-sanitized-id="installation-preparation">Installation Preparation</h2>
<p>Install QEMU and modify your user using <a href="https://christitus.com/vm-setup-in-linux">https://christitus.com/vm-setup-in-linux</a> Guide.</p>
<p>Clone this repository on your QEMU system. Files from this repository are used in the following steps.</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">cd ~
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">git clone --depth 1 --recursive https://github.com/foxlet/macOS-Simple-KVM
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">cd macOS-Simple-KVM
</span></span></code></pre></div><h2 data-sanitized-id="installation-media">Installation Media</h2>
<p>This downloads our installation media and I’d recommend using Catalina for compatibility and performance.</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">./jumpstart.sh --catalina
</span></span></code></pre></div><p><em>Note: Modern NVIDIA GPUs are supported on HighSierra but not on later
versions of macOS. Recommended PCI Passthrough GPU is 5700XT as this works on Catalina and above. If you go with a 6000 Series Card only certain ones will work on Big Sur and Monterey, but not earlier releases.</em></p>
<h2 data-sanitized-id="virtual-machine-setup">Virtual Machine Setup</h2>
<p>I recommend using Virtual Machine Manager (virt-manager) as it has a fantastic interface and Simple-KVM does a great job with their setup script. Simply type the following to get the macOS VM setup:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">sudo ./make.sh --add
</span></span></code></pre></div><h3 data-sanitized-id="vm-modification">VM Modification</h3>
<p>Before we can start out VM we have to have a hard drive to load it. You have two options: physical hard drive passthrough or qcow2 file.</p>
<p>Obviously, the physical drive is considerably faster, but not possible in some instances such as laptops or if you can’t afford a secondary drive.</p>
<h4 data-sanitized-id="physical-hard-drive-passthrough">Physical Hard Drive Passthrough</h4>
<p>This is pretty simple as you just click Add Hardware -&gt; Storage and then specify your hard drive.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/qemu/hdd.webp" alt="hdd" data-sanitized-class="img-fluid"> </p>
<p><em>Note: while you can use drive short names <code>/dev/sda</code> I’d recommend using <code>/dev/disk/by-id/HARDDRIVESERIAL</code> as this doesn’t ever change.</em></p>
<h4 data-sanitized-id="qcow2-file-for-hard-drive">QCOW2 File for Hard Drive</h4>
<p>This is even simpler as you just click Add Hardware -&gt; Storage and create new file. Just make sure you put it on at least a SSD or a nvme drive as it will be super slow if you don’t.</p>
<h2 data-sanitized-id="install-process">Install Process</h2>
<p>Boot your machine and select the OS Install Partition on startup.</p>
<p>Use the <code>Disk Utility</code> tool within the macOS installer to partition, and
format the virtual disk attached to the macOS VM.</p>
<p><strong>TIP: Using a non-APFS filesystem is recommended.</strong></p>
<p>Go ahead, and install macOS</p>
<h3 data-sanitized-id="post-installation">Post-Installation</h3>
<h4 data-sanitized-id="bridge-networking">Bridge Networking</h4>
<p><em>First</em> find your card interface name</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">ip a
</span></span></code></pre></div><p>Example: (Interface name is enp7s0)</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> inet 127.0.0.1/8 scope host lo
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> valid_lft forever preferred_lft forever
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> inet6 ::1/128 scope host
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> valid_lft forever preferred_lft forever
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">2: enp7s0: &lt;NO-CARRIER,BROADCAST,MULTICAST,UP&gt; mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> link/ether 24:bb:ee:55:22:33 brd ff:ff:ff:ff:ff:ff
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> inet 10.0.0.99/24 brd 10.0.0.255 scope global
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> valid_lft forever preferred_lft forever
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> inet6 ::1/128 scope host
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> valid_lft forever preferred_lft forever
</span></span></code></pre></div><p><em>Second</em> Update <code>/etc/network/interfaces</code></p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">source /etc/network/interfaces.d/*
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> 
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># The loopback network interface
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">auto lo
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">iface lo inet loopback
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># The primary network interface - old entry
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># allow-hotplug enp7s0
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># iface enp7s0 inet dhcp
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># The primary network interface - new entry
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># DEVICENAME = enp7so for this pc and MYUSERNAME need to be $(whoami)
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">auto br0
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">iface br0 inet dhcp
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> bridge_ports DEVICENAME tap0
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">auto tap0
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">iface tap0 inet dhcp
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> pre-up tunctl -u MYUSERNAME -t tap0
</span></span></code></pre></div><p><em>Lastly</em> Restart the networking service or reboot computer. Then change your VM NIC (Network Hardware) to <code>br0</code> interface.</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">sudo systemctl restart networking
</span></span></code></pre></div><h4 data-sanitized-id="other-considerations">Other Considerations</h4>
<ul>
<li>GPU Passthrough (Requires two Graphics Cards) - <a href="https://github.com/foxlet/macOS-Simple-KVM/blob/master/docs/guide-passthrough.md">https://github.com/foxlet/macOS-Simple-KVM/blob/master/docs/guide-passthrough.md</a></li>
<li>Changing Screen Resolution - <a href="https://github.com/foxlet/macOS-Simple-KVM/blob/master/docs/guide-screen-resolution.md">https://github.com/foxlet/macOS-Simple-KVM/blob/master/docs/guide-screen-resolution.md</a></li>
<li>Optimizing System Performance - <a href="https://github.com/sickcodes/osx-optimizer">https://github.com/sickcodes/osx-optimizer</a></li>
<li>Sound - Two methods, Pass the audio through HDMI if using GPU Passthrough OR Pass through a USB sound card that is macOS compatible
<ul>
<li><em>Note: There is a way to use Voodoo kext or AppleALC, but it will crackle and sound terrible</em></li>
</ul>
</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/dMLNP6FfhkI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/ntlite-guide/
title: NTLite Guide
link: https://christitus.com/ntlite-guide/
hash: /v�0�C��72��5�
attributes: {"enclosures":[]}
content:
<p>This Guide shows you the easiest way to configure Windows and make an ISO with NTLite.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/ntlite/ntlite.webp" alt="ntlite" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="overview">Overview</h2>
<p>NTLite is the best program for making an ISO for a Windows Environment. You have every option you could need, but is often overwhelming for new users. It’s why when you pull up NTLite Guide on YouTube you get 30+ Minute long videos.</p>
<p>These options are great for IT Professionals, but for a normal user it is too much and most normal users just end up with a broken Windows install ISO.</p>
<p>That is where import existing profiles that have already been tested by the NTLite community comes into play. You simply unpack the official ISO, apply the profile, and make your custom ISO!</p>
<h2 data-sanitized-id="prerequisites">Prerequisites</h2>
<ul>
<li>NTLite costs $40 for a home user and is worth every penny in my opinion. Download and buy from their website <a href="https://ntlite.com/">https://ntlite.com</a></li>
<li>Download the presets to import from my GitHub Repository <a href="https://github.com/ChrisTitusTech/ntlite-configs">https://github.com/ChrisTitusTech/ntlite-configs</a> - Credit for it’s creation goes to Txmmy from NTLite forums. I’m using GitHub to maintain and update it based on user requests.</li>
<li>Install 7zip to extract files from Windows ISO - Windows Terminal install with <code>winget install --id=7zip.7zip -e</code></li>
<li>Download the official Windows ISO <a href="https://www.microsoft.com/en-us/software-download/windows10">https://www.microsoft.com/en-us/software-download/windows10</a></li>
</ul>
<p><img loading="lazy" src="https://christitus.com/images/2022/ntlite/download-iso.webp" alt="ms-download" data-sanitized-class="img-fluid"> </p>
<p><em>Note: In windows it will default to “Media Creation Tool” to make the iso (see above) You can use Mac/Linux to direct download ISO or User Agent Switch Browser Extension to trick Microsoft</em></p>
<h2 data-sanitized-id="the-setup">The Setup</h2>
<p>These are the following steps for the NTLite to make a proper ISO. Extract the Official ISO, Add ISO Files, Load Files, Apply Imported XML Profile, Save New ISO!</p>
<h3 data-sanitized-id="extract-windows-iso-file">Extract Windows ISO File</h3>
<p>Right click your <code>windows.iso</code> file and select the “extract files”. <em>If you don’t see the extract files in the context menu then you did NOT install 7zip OR in Windows 11 you need to select “show more options”</em></p>
<h3 data-sanitized-id="preparing-ntlite">Preparing NTLite</h3>
<p>Look at the image below and add the files you extracted above. Follow these steps in order:</p>
<ol>
<li>Select Folder from Add Menu</li>
<li>Delete unneeded Windows versions <em>Ex. Windows Pro N or Windows Educational</em></li>
</ol>
<ul>
<li>Select the Version you DO NEED after before move to Apply</li>
<li>Import the Presets XML File</li>
</ul>
<ol start="3">
<li>Apply to load the files <em>Note: This will take a LONG time 5-10 minutes on fast systems</em></li>
</ol>
<p><img loading="lazy" src="https://christitus.com/images/2022/ntlite/import-image.webp" alt="import-image" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="customize-image">Customize Image</h3>
<p>There are a TON of customizations you can do here, but DO NOT OVER DO IT! Past the imported presets that automatically set the services you need and a few other quality of life settings, you should also import the drivers for the system you are installing it on. This speeds up the post-install time.</p>
<p>Once you have everything the way you want it, simply apply the settings.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/ntlite/apply-settings.webp" alt="apply-settings" data-sanitized-class="img-fluid"> </p>
<p><em>Note: This is the longest of all the stages and took almost 15 minutes on a good system</em></p>
<h4 data-sanitized-id="dummy-keys-for-windows-10">Dummy Keys for Windows 10</h4>
<p>Here is the list of generic keys for various Windows 10 Editions.</p>
<table>
<thead>
<tr>
<th>Windows 10 Edition</th>
<th>Generic Keys</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows 10 Home</td>
<td>YTMG3-N6DKC-DKB77-7M9GH-8HVX7</td>
</tr>
<tr>
<td>Windows 10 Home N</td>
<td>4CPRK-NM3K3-X6XXQ-RXX86-WXCHW</td>
</tr>
<tr>
<td>Windows 10 Pro</td>
<td>VK7JG-NPHTM-C97JM-9MPGT-3V66T</td>
</tr>
<tr>
<td>Windows 10 Pro N</td>
<td>2B87N-8KFHP-DKV6R-Y2C8J-PKCKT</td>
</tr>
<tr>
<td>Windows 10 Pro for Workstations</td>
<td>DXG7C-N36C4-C4HTG-X4T3X-2YV77</td>
</tr>
<tr>
<td>Windows 10 Pro N for Workstations</td>
<td>WYPNQ-8C467-V2W6J-TX4WX-WT2RQ</td>
</tr>
<tr>
<td>Windows 10 Pro Education</td>
<td>8PTT6-RNW4C-6V7J2-C2D3X-MHBPB</td>
</tr>
<tr>
<td>Windows 10 Pro Education N</td>
<td>GJTYN-HDMQY-FRR76-HVGC7-QPF8P</td>
</tr>
<tr>
<td>Windows 10 Education</td>
<td>YNMGQ-8RYV3-4PGQ3-C8XTP-7CFBY</td>
</tr>
<tr>
<td>Windows 10 Education N</td>
<td>84NGF-MHBT6-FXBX8-QWJK7-DRR8H</td>
</tr>
<tr>
<td>Windows 10 Enterprise</td>
<td>XGVPP-NMH47-7TTHJ-W3FW7-8HV2C</td>
</tr>
<tr>
<td>Windows 10 Enterprise N</td>
<td>WGGHN-J84D6-QYCPR-T7PJ7-X766F</td>
</tr>
<tr>
<td>Windows 10 Enterprise S</td>
<td>NK96Y-D9CD8-W44CQ-R8YTK-DYJWX</td>
</tr>
<tr>
<td>Windows 10 S</td>
<td>3NF4D-GF9GY-63VKH-QRC3V-7QW8P</td>
</tr>
</tbody>
</table>
<h2 data-sanitized-id="create-the-iso">Create the ISO</h2>
<p>Finally, we are ready to make the ISO. Just Click “Create ISO” and select the location to save it.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/ntlite/create-iso.webp" alt="create-iso" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="next-steps">Next Steps</h2>
<p>After you have made your ISO file you are now ready to install and finish your configuration</p>
<p>Check out my Windows Utility script and set the Security Updates, Install Extra Programs, and more @ <a href="https://christitus.com/windows-tool/">https://christitus.com/windows-tool/</a></p>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/xLCWtC6UYrM?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/how-i-setup-my-website/
title: How I Setup My Website
link: https://christitus.com/how-i-setup-my-website/
hash: *���'+J�1�\�s
attributes: {"enclosures":[]}
content:
<p>This shows you have I automate my workflows and setup my website for maximum productivity and search</p>
<p>The best part is this is FREE and will produce a website faster than anything on the web. Netlify, my host, didn’t charge anything until I was breaking 100GB of bandwidth and 100,000 active users PER MONTH! Now with double those numbers I pay only $19 a month and have 1 TB (Terabyte) of data per month.</p>
<h2 data-sanitized-id="the-workflow-and-overview">The Workflow and Overview</h2>
<p>Typically before I start recording any video, I write an outline and publish it on my website. It’s almost like a video script, but also a copy paste guide for either a viewer or just someone searching google.</p>
<p>This is done by using a static site generator. There are bunch on the market, but the one that suited my needs the best is <a href="https://gohugo.io/">Hugo</a>. It has a bunch of themes ready to use out of the box @ <a href="https://themes.gohugo.io/">https://themes.gohugo.io/</a> and is extremely modular.</p>
<p>Then there are the annoyances of other website platforms like WordPress. You need to go on the web and use some terrible web based editor that just is slow and takes a long time. Hugo fixes this by using both GitHub and Netlify for deployment. Netlify will “host, build, and distribute” the content automatically and GitHub will be where you publish when it’s ready for the publish stage that Netlify controls.</p>
<p>What this looks like in practice is I issue a <code>hugo new posts/new-post.md</code>, edit it with <code>vim posts/new-post.md</code>, and post it with git commit and push. This allows me to create a page in seconds if I wanted.</p>
<h2 data-sanitized-id="the-setup">The Setup</h2>
<p>Install Hugo (I recommend <a href="https://christitus.com/nix-package-manager">NIX Package Manager</a>)</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">nix-env -iA nixpkgs.hugo
</span></span></code></pre></div><p>Do a quick setup that creates the <code>website</code> folder and the needed HUGO framework files with:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">hugo new site website
</span></span></code></pre></div><p>Then we will initialize it with a HUGO theme like so:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">cd website
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">git init
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">git submodule add https://github.com/zzossig/hugo-theme-zzo.git themes/zzo
</span></span></code></pre></div><p>I absolutely love the ZZO theme as a beginner. It has some of the best instructions and documentation you will find! <a href="https://zzo-docs.vercel.app/zzo/gettingstarted/installation/">https://zzo-docs.vercel.app/zzo/gettingstarted/installation/</a></p>
<h2 data-sanitized-id="usage-and-first-steps">Usage and First Steps</h2>
<p>The first thing you want to do is look over the sample post in <code>/themes</code> under <code>/themes/examplesite</code>. Under here you will see the structure that HUGO uses and how most of the content ends up in the <code>content</code> directory off of root.</p>
<p>The second thing to note is the <code>/content/posts/</code> and seeing the examples here. This will show you the sample markdown file and how it’s laid out. Change these and make your first post. Once you figure out a good structure for your posts, you can then edit the default template.</p>
<p>For previewing the changes you can open up a new terminal and just type <code>hugo server</code> from the root <code>website</code> directory.</p>
<p>Now I have three different windows that I’m using for the bulk of my workflow:</p>
<ol>
<li>Chrome Window with <a href="https://localhost:1313/">https://localhost:1313</a></li>
<li>IDE for editing my markdown files (vs code, vim, etc.)</li>
<li>Extra terminal window running <code>hugo server</code> for real time updates for the chrome window</li>
</ol>
<p><em>Note: You can use terminal inside vs code and with the auto save feature you can see the code get updated on the webpage for every change you make!</em></p>
<h2 data-sanitized-id="your-first-modifications">Your First Modifications</h2>
<p>Remember the big thing with HUGO is everything is modular and everything can be changed, because at the end it is simply outputting a static html file.</p>
<p>Once you figure out how you want your posts structured, change the <code>/archtypes/default.md</code>. This template is what each new post will use. This is where you really increase your efficiency as we often find ourselves writing the same few things on each new post we make.</p>
<p>The next modification will probably comes from adding widgets or sidebar components. Instead of directly modifying the <code>/theme/zzo</code> files you can actually look through the partials directory and create your own <code>/layouts/partials</code> in your root that will take precedence over the ones in the theme directory. More in-depth explanation from the official site <a href="https://gohugo.io/templates/partials/">https://gohugo.io/templates/partials/</a>.</p>
<h2 data-sanitized-id="complex-theme-modifications">Complex Theme Modifications</h2>
<p>In my past Hugo Guide I went into some pretty big theme modifications (adding search, tags, etc.) Read more about that @ <a href="https://christitus.com/hugo-guide/">https://christitus.com/hugo-guide/</a></p>
<p>Also if you see something you want to copy from my website, everything is on my public GitHub @ <a href="https://github.com/christitustech/website">https://github.com/christitustech/website</a></p>
<p>Adding comments can be done in a multitude of ways, but my absolute favorite instead of using Disqus or commento.io is simply using GitHub to host the comments directly on your website repository! There is an amazing “plugin” that you can add called <a href="https://github.com/utterance/utterances">https://github.com/utterance/utterances</a> which does all the spam filtering and integrates comments BETTER!</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/xMv10E561WQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/pros-use-bleachbit/
title: Pros Use Bleachbit
link: https://christitus.com/pros-use-bleachbit/
hash: 0'c*|0~���f��Y?
attributes: {"enclosures":[]}
content:
<p>I still see far too many comments with people that still use CCLeaner. Bleachbit is a FAR superior product and it’s also free and open source. It won’t try to upsell you a bunch of garbage and has a great track record, unlike CCleaner which was hacked and literally installed malware on thousands of PCs.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">I don't know why but I keep seeing folks say they use CCleaner. They literally ship bloat and shipped malware a couple years ago. <br>Just use Bleachbit. It's free and open source while working on Windows, MacOS, and Linux.</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1577379725869256734?ref_src=twsrc%5Etfw">October 4, 2022</a></blockquote>

<h2 data-sanitized-id="ccleaner-history">CCleaner History</h2>
<p>I made a whole article on the CCleaner malware issue, but the main issue today is the program adds to much bloat. From the monitoring service, to the “Optimization Service” that adds multiple processes to your system. If you want to know more about this here is my past on CCleaner.</p>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/tSm1GcuygM0?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<h2 data-sanitized-id="bleachbit-overview">BleachBit Overview</h2>
<p>As a free and open source tool you simply run Bleachbit when you want to. No extra process run when you aren’t using it and it does a fantastic job on ANY system.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/bleachbit.webp" alt="bleachbit" data-sanitized-class="img-fluid"> </p>
<p>There is a TON of features and it deletes not only system temporary files, but also program specific temporary files like those stored from Discord or your web browser.</p>
<p>Is a program missing that you want cleaned? Chances are the community made a special XML file to clean it @ <a href="https://github.com/bleachbit/cleanerml">https://github.com/bleachbit/cleanerml</a></p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/2oT4qrHmDMY?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/vim-the-ultimate-editor/
title: Vim the Ultimate Editor
link: https://christitus.com/vim-the-ultimate-editor/
hash: |7���m���1�\
attributes: {"enclosures":[]}
content:
<p>VIM editor is one of the most beloved, but often misunderstood editors in existence. Let’s configure it from a noobs perspective and show you it’s power.</p>
<h2 data-sanitized-id="why-vim">Why VIM?</h2>
<p>There is so many things to learn about VIM, but before we start the question often pops up why not just use VS Code or IntelliJ?</p>
<p>VS Code and IntelliJ have some fantastic ease of use, and great debugging capabilities. There is extension support to add some amazing functionality. So why do many programmers still use VIM? one word: SPEED!</p>
<p>There is nothing that can even compare when it comes to speed from a veteran VIM user. They will blaze through code at the speed of light and change so much on their screen that you will have a hard time following just watching it. Don’t believe me? Just watch ANY “<a href="https://www.youtube.com/c/ThePrimeagen/videos">The Primeagen</a>” videos</p>
<p>So if it’s so fast why don’t most people use VIM? It’s hard and has one of the biggest learning curves that I have ever seen from any program. It will take <strong>YEARS</strong> to master, months to be better than vs code/intellij editors, and weeks of learning to be comparable to any other editor on the market.</p>
<p>However, the payoff is beyond worth it to me. The reward feels so good when you start to <em>get</em> it. The big thing… you can throw your mouse away, because when you get it… a mouse is no longer needed.</p>
<h2 data-sanitized-id="beginning-steps">Beginning steps</h2>
<p>The very first thing you need to know about vim is the modes.</p>
<ul>
<li>Normal Mode - The default mode you enter into on launch. This allows quick movement, exiting, commands, but you don’t “type” in this mode.</li>
<li>Insert Mode - Pressing <code>i</code> on your keyboard will allow you enter insert mode. This allows you to type text and keyboard input to the open file.</li>
<li>Visual Mode - Pressing <code>v</code> on your keyboard will put you in visual mode. This allows you to highlight and use commands on highlighted syntax.</li>
</ul>
<p><em>Note: You can escape Insert and Visual mode to go back to Normal mode with <code>esc</code> key</em></p>
<p>The other MEME you will always see about vim is you can’t exit it… just turn your computer off. Haha, but seriously exiting vim is probably my favorite thing and that brings us to the first thing to remember:</p>
<blockquote>
<p>“If something is slow in vim, there is a way to do it faster in vim”</p>
</blockquote>
<p>The official way to save and quit vim is to press the following in normal mode: <code>:wq</code> or faster <code>:x</code> or even faster <code>ZZ</code></p>
<p>To quit without saving: <code>:q!</code> or faster <code>ZQ</code></p>
<p>VIM Cheatsheets:</p>
<ul>
<li><a href="https://devhints.io/vim">https://devhints.io/vim</a></li>
<li><a href="https://vim.rtorr.com/">https://vim.rtorr.com/</a></li>
</ul>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Created a cheatsheet to sit on my background.<br>Handy if you are starting to learn vim. <a href="https://t.co/dM6cl3ebho">pic.twitter.com/dM6cl3ebho</a></p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1577690702200590336?ref_src=twsrc%5Etfw">October 5, 2022</a></blockquote>

<h2 data-sanitized-id="learning-the-basics">Learning the basics</h2>
<p>Now that you can actually function inside of vim, you might be thinking… “How in the hell do elite programmers use this damn program so fast?”.</p>
<p>Movement and muscle memory are the biggest things with vim. It’s not just knowing the keys, but using them without thinking. This may seem impossible, but the more you practice the better you will get.</p>
<p>You may have heard of <code>vimtutor</code> which walks you through the basics of vim. However, I’d encourage you to treat it like speed runners of your favorite video game. Run <code>vimtutor</code> as often as you can and treat it like a video game. How fast can you run it? Can you beat the old time? Can you complete the entire thing for the first time?!</p>
<p>This is where you will pick up the speed. Between the constant cheatsheets and running <code>vimtutor</code> as often as possible.</p>
<p>Other tips are moving as much of your workflow into vim as possible and customizing it to <strong>YOUR</strong> needs. Don’t just copy and paste some vimrc file your favorite programmer uses… it’s made for that person NOT YOU!</p>
<h2 data-sanitized-id="making-vim-your-own">Making VIM your own</h2>
<p>It is time to elevate your game to the elite status and making your own <code>.vimrc</code> file. This is where you make it feel awesome, even if you still suck at using vim. It’s important that you make vim feel good as this will make you want to continue using it.</p>
<p>I’ve been using VIM for a month and this is my <code>.vimrc</code> file. I use a lot of plugins, themes, and just a few hotkeys. This isn’t what an experts .vimrc file looks like, as I still consider myself just now leaving the beginner stages into an intermediate user. As time goes on I will expand this file by adding more shortcuts and better hotkeys.</p>
<p>Source: <a href="https://github.com/christitustech/myvim">https://github.com/christitustech/myvim</a>
</p><div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="vimrc" data-sanitized-class="language-vimrc"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Plugin Loading</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">call</span> <span data-sanitized-class="nx">plug</span>#<span data-sanitized-class="nx">begin</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'~/.vim/plugged'</span><span data-sanitized-class="p">)</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'itchyny/lightline.vim'</span> <span data-sanitized-class="c">"Highlights lines</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'joshdick/onedark.vim'</span> <span data-sanitized-class="c">"The One Dark Theme</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'junegunn/fzf'</span><span data-sanitized-class="p">,</span> { <span data-sanitized-class="s1">'do'</span>: { <span data-sanitized-class="p">-&gt;</span> <span data-sanitized-class="nx">fzf</span>#<span data-sanitized-class="nx">install</span><span data-sanitized-class="p">()</span> } }
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'junegunn/fzf.vim'</span> <span data-sanitized-class="c">"Fuzzy find plugin</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'junegunn/goyo.vim'</span> <span data-sanitized-class="c">"Removes Line numbers for focusing</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'mbbill/undotree'</span> <span data-sanitized-class="c">"Creates an undo tree</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'preservim/nerdtree'</span> <span data-sanitized-class="c">"File browser inside vim</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'godlygeek/tabular'</span> <span data-sanitized-class="c">"Auto formatting</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'plasticboy/vim-markdown'</span> <span data-sanitized-class="c">"Markdown syntax highlighting</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'wakatime/vim-wakatime'</span> <span data-sanitized-class="c">"Wakatime tracker</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'ryanoasis/vim-devicons'</span> <span data-sanitized-class="c">"Cool icons for nerd tree</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'Xuyuanp/nerdtree-git-plugin'</span> <span data-sanitized-class="c">"nerd tree customization</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'907th/vim-auto-save'</span> <span data-sanitized-class="c">"auto saves files as you edit</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">Plug</span> <span data-sanitized-class="s1">'jdhao/better-escape.vim'</span> <span data-sanitized-class="c">"remaps esc key to jj</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">call</span> <span data-sanitized-class="nx">plug</span>#<span data-sanitized-class="nx">end</span><span data-sanitized-class="p">()</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Startup Settings</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">syntax</span> <span data-sanitized-class="nx">on</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">mapleader</span><span data-sanitized-class="p">=</span><span data-sanitized-class="s2">" "</span> <span data-sanitized-class="c">"Maps Leader to space</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">NERDTreeShowHidden</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">auto_save</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">auto_save_events</span> <span data-sanitized-class="p">=</span> [<span data-sanitized-class="s2">"InsertLeave"</span><span data-sanitized-class="p">,</span> <span data-sanitized-class="s2">"TextChanged"</span>]
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> $<span data-sanitized-class="nx">FZF_DEFAULT_COMMAND</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="s1">'fdfind --type f --hidden --follow --exclude .git --ignore-file ~/.ignore'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">mouse</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">a</span> <span data-sanitized-class="c">"Allows mouse usage inside vim. Great for noobs.</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">clipboard</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">unnamedplus</span> <span data-sanitized-class="c">"Remaps default copy paste to system clipboard</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">cursorline</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">highlight</span> <span data-sanitized-class="nx">CursorLine</span> <span data-sanitized-class="nx">ctermbg</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">Yellow</span> <span data-sanitized-class="nx">cterm</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nb">bold</span> <span data-sanitized-class="nx">guibg</span><span data-sanitized-class="p">=</span><span data-sanitized-class="mh">#2b2b2b</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">noerrorbells</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">splitbelow</span> <span data-sanitized-class="nx">splitright</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">tabstop</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">2</span> <span data-sanitized-class="nx">softtabstop</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">2</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">shiftwidth</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">2</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">expandtab</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">smartindent</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">nofoldenable</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">nowrap</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">smartcase</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">noswapfile</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">nobackup</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">incsearch</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">history</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">5000</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">nocompatible</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">number</span> <span data-sanitized-class="nx">relativenumber</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">colorscheme</span> <span data-sanitized-class="nx">onedark</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">background</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nb">dark</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">termguicolors</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">filetype</span> <span data-sanitized-class="nx">plugin</span> <span data-sanitized-class="nx">on</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">encoding</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">utf</span><span data-sanitized-class="m">-8</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">wildmenu</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">wildmode</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">longest</span><span data-sanitized-class="p">,</span><span data-sanitized-class="nx">list</span><span data-sanitized-class="p">,</span><span data-sanitized-class="nx">full</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">laststatus</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">2</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">if</span> <span data-sanitized-class="p">!</span><span data-sanitized-class="nx">has</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'gui_running'</span><span data-sanitized-class="p">)</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">t_Co</span><span data-sanitized-class="p">=</span><span data-sanitized-class="m">256</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">endif</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">autocmd</span> <span data-sanitized-class="nx">FileType</span> * <span data-sanitized-class="nx">setlocal</span> <span data-sanitized-class="nx">formatoptions</span><span data-sanitized-class="p">-=</span><span data-sanitized-class="nx">c</span> <span data-sanitized-class="nx">formatoptions</span><span data-sanitized-class="p">-=</span><span data-sanitized-class="nx">r</span> <span data-sanitized-class="nx">formatoptions</span><span data-sanitized-class="p">-=</span><span data-sanitized-class="nx">o</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">spell</span> <span data-sanitized-class="nx">spelllang</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nx">en_us</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Plugin Shortcuts</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">map</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">f</span> :<span data-sanitized-class="nx">NERDTreeToggle</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">map</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">C</span><span data-sanitized-class="p">-</span>\<span data-sanitized-class="p">&gt;</span> :<span data-sanitized-class="nx">Goyo</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">F5</span><span data-sanitized-class="p">&gt;</span> :<span data-sanitized-class="nx">UndotreeToggle</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span> :<span data-sanitized-class="nx">UndotreeFocus</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">C</span><span data-sanitized-class="p">-</span><span data-sanitized-class="nx">f</span><span data-sanitized-class="p">&gt;</span> :<span data-sanitized-class="nx">Files</span><span data-sanitized-class="p">!&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">l</span> :<span data-sanitized-class="nx">Tabularize</span> /
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">better_escape_shortcut</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="s1">'jj'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">better_escape_interval</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">250</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" General Shortcuts</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="nx">S</span> :%<span data-sanitized-class="nx">s</span><span data-sanitized-class="sr">//</span><span data-sanitized-class="nx">g</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Left</span><span data-sanitized-class="p">&gt;&lt;</span><span data-sanitized-class="nx">Left</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nmap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">r</span> :<span data-sanitized-class="nx">w</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>:<span data-sanitized-class="nx">so</span> %<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">map</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">e</span> $
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Persistent_undo</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">undodir</span><span data-sanitized-class="p">=~</span><span data-sanitized-class="sr">/.vim/</span><span data-sanitized-class="nx">undodir</span>"
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">set</span> <span data-sanitized-class="nx">undofile</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">undotree_WindowLayout</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">2</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Tabedit keybinds</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="m">1</span> <span data-sanitized-class="m">1</span>gt<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="m">2</span> <span data-sanitized-class="m">2</span>gt<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="m">3</span> <span data-sanitized-class="m">3</span>gt<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="m">4</span> <span data-sanitized-class="m">4</span>gt<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="m">5</span> <span data-sanitized-class="m">5</span>gt<span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">t</span> :<span data-sanitized-class="nx">tabnew</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">nnoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Leader</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">c</span> :<span data-sanitized-class="nx">tabclose</span><span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Markdown Edits</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_autowrite</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_no_extensions_in_markdown</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_conceal</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_override_foldtext</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_folding_disabled</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">g</span>:<span data-sanitized-class="nx">vim_markdown_new_list_item_indent</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="m">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" Markdown auto format tables</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="nx">inoremap</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">silent</span><span data-sanitized-class="p">&gt;</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Bar</span><span data-sanitized-class="p">&gt;</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">Bar</span><span data-sanitized-class="p">&gt;&lt;</span><span data-sanitized-class="nx">Esc</span><span data-sanitized-class="p">&gt;</span>:<span data-sanitized-class="nx">call</span> <span data-sanitized-class="p">&lt;</span><span data-sanitized-class="nx">SID</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">align</span><span data-sanitized-class="p">()&lt;</span><span data-sanitized-class="nx">CR</span><span data-sanitized-class="p">&gt;</span><span data-sanitized-class="nx">a</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="k">function</span><span data-sanitized-class="p">!</span> <span data-sanitized-class="nx">s</span>:<span data-sanitized-class="nx">align</span><span data-sanitized-class="p">()</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">p</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="s1">'^\s*|\s.*\s|\s*$'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">if</span> <span data-sanitized-class="nx">exists</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">':Tabularize'</span><span data-sanitized-class="p">)</span> &amp;&amp; <span data-sanitized-class="nx">getline</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span> <span data-sanitized-class="p">=~</span># <span data-sanitized-class="s1">'^\s*|'</span> &amp;&amp; <span data-sanitized-class="p">(</span><span data-sanitized-class="nx">getline</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">line</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span><span data-sanitized-class="m">-1</span><span data-sanitized-class="p">)</span> <span data-sanitized-class="p">=~</span># <span data-sanitized-class="nx">p</span> <span data-sanitized-class="p">||</span> <span data-sanitized-class="nx">getline</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">line</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)+</span><span data-sanitized-class="m">1</span><span data-sanitized-class="p">)</span> <span data-sanitized-class="p">=~</span># <span data-sanitized-class="nx">p</span><span data-sanitized-class="p">)</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">column</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="nx">strlen</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">substitute</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">getline</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span>[<span data-sanitized-class="m">0</span>:<span data-sanitized-class="nx">col</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span>]<span data-sanitized-class="p">,</span><span data-sanitized-class="s1">'[^|]'</span><span data-sanitized-class="p">,</span><span data-sanitized-class="s1">''</span><span data-sanitized-class="p">,</span><span data-sanitized-class="s1">'g'</span><span data-sanitized-class="p">))</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">let</span> <span data-sanitized-class="nx">position</span> <span data-sanitized-class="p">=</span> <span data-sanitized-class="nx">strlen</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">matchstr</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">getline</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span>[<span data-sanitized-class="m">0</span>:<span data-sanitized-class="nx">col</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">)</span>]<span data-sanitized-class="p">,</span><span data-sanitized-class="s1">'.*|\s*\zs.*'</span><span data-sanitized-class="p">))</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">Tabularize</span><span data-sanitized-class="sr">/|/</span><span data-sanitized-class="nx">l1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">normal</span><span data-sanitized-class="p">!</span> <span data-sanitized-class="m">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="nx">call</span> <span data-sanitized-class="nx">search</span><span data-sanitized-class="p">(</span><span data-sanitized-class="nx">repeat</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'[^|]*|'</span><span data-sanitized-class="p">,</span><span data-sanitized-class="nx">column</span><span data-sanitized-class="p">)</span>.<span data-sanitized-class="s1">'\s\{-\}'</span>.<span data-sanitized-class="nx">repeat</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">,</span><span data-sanitized-class="nx">position</span><span data-sanitized-class="p">),</span><span data-sanitized-class="s1">'ce'</span><span data-sanitized-class="p">,</span><span data-sanitized-class="nx">line</span><span data-sanitized-class="p">(</span><span data-sanitized-class="s1">'.'</span><span data-sanitized-class="p">))</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">endif</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="k">endfunction</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">
</span></span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c">" transparent bg</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="k">autocmd</span> <span data-sanitized-class="nx">vimenter</span> * <span data-sanitized-class="k">hi</span> <span data-sanitized-class="nx">Normal</span> <span data-sanitized-class="nx">guibg</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nb">NONE</span> <span data-sanitized-class="nx">ctermbg</span><span data-sanitized-class="p">=</span><span data-sanitized-class="nb">NONE</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span></code></pre></div>

<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/P88ydZVcm1s?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/why-the-cli-is-op/
title: Why the Command Line is Overpowered
link: https://christitus.com/why-the-cli-is-op/
hash: �%XR���_\ ���
attributes: {"enclosures":[]}
content:
<p>When I say “Overpowered”, this means the command line interfaces can do things that are otherwise impossible.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Do you think the command line in all operating systems (Windows, MacOS, and Linux) is Overpowered?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1578822405518397442?ref_src=twsrc%5Etfw">October 8, 2022</a></blockquote>

<h2 data-sanitized-id="all-operating-systems">All Operating Systems</h2>
<p>When your think of command line interfaces or CLI, there are a lot of things that come to my mind, but let’s go over how they are overpowered in EVERY operating system.</p>
<h3 data-sanitized-id="windows">Windows</h3>
<p>Both PowerShell and Command Prompt in Windows can do some amazing things. I use them extensively in both my personal and business life. I have some batch scripts that strip out and delete edge every time Microsoft reinstalls it through an unwanted update.</p>
<p>In Powershell my entire Windows Utility is built through a PS1 script and XAML. I can install Microsoft Store Apps, Clean and Optimize systems quickly. I can also modify Windows in a way where I only have <strong>40</strong> processes running.</p>
<p>These feats are not possible from just using fancy graphics and a mouse. Without them, you are crippled and at the mercy of Microsoft.</p>
<h3 data-sanitized-id="macos">MacOS</h3>
<p>Terminal on a mac is the one thing I love about the operating system. Most mac users don’t even know how awesome their UNIX based terminal is. They just click around and open up their wallets to the App Store when they need something.</p>
<p>That all changes when you discovery terminal and a program called “Homebrew”. This gives you the ability to install programs in a flash and it doesn’t cost you a dime. I couldn’t live without this on a Mac.</p>
<h3 data-sanitized-id="linux">Linux</h3>
<p>Terminal is the CLI that made command line cool. The functions you get from this in Linux is absolutely amazing. It is so good that many mundane tasks are simply easier on terminal than using a mouse and the graphic user interface. The entire system can be run from terminal with ease and why the world runs on Linux servers.</p>
<h2 data-sanitized-id="is-it-faster-than-a-gui">Is it faster than a GUI?</h2>
<p>There is a debate about this among hobbyists, but any IT professional will tell you that there isn’t any comparison. Installing programs, tweaking a system, copying large amounts of files, and many more tasks are not only easier, but incredibly faster. It is not to say there is no place for the GUI, but for tasks you do often, there is no equal that can come close to the efficiency of the command line.</p>
<p>So the question isn’t if it is faster than the GUI… The question is:</p>
<blockquote>
<p>“Are you skilled enough to use the command line to its potential?”</p>
</blockquote>
<p>I often ask myself this question when I find something cumbersome and I don’t know the alternative in the command line. The thing most people miss is, ANYTHING is possible on the command line. It’s just whether or not you know it.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/pkhazgI3LAo?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/setting-up-the-ultimate-windows-11/
title: Setting Up the Ultimate Windows 11
link: https://christitus.com/setting-up-the-ultimate-windows-11/
hash: �]:��{"Z����
attributes: {"enclosures":[]}
content:
<p>This guide shows you how to get the best performing Windows in the lightest package possible.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Extreme debloat for windows? Challenge accepted. <a href="https://t.co/YMr9xpAl9E">pic.twitter.com/YMr9xpAl9E</a></p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1578070224896663553?ref_src=twsrc%5Etfw">October 6, 2022</a></blockquote>

<h2 data-sanitized-id="before-you-begin">Before you begin</h2>
<p>A custom ISO is a MUST! With extreme debloat we will be removing Windows Update, Security Services, and a variety of other system services that will bring Windows back to the XP era.</p>
<p>If your never used Windows XP, it was an extremely light OS by today’s standards, but it came at a cost. The update system was web based, there was no antivirus, and security center didn’t appear until SP2 came out. This is a LOT like those days, where the user was responsible for the safety of their system.</p>
<p>I also highly recommend buying NTLite if you want to live in this environment. Yes, it makes the ISO easier, but I absolutely love the fact it can control your Windows updates as well. Once a month, you can open NTLite and pull down the latest updates and apply them through their tool to the live install.</p>
<h2 data-sanitized-id="the-process">The Process</h2>
<ul>
<li>Make the NTLite Install Media <a href="https://christitus.com/ntlite-guide/">https://christitus.com/ntlite-guide/</a></li>
<li>Install Windows</li>
<li>Run my Windows utility <a href="https://christitus.com/windows-tool/">https://christitus.com/windows-tool/</a></li>
</ul>
<p><em>Shortcut</em></p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">irm christitus.com/win | iex
</span></span></code></pre></div><h2 data-sanitized-id="issues-with-minimal-install">Issues with Minimal Install</h2>
<p>Certain dependencies for programs will be missing. When you run my utility installation of winget will likely fail because there isn’t a trace of the Microsoft store on the system.</p>
<p>I manually grabbed these using Invoke Rest Method. These are the commands I used in the video below:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="gdscript3" data-sanitized-class="language-gdscript3"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">irm</span> <span data-sanitized-class="s2">"https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">o</span> <span data-sanitized-class="s2">"./Microsoft.VCLibs.x64.14.00.Desktop.appx"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">irm</span> <span data-sanitized-class="s2">"https://github.com/microsoft/winget-cli/releases/download/v1.2.10271/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">o</span> <span data-sanitized-class="s2">"./Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">irm</span> <span data-sanitized-class="s2">"https://github.com/microsoft/winget-cli/releases/download/v1.2.10271/b0a0692da1034339b76dce1c298a1e42_License1.xml"</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">o</span> <span data-sanitized-class="s2">"./b0a0692da1034339b76dce1c298a1e42_License1.xml"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">Add</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">AppxProvisionedPackage</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Online</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">PackagePath</span> <span data-sanitized-class="s2">".\Microsoft.VCLibs.x64.14.00.Desktop.appx"</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">SkipLicense</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">Add</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">AppxProvisionedPackage</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Online</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">PackagePath</span> <span data-sanitized-class="s2">".\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">LicensePath</span> <span data-sanitized-class="s2">".</span><span data-sanitized-class="se">\b</span><span data-sanitized-class="s2">0a0692da1034339b76dce1c298a1e42_License1.xml"</span>
</span></span></code></pre></div><p>I’m working on expanding my tool to give an easy way to do this reliably for these types of minimal systems. If you’d like to support my work and its future development, consider grabbing the exe @ <a href="https://cttstore.com/windows-toolbox">https://cttstore.com/windows-toolbox</a></p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/WmOvg0MagW0?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/buying-cheap-ebay-graphics-card/
title: Buying Cheap Ebay Graphics Cards
link: https://christitus.com/buying-cheap-ebay-graphics-card/
hash: � T��sO�f�K�W
attributes: {"enclosures":[]}
content:
<p>With GPU Market prices plummeting and about to go even further down… I picked up a used GPU from eBay.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Just bought a 5700 XT GPU for $170. Let's see how these used mining cards fair...</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1573043990018113539?ref_src=twsrc%5Etfw">September 22, 2022</a></blockquote>

<h2 data-sanitized-id="the-deal">The Deal</h2>
<p>You can monitor these cards and get some amazing deals. The AMD 5700 XT I picked up for $170 and this was selling for OVER $1000 dollars in 2021. This card is special because its predecessor is the 6700 XT and has only 3% better performance in 1080p format. Amazing right? Well… it is not quite that simple.</p>
<h2 data-sanitized-id="buying-through-ebay">Buying through eBay</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/buying-cheap-ebay-graphics-card/ebay-itemview.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>This particular post intrigued me because it the pictures that came with it and the extremely high feedback with high volumes.</p>
<p>The picture I paid the most attention to was the backplate. Notice over the screws the warranty symbol sticker. This is still there, even through they post says they upgraded the thermal pads. This tells me either the picture isn’t of the card or the person took extreme care when doing this upgrade. The other thing that stood out was the card itself looked to be in very good condition.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/buying-cheap-ebay-graphics-card/backplate-5700x.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="red-flags">Red Flags</h2>
<p>There are couple things I look at when scanning the pictures.</p>
<ul>
<li>Stock photos - HUGE Flag and do not buy anything with a stock photo</li>
<li>Excessive “grease stains” - On the card zoom in and if you can see smears or what looks like the plastic is wet, then the card was run extremely hot and a lot of the thermal compound leaked and was smeared on the card itself. Most of these used mining cards will have a little bit of that, but pay close attention to it.</li>
<li>No Retail Packaging - This isn’t a huge flag, but typically this just means they didn’t put much care into keeping the packaging. What else didn’t that pay attention to?</li>
</ul>
<h2 data-sanitized-id="pricing">Pricing</h2>
<p>Even though I bought this card at $170 and that is below the retail and eBay historical pricing for the past couple years, I could have waited a bit longer. Once the new generation cards come out, these cards will drop even LOWER! That is the perfect time to scoop up a deal. For 1080p gaming, you’d have to hate yourself to buy a new generation card. These older gen cards give more performance than you could ever want at that resolution.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/buying-cheap-ebay-graphics-card/ebay.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><img loading="lazy" src="https://christitus.com/images/2022/buying-cheap-ebay-graphics-card/retail.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="issues-once-you-bought-the-card">Issues once you bought the card</h2>
<p>The biggest issue you will run into is bad roms. Most these mining farms flash the vbios with undervolted presets. This can cause blue screens and host of other issues.</p>
<p>This can be fixed with downloading a new bios from <a href="https://www.techpowerup.com/vgabios/">https://www.techpowerup.com/vgabios/</a></p>
<p>Just be very careful and backup the existing bios with a program like GPUZ <a href="https://www.techpowerup.com/download/techpowerup-gpu-z/">https://www.techpowerup.com/download/techpowerup-gpu-z/</a></p>
<p>I’d recommend using GPUz for the BIOS backup and also create a backup using the flashing program as well. I bricked my card momentarily when I tried to flash in Windows. This was fixed by booting in Linux and force flashing the vbios from command line.</p>
<p>The other issue is the cards were not taken care of and were run at too high of temperatures. This can cause multiple errors and generally the card is bad. HOWEVER, I have yet to run into this being the case for me. Most times just re-flashing with a factory bios fixes most the issues I’ve encountered.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/X44gW2BoSpc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/installing-appx-without-msstore/
title: Installing Appx Without Microsoft Store
link: https://christitus.com/installing-appx-without-msstore/
hash: ��Ax�:��-��
attributes: {"enclosures":[]}
content:
<p>Do you have a bare version of windows LTSC or highly stripped out ISO image that doesn’t have the Microsoft Store? This is the guide to show you how to install appx and other apps without it.</p>
<h2 data-sanitized-id="winget-installation">Winget Installation</h2>
<p>Using the powershell and a couple projects we can install winget. You need the Microsoft sanctioned script repository called PSGallery. It has some system admin scripts that are clutch when all you have is powershell.</p>
<h2 data-sanitized-id="what-this-does">What this does</h2>
<p>It grabs the script from <a href="https://www.powershellgallery.com/packages/winget-install/0.0.4">https://www.powershellgallery.com/packages/winget-install/0.0.4</a> and runs it. The script itself utilizes NuGet and other tools that are in every Windows installation to install the dependancies, before retrieving the winget packages.</p>
<h2 data-sanitized-id="why-this-is-better">Why this is better</h2>
<p>This way is far superior to other methods as most will fail in a stripped down Windows like the one made from my <a href="https://christitus.com/ntlite-guide/">NTLite Build</a>.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/but-why.gif" alt="but-why" data-sanitized-class="img-fluid"> </p>
<p>The package that is often missing and hard to install manually is <code>Microsoft.UI.Xaml</code> the typical method to install this is using NuGet Package Manager inside of Visual Studio. You can track down the exact version and appx file from Microsoft’s repository here: <a href="https://store.rg-adguard.net/">https://store.rg-adguard.net/</a>, but this is overly cumbersome and why I recommend the PSGallery approach.</p>
<h2 data-sanitized-id="how-to-manually-get-any-appx">How to Manually get ANY Appx</h2>
<p>Using the <a href="https://store.rg-adguard.net/">https://store.rg-adguard.net/</a> site we can snatch any appx as long as we know the package name.</p>
<p>Get product id from <a href="https://apps.microsoft.com/store/apps">https://apps.microsoft.com/store/apps</a></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/installing-appx-without-msstore/app-store.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>Then grab the appx from rg-adguard AND its dependancies… like this:</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/installing-appx-without-msstore/rg-adguard.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="direct-download-with-script">Direct Download with Script</h3>
<p>Here is quick snippit that you can toss the product id in to pull it down from PowerShell.</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="gdscript3" data-sanitized-class="language-gdscript3"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">apiUrl</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="s2">"https://store.rg-adguard.net/api/GetFiles"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">productUrl</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="s2">"https://www.microsoft.com/store/productId/9nblggh5r558"</span> <span data-sanitized-class="c1"># To Do</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c1">#$productUrl = "https://www.microsoft.com/store/productId/9MSPC6MP8FM4" # Whiteboard</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="c1">#$productUrl = "https://www.microsoft.com/store/productId/9WZDNCRFJBB1" # Wireless Display Adapter</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFolder</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="n">Join</span><span data-sanitized-class="o">-</span><span data-sanitized-class="ne">Path</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">env</span><span data-sanitized-class="p">:</span><span data-sanitized-class="n">TEMP</span> <span data-sanitized-class="s2">"StoreDownloads"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="k">if</span><span data-sanitized-class="p">(</span><span data-sanitized-class="o">!</span><span data-sanitized-class="p">(</span><span data-sanitized-class="n">Test</span><span data-sanitized-class="o">-</span><span data-sanitized-class="ne">Path</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFolder</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">PathType</span> <span data-sanitized-class="ne">Container</span><span data-sanitized-class="p">))</span> <span data-sanitized-class="p">{</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">New</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">Item</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFolder</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">ItemType</span> <span data-sanitized-class="ne">Directory</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Force</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="p">}</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">body</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="err">@</span><span data-sanitized-class="p">{</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">type</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="s1">'url'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">url</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">productUrl</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">ring</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="s1">'RP'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">lang</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="s1">'en-US'</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="p">}</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">raw</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="n">Invoke</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">RestMethod</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Method</span> <span data-sanitized-class="n">Post</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Uri</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">apiUrl</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">ContentType</span> <span data-sanitized-class="s1">'application/x-www-form-urlencoded'</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Body</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">body</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">$</span><span data-sanitized-class="n">raw</span> <span data-sanitized-class="o">|</span> <span data-sanitized-class="n">Select</span><span data-sanitized-class="o">-</span><span data-sanitized-class="ne">String</span> <span data-sanitized-class="s1">'&lt;tr style.*&lt;a href=</span><span data-sanitized-class="se">\"</span><span data-sanitized-class="s1">(?&lt;url&gt;.*)"\s.*&gt;(?&lt;text&gt;.*)&lt;\/a&gt;'</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">AllMatches</span><span data-sanitized-class="o">|</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="o">%</span> <span data-sanitized-class="p">{</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">_</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Matches</span> <span data-sanitized-class="p">}</span> <span data-sanitized-class="o">|</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="o">%</span> <span data-sanitized-class="p">{</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">url</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">_</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Groups</span><span data-sanitized-class="p">[</span><span data-sanitized-class="mi">1</span><span data-sanitized-class="p">]</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Value</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">text</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">_</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Groups</span><span data-sanitized-class="p">[</span><span data-sanitized-class="mi">2</span><span data-sanitized-class="p">]</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Value</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">Write</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">Host</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">text</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">if</span><span data-sanitized-class="p">(</span><span data-sanitized-class="o">$</span><span data-sanitized-class="n">text</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">match</span> <span data-sanitized-class="s2">"_(x86|x64|neutral).*appx(|bundle)$"</span><span data-sanitized-class="p">)</span> <span data-sanitized-class="p">{</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFile</span> <span data-sanitized-class="o">=</span> <span data-sanitized-class="n">Join</span><span data-sanitized-class="o">-</span><span data-sanitized-class="ne">Path</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFolder</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">text</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="k">if</span><span data-sanitized-class="p">(</span><span data-sanitized-class="o">!</span><span data-sanitized-class="p">(</span><span data-sanitized-class="n">Test</span><span data-sanitized-class="o">-</span><span data-sanitized-class="ne">Path</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFile</span><span data-sanitized-class="p">))</span> <span data-sanitized-class="p">{</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="n">Invoke</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">WebRequest</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">Uri</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">url</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">OutFile</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">downloadFile</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="p">}</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> <span data-sanitized-class="p">}</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="p">}</span>
</span></span></code></pre></div><h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/__2_41pVHcQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/pretty-powershell/
title: Pretty Powershell
link: https://christitus.com/pretty-powershell/
hash: #�p�u ��$�j��
attributes: {"enclosures":[]}
content:
<p>PowerShell is UGLY and cumbersome by default. This Guide fixes that!</p>
<p>The End Result:</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/pretty-powershell/end-result.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="fixing-the-visuals">Fixing the Visuals</h2>
<p>With all my guides here is the one line script to install “most” of the needed fixes. I’d recommend running it from an admin elevated prompt for installation of OhMyPosh.</p>
<h3 data-sanitized-id="one-line-install">One Line Install</h3>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">irm "https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1" | iex
</span></span></code></pre></div><p>The first thing that needs to be fixed is installing the correct font. Here are screenshots from both Windows 11 using Terminal and Windows 10 using Conhost. After running the above script, you will unzip the <code>cove.zip</code> file from the directory the command above was run from and install those nerd fonts. If you want to download other nerd fonts, go to: <a href="https://www.nerdfonts.com/">https://www.nerdfonts.com/</a></p>
<h3 data-sanitized-id="windows-11-font-settings">Windows 11 Font Settings</h3>
<p><img loading="lazy" src="https://christitus.com/images/2022/pretty-powershell/win11.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="windows-10-font-settings">Windows 10 Font Settings</h3>
<p>In the screenshot below you will see the stock font select and the missing icons. Selecting CaskaydiaCove above Consolas and saving will fix it.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/pretty-powershell/win10.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="fixing-the-syntax">Fixing the Syntax</h2>
<p>The defaults are clunky and take too long to type in even when using shorthand. Linux does this better, so lets bring in that syntax to fix it with Aliases in our PowerShell profile.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Every time I'm in Windows PowerShell I can't help but think that the Microsoft Devs were on some heavy drugs when setting commands.<br>I'm going to fix that. <a href="https://t.co/AVaOCoVyOT">pic.twitter.com/AVaOCoVyOT</a></p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1581708112394096640?ref_src=twsrc%5Etfw">October 16, 2022</a></blockquote>

<h3 data-sanitized-id="new-aliases">New Aliases</h3>
<p>Here are the following added aliases for quality of life</p>
<ul>
<li>cd… <code>cd ..\..</code></li>
<li>cd…. <code>cd ..\..\..</code></li>
<li>dirs “Recursive directory listing”</li>
<li>admin / su / sudo “Elevate to admin prompt”</li>
<li>Edit-Profile “Edit current powershell $PROFILE”</li>
<li>vim <code>nvim</code> “Neovim alias”</li>
<li>ll “file listing, excluding dirs”</li>
<li>g “cd to Documents\Github”</li>
<li>gcom “quick github commit”</li>
<li>lazyg “quick github commit and push”</li>
<li>Get-PubIP “Grab external IP”</li>
<li>uptime</li>
<li>reload-profile</li>
<li>find-file “recursive file search from current directory”</li>
<li>unzip</li>
<li>grep</li>
<li>touch</li>
<li>df “disk free”</li>
<li>sed</li>
<li>which</li>
<li>export</li>
<li>pkill “process killer”</li>
<li>pgrep “process finder”</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/LuAipOW8BNQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/reagentc-windows-recovery-partition/
title: Reagentc Windows Recovery Partition
link: https://christitus.com/reagentc-windows-recovery-partition/
hash: ��n4�w� GM����
attributes: {"enclosures":[]}
content:
<p>Don’t know what ReAgentC is or how to use it? This is your guide.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Do you know how to use ReAgentC and setup the built-in windows recovery partition?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1584603485261115392?ref_src=twsrc%5Etfw">October 24, 2022</a></blockquote>

<h2 data-sanitized-id="setup-recovery-partition">Setup Recovery Partition</h2>
<ol>
<li>
<p>Create Recovery Partition at least 1GB in size.</p>
</li>
<li>
<p>Format the recovery partition as NTFS</p>
</li>
<li>
<p>DISKPART Changes</p>
<pre><code>- select disk 0
- select partition 3 (last partition)
- detail partition (list partition details)
- set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac" (GPTDisk) _Note: id=27 on MBR_
NOTE: Reset ids to normal if you did the WRONG partition (MBR set id=7 and GPT set id="ebd0a0a2-b9e5-4433-87c0-68b6b72699c7")
- _Create Partition if Missing!_ `cre par pri size=605 id=de94bba4-06d1-4d40-a16a-bfd50179d6ac`
- `format fs=ntfs quick label=WinRE`
- `assign letter=z`
- UEFI only: `gpt attributes=0x8000000000000001`
</code></pre>
</li>
<li>
<p><code>reagentc /disable</code></p>
</li>
<li>
<p>Verify <code>WinRE.wim</code> is installed on local system <code>ls "C:\Windows\System32\Recovery" | FindStr /I "WinRE.wim" ; ls "C:\Windows\System32\Recovery" -Hidden | FindStr /I "WinRE.wim"</code>
5a. If Missing, Copy WinRE.wim and the uninitialized ReAgent.xml files from the installation Media (Easiest method is to use 7zip to extract <code>WinRE.wim</code> from <code>install.wim</code>) to <code>C:\Windows\System32\Recovery</code></p>
</li>
<li>
<p><code>reagentc /enable</code> (this will move WinRe.wim to the Recovery partition and set the GUID and location in ReAgent.xml)</p>
</li>
<li>
<p><code>reagentc /info</code> (Check settings for verification)</p>
</li>
</ol>
<h3 data-sanitized-id="if-reagentc-enable-does-not-work">If ReAgentC /enable does NOT work</h3>
<ul>
<li>Manually copy <code>WinRE.wim</code> to <code>Z:\Recovery\WindowsRE</code></li>
<li><code>ReAgentC /SetREimage /Path "Z:\Recovery\WindowsRE"</code></li>
<li><code>ReAgentC /Enable</code></li>
<li>Verify with <code>ReAgentC /Info</code></li>
</ul>
<h2 data-sanitized-id="rebooting-to-recovery-partition">Rebooting to Recovery Partition</h2>
<p>If you can boot in to Windows, hold shift while pressing restart. This will reboot your PC into a menu. Select <em>Advanced Options</em></p>
<p>Another method to reach this screen is to have the boot fail 3 times. A reboot during the load screen will count as a failure.</p>
<p>F8 is an older method that doesn’t work unless enabled, but was a great way to get to the menu. I’m adding this to my Windows Utility Tweaks section.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/reagentc-windows-recovery-partition/recovery.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="startup-repair-and-settings">Startup Repair and Settings</h3>
<p>Startup Repair almost never works, but once in a blue moon is beneficial. Startup Settings can send you to safe mode.</p>
<h3 data-sanitized-id="command-prompt">Command Prompt</h3>
<p>Here are the highlights of a recovery partition:</p>
<ul>
<li>Copy Files</li>
<li>Chkdsk for failing hard drives</li>
<li>SFC/DISM repairs corrupt system files (<code>sfc /scannow</code> and <code>dism /image:c:\ /cleanup-image /restorehealth</code>)</li>
</ul>
<p><img loading="lazy" src="https://christitus.com/images/2022/reagentc-windows-recovery-partition/sfc.webp" alt="" data-sanitized-class="img-fluid"> </p>
<ul>
<li>Regedit for editing the registry</li>
</ul>
<p><img loading="lazy" src="https://christitus.com/images/2022/reagentc-windows-recovery-partition/regedit.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="uninstall-updates">Uninstall Updates</h3>
<p>Bad update and now it doesn’t work? Click this and revert it!</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/reagentc-windows-recovery-partition/updates.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="uefi-firmware-settings">UEFI Firmware Settings</h3>
<p>Loads into BIOS. Can be useful on laptops where you don’t know key combination when powering on.</p>
<h3 data-sanitized-id="system-restore-and-system-image-recovery">System Restore and System Image Recovery</h3>
<p>I don’t use these much, but can be a good last resort option. System Restore generally brings most of the system back to last restore point and System Image is good for recovering Windows if you used the built-in Windows Backup Software to external hard drive.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/L7Ss-KKp010?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: yt:video:jlyru5YXCfY
title: Auto-Resize Text Layers with Expressions in After Effects
author: ;ukramedia
link: https://www.youtube.com/watch?v=jlyru5YXCfY
hash: �s�tq:PY�譨��
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/jlyru5YXCfY?version=3","title":"Auto-Resize Text Layers with Expressions in After Effects","description":"Hey there! Get ready for some After Effects magic in this fun tutorial video! In this step-by-step guide, I'll show you how to effortlessly auto-resize text layers to a custom size using expressions. Say goodbye to the hassle of manually adjusting your text when it gets too wide! With just a few lines of code, you can create a super cool effect that automatically resizes your text once it hits a specific limit. Let's simplify your workflow and create some awesome auto-resizing text layers together! \n\n/// Free After Effects Project File:\n     Project File: https://ukramedia.com/?add-to-cart=361407\n\n/// Links from the Video:\n     Smart Resizer: https://ukramedia.com/SmartResizer\n\n/// Let's Connect:\n     Facebook: https://www.facebook.com/ukramedia\n     Sergei's Facebook Page: https://www.facebook.com/sergeiprokhn...\n     Twitter: https://twitter.com/ukramedia\n     TikTok: https://www.tiktok.com/@ukramedia\n     Instagram: https://www.instagram.com/ukramedia/\n     Pinterest: https://www.pinterest.com/ukramedia/\n     Linkedin: https://www.linkedin.com/company/ukra...\n     YouTube: https://www.youtube.com/c/ukramedia\n     Ukramedia Online Community: https://www.ukramedia.com/community\n\n#AeExpressions #AfterEffects #AdobeAfterEffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i3.ytimg.com/vi/jlyru5YXCfY/hqdefault.jpg"]}]}


guid: https://christitus.com/urbackup/
title: Urbackup
link: https://christitus.com/urbackup/
hash: �_u�;� ���;b�&
attributes: {"enclosures":[]}
content:
<p>Want a Universal Backup that works on EVERY operating system and is free + open source? Urbackup is the software you are looking for!</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">What is your Backup Solution?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1584567052404412416?ref_src=twsrc%5Etfw">October 24, 2022</a></blockquote>

<h2 data-sanitized-id="why-urbackup">Why UrBackup</h2>
<p>This program is absolutely amazing and free! All it’s source code is on the internet which made it able to adapt to ALL operating systems. Windows, Mac, Linux… hell it even has ARM support!</p>
<h2 data-sanitized-id="universal-backup-servers">Universal Backup Servers</h2>
<p>There is a ton of different supported servers and even some that are unsupported that still work. Here is the official download page: <a href="http://www.urbackup.org/download.html">http://www.urbackup.org/download.html</a></p>
<p>One notable non-official project is for Synology NAS devices. I use a 64-bit Synology on DSM 7+, so pay attention to your current version if you want to use the project below.</p>
<p>Synology Project: <a href="https://github.com/josef109/spksrc">https://github.com/josef109/spksrc</a></p>
<h3 data-sanitized-id="server-dashboard">Server Dashboard</h3>
<p><img loading="lazy" src="https://christitus.com/images/2022/urbackup/dash.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="automated-terminal-install-and-linux-setup">Automated Terminal Install and Linux Setup</h3>
<p>Linux installs are a complete DREAM! Just paste the command listed under terminal when you use “Add New Client” Button. Here is an example install:</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/urbackup/linux-term.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="enable-restore-from-web">Enable Restore from Web</h3>
<p>You need to enable restoration in client configuration to completely control everything from server web interface. Here is a sample client configuration <code>/etc/default/urbackupclientbackend</code></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/urbackup/enable-web.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="windows-client-setup">Windows Client Setup</h2>
<p>Windows uses a executable that is made with the “Add New Client” button. By default, windows clients will have full image backup on and no file based backups. I’d recommend changing this by adding your home directory or any other important folders, such as: <code>My Documents</code></p>
<h2 data-sanitized-id="linux-client-setup">Linux Client Setup</h2>
<p>Linux clients can be installed via terminal and what I recommend.</p>
<p><em>Note: The Linux GUI isn’t good and terminal use of <code>urbackupclientctl</code> is used</em></p>
<h3 data-sanitized-id="image-backups">Image Backups</h3>
<p>Since urbackup only supports EXT4 and XFS we need LVM setup on these volumes BEFORE installing the distribution. LVM is tricky to setup correctly and will be hard as a beginner. The good thing about Linux is we don’t have to worry about full image backups. All our configuration settings are in <code>~/.config</code> and global settings in <code>/etc/</code>. On my installs I mainly backup the <code>.config</code> folder and any other folder where I might put important information that would be isolated to that computer.</p>
<h3 data-sanitized-id="setting-the-backup-directories">Setting the backup directories</h3>
<p>Here is a sample backup command to add my <code>~/.config</code> directory</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">sudo urbackupclientctl add-backupdir -d $HOME/.config/
</span></span></code></pre></div><p>Then, check the status using the server web interface.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/urbackup/linux-file.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h3 data-sanitized-id="uninstall">Uninstall</h3>
<p>Uninstallation is a bit weird and needs to be done with this command:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">sudo uninstall_urbackupclient
</span></span></code></pre></div><p><img loading="lazy" src="https://christitus.com/images/2022/urbackup/linux-uninstall.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="alternatives">Alternatives</h2>
<p>There are a lot of free and open source backup solutions for backup. I picked urbackup because it is the most basic and probably the easiest to setup. However, if you need more features there are more backup solutions that I’d consider better for large environments or businesses.</p>
<ul>
<li>BorgBackup <a href="https://www.borgbackup.org/">https://www.borgbackup.org/</a> for cloud paid offering, BorgBase <a href="https://www.borgbase.com/">https://www.borgbase.com/</a></li>
<li>Bacula <a href="https://www.bacula.org/">https://www.bacula.org/</a> Enterprise solutions and fantastic dashboard</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/tXGVzMUsuE4?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/neovim-is-better/
title: Neovim Is Better
link: https://christitus.com/neovim-is-better/
hash: s0��/34���b���
attributes: {"enclosures":[]}
content:
<p>I’ve never experienced a program with such power and potential than Neovim. It does so much and we are at the beginning as it isn’t even to a 1.0 release yet. The best part is the program works on Windows, MacOS, and Linux.</p>
<p>The following tweet encompasses my thoughts and feelings in my first week using Neovim.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Ok the more time I spend in Neovim... The more godly I feel. Seriously feels like I'm unlocking the meaning of life...<br>It is just better in every way once configured.<br>Thumbnail preview: <a href="https://t.co/lOyZDXfRTf">pic.twitter.com/lOyZDXfRTf</a></p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1584944224700702720?ref_src=twsrc%5Etfw">October 25, 2022</a></blockquote>

<h2 data-sanitized-id="is-this-the-path-for-you">Is this the path for you?</h2>
<p>Neovim is rewarding after configured. The amount of automation, speed, and shear possibilities are limitless, but NOT without it’s downside though. I’ve spent hours working on my basic configuration and I am still months away before I will be close to completion. I say this as a NOOB! That is because I had no idea what a DAP, LSP, Linter, and other coding terms were before I began this journey.</p>
<p>If you know any of the coding terms and a little LUA, you will have a better starting point than myself. If not, get prepared to learn because there will be a lot of new terms and functionality you will need to know to get the most out of Neovim experience.</p>
<h2 data-sanitized-id="what-i-use-neovim-for">What I use Neovim for</h2>
<ul>
<li><strong>Writing</strong> is a difficult task that requires focus and creativity. For me, having the focus mode with a Linter that checks spelling and grammar has made a massive difference. I prefer the linting approach to writing, because it doesn’t tell me about sentence structure or grammar until I’ve finished my thought and saved.</li>
<li><strong>Configuration Files</strong> in Neovim are a dream for any system admin that doesn’t have the luxury of a desktop or are using a remote server. Tab out files, read other contents into an existing file, and have a file explorer with full undo logs. I could go on, but you get the idea.</li>
<li><strong>Coding</strong> is where most people’s mind goes with Neovim. You have the rockstars, like primeagen, that make Neovim look like a tool of the gods and mere mortals use other editors.</li>
</ul>
<h2 data-sanitized-id="installation">Installation</h2>
<p>With Neovim being so young in releases the latest release you can get is the best. Anything below 0.7 is too low as it won’t have the features you will need for the best experience. I highly recommend downloading directly from Neovim’s GitHub releases: <a href="https://github.com/Neovim/Neovim/releases/tag/stable">https://github.com/Neovim/Neovim/releases/tag/stable</a></p>
<p>All dependencies and requirements are in my setup.sh for Linux and winsetup.ps1 for Windows from: <a href="https://github.com/ChrisTitusTech/Neovim">https://github.com/ChrisTitusTech/Neovim</a></p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">git clone https://github.com/christitustech/Neovim
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">cd Neovim
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">sudo ./setup.sh
</span></span></code></pre></div><h3 data-sanitized-id="windows-powershell-alternative">Windows PowerShell Alternative</h3>
<p>I modified PowerShell to also use Neovim. I did make a <code>winsetup.ps1</code> to help aid in the setup, but there will be more manual steps to this setup.</p>
<p>Included cpp compiler and runtime to assist in programming, but the biggest thing to setup is nodejs. This has an automated script that will fix python and other dependencies that are problematic in Windows.</p>
<p>Setting PATH in Windows is your biggest priority for a functional Neovim. Type <code>sysdm.cpl</code> to launch into System Properties and click Advanced -&gt; Environment Variables to set the paths. Add any missing health checks here.</p>
<h2 data-sanitized-id="configuration">Configuration</h2>
<p>Instead of making a big modular structure that you see in most Neovim projects, mine is small for ease of learning. It will expand as times goes on, but I want to KISS it… Keep it stupid simple. There is 3 files:</p>
<ul>
<li><code>init.lua</code> - Initializes Neovim and calls any extra files. These are my main settings and special plugin configurations. _Note: some people use the old <code>init.vim</code> instead of lua, but that defeats the purpose of using Neovim.</li>
<li><code>lua/keymaps.lua</code> - These are all my key bindings for Neovim</li>
<li><code>lua/plugins.lua</code> - List of plugins to load.</li>
</ul>
<h2 data-sanitized-id="startup">Startup</h2>
<p>USE <code>:checkhealth</code> FIRST!</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/neovim-is-better/checkhealth.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>Errors must be fixed to have a functional Neovim experience. Warnings can be ignored, but noted, because you may have failed installs for LSPs, Linters, and other tools.</p>
<h3 data-sanitized-id="adding-tools">Adding Tools</h3>
<p><code>:Mason</code></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/neovim-is-better/mason.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><em>Note: I recommend ONLY installing what you USE!</em></p>
<p>Shortcuts for Mason:</p>
<ul>
<li>i = install</li>
<li>U = upgrade package</li>
<li>X = remove package</li>
</ul>
<h2 data-sanitized-id="what-not-to-do">What NOT to do</h2>
<p>Neovim is such a powerful editor that it can do anything. Before you do this, ask yourself, “Do I use this?” and if not, do NOT install it!</p>
<p>If you want all the plugins and have every language supported, I’d recommend Lunar vim or NvChad. These projects do a fantastic job of emulating every part of vscode, while also having an easy install and setup.</p>
<p>I’d recommend installing them to see what Neovim is capable of, but I did NOT like them for the long term. This is because Neovim needs a personal touch to see its true power.</p>
<p>I fell in love with Neovim once I started to add the features I used. Remember, you can always expand later.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/6VbOLOuiHUI?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/Windows-22H2-problems/
title: Windows 22H2 has Problems
link: https://christitus.com/Windows-22H2-problems/
hash: �5 ���p�K�ۚ;#
attributes: {"enclosures":[]}
content:
<p>I’ve had a ton of bug reports from 22H2. DO NOT UPDATE to this first Windows 11 update.</p>
<h2 data-sanitized-id="the-nature-of-updates-and-security">The Nature of Updates and Security</h2>
<blockquote>
<p>Security is a journey, not a destination - Ralph Waldo Emerson</p>
</blockquote>
<p>The instinct for any Journalist, YouTuber, Media Personality, or Technical Writer to make a sensational title. This one could be “Windows 22H2 is a Nightmare and it will steal the DNA from your babies.”</p>
<p>That would get a stupid amount of views and ad revenue, but it wouldn’t teach you anything. Instead we need to understand the nature of update and with that knowledge, we will be better computer users.</p>
<p>Any system that updates frequently will have bugs. Fix two bugs… One more appears. This is the nature of computing.</p>
<h2 data-sanitized-id="microsoft-known-issues-and-updates">Microsoft Known Issues and Updates</h2>
<p>Source article: <a href="https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-22h2">https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-22h2</a></p>
<p><em>Issues on 10-22-2022</em></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/Windows-22H2-problems/ms-known-issues.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><em>Issues update on 10-31-2022</em></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/Windows-22H2-problems/issue-update.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="should-you-update">Should you Update?</h2>
<p>HELL NO!</p>
<p>Being on the newest release of anything can be fun and dealing with new shining features is a blast, but it comes with a cost. You will experience issues and more “known issues” will appears as more and more users adopt it. Microsoft doesn’t have a good quality control department and I wait AT LEAST 1 year after feature updates hit the market before upgrading. For my Windows instances, I wait 2 years.</p>
<h2 data-sanitized-id="is-windows-bad-at-updates">Is Windows Bad at Updates?</h2>
<p>This isn’t a yes or no answer, but the more complex and old a system is, the greater margin for errors to occur. The foundation of Windows hasn’t drastically changed in decades and this makes updating the platform a monumental task for even the mammoth corporation that is Microsoft.</p>
<p>Microsoft has some talented employees, but it takes time to add polish and with new feature updates pushed out the door every 6 months… Expect this to be a trend for ALL future feature updates.</p>
<h2 data-sanitized-id="source-articles">Source Articles</h2>
<ul>
<li><a href="https://pureinfotech.com/windows-11-22h2-bug-remote-desktop/">https://pureinfotech.com/windows-11-22h2-bug-remote-desktop/</a></li>
<li><a href="https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-22h2">https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-22h2</a></li>
<li><a href="https://windowsreport.com/windows-11-22h2-bugs/">https://windowsreport.com/windows-11-22h2-bugs/</a></li>
<li><a href="https://www.techradar.com/news/windows-11-22h2-bug-breaks-windows-hello-security-feature">https://www.techradar.com/news/windows-11-22h2-bug-breaks-windows-hello-security-feature</a></li>
<li><a href="https://www.thurrott.com/forums/microsoft/windows/thread/major-bugs-in-win10-22h2">https://www.thurrott.com/forums/microsoft/windows/thread/major-bugs-in-win10-22h2</a></li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ITI1HaFeq_g?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: yt:video:JfHoXEXwdCg
title: How to Add Dividers to Dropdown Menus in After Effects
author: ;ukramedia
link: https://www.youtube.com/watch?v=JfHoXEXwdCg
hash: �<�mb�4�.<��6�a
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/JfHoXEXwdCg?version=3","title":"How to Add Dividers to Dropdown Menus in After Effects","description":"/// About:\n     In this video, I will show you how to quickly add dividers inside dropdown menus in Adobe After Effects.\n\n     *** Learn more about how to use the Dropdown Menu in After Effects by watching this tutorial: https://youtu.be/nPTNtwSx9SE.\n\n/// Let's Connect:\n     Facebook: https://www.facebook.com/ukramedia\n     Sergei's Facebook Page: https://www.facebook.com/sergeiprokhn...\n     Twitter: https://twitter.com/ukramedia\n     TikTok: https://www.tiktok.com/@ukramedia\n     Instagram: https://www.instagram.com/ukramedia/\n     Pinterest: https://www.pinterest.com/ukramedia/\n     Linkedin: https://www.linkedin.com/company/ukra...\n     YouTube: https://www.youtube.com/c/ukramedia\n     Ukramedia Online Community: https://www.ukramedia.com/community\n\n##AfterEffects #AdobeAfterEffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i3.ytimg.com/vi/JfHoXEXwdCg/hqdefault.jpg"]}]}


guid: https://christitus.com/shell-the-essential-app/
title: Shell The Essential App
link: https://christitus.com/shell-the-essential-app/
hash: 5�eY����n'{p�
attributes: {"enclosures":[]}
content:
<p>Context menus have become worse in Windows 11 and weren’t good in Windows 10. This application will fix it for both modern Windows operating systems.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Do you feel context menus have become worse in Windows 11?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1587824008342429696?ref_src=twsrc%5Etfw">November 2, 2022</a></blockquote>

<h2 data-sanitized-id="the-app">The App</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/shell-the-essential-app/shell.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>I install this app in both Windows 10 and Windows 11. Here is a breakdown of all the context menus that it adds and expands.</p>
<ul>
<li>Access the terminal from anywhere (hold shift to run as admin)</li>
<li>Expanded Files (Create New, Copy Path, and Show hidden)</li>
<li>Developer Options (Vs code launch, build from explorer, etc.)</li>
<li>Goto Shortcuts (Common files and folders, System settings, etc.)</li>
<li>Common sense copy and paste</li>
<li>Create Shortcuts</li>
<li>Program your own command!</li>
</ul>
<p><img loading="lazy" src="https://christitus.com/images/2022/shell-the-essential-app/menu.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="build-your-own-menu-and-items">Build your own menu and items</h2>
<p>Shell is extremely easy to add commands and custom menus. Launch custom commands with arguments. Here is a quick how-to:</p>
<p>Open <code>C:\Program Files\Nilesoft\Shell\shell.shl</code></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/shell-the-essential-app/shl.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>Add a custom command and pass arguments by editing the dynamic JSON section:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">dynamic
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">{
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> item(title='Chris Titus Tech YouTube' cmd='C:\Users\Subscribe\AppData\Local\BraveSoftware\Brave-Browser\Application\brave.exe' args='https://youtube.com/c/ChrisTitusTech')
</span></span></code></pre></div><p>The basic syntax is :</p>
<blockquote>
<p>item(title=‘sample title’ cmd=‘executable path and exe’ args=‘extra commands’)</p>
</blockquote>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/s6YINpJb2dc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/fix-corrupt-windows-install/
title: Fix Corrupted Windows Install
link: https://christitus.com/fix-corrupt-windows-install/
hash: �s � ���l��
attributes: {"enclosures":[]}
content:
<p>Using SFC and DISM is often done in haste and incorrectly. If you need to fix a corrupted install, then a special DISM command MUST BE issued.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Do you know how to restore corrupt windows features using DISM and source the files from a windows ISO?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1587911136879542273?ref_src=twsrc%5Etfw">November 2, 2022</a></blockquote>

<h2 data-sanitized-id="the-commands">The Commands</h2>
<h3 data-sanitized-id="basic-online-command">Basic Online Command</h3>
<p><img loading="lazy" src="https://christitus.com/images/2022/fix-corrupt-windows-install/dism-normal.webp" alt="" data-sanitized-class="img-fluid"> </p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">DISM /Online /Cleanup-Image /CheckHealthDISM /Online /Cleanup-Image /CheckHealth
</span></span></code></pre></div><p><em>Note: This will check it’s health and cleanup basic corruption errors.</em></p>
<h3 data-sanitized-id="command-to-fix-from-windows-iso">Command to Fix From Windows ISO</h3>
<p>Use this command when the basic one fails. Follow these steps:</p>
<ol>
<li>Download the Windows ISO from <a href="https://www.microsoft.com/en-us/software-download/windows10ISO">https://www.microsoft.com/en-us/software-download/windows10ISO</a></li>
<li>Mount the ISO and note the drive letter (ex. E:)</li>
<li>Run DISM with sources flag</li>
</ol>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">DISM /Online /Cleanup-Image /RestoreHealth /Source:E:\Sources\install.wim
</span></span></code></pre></div><p><em>Note: <code>install.wim</code> is known as ESD in some downloads <code>install.esd</code></em></p>
<h2 data-sanitized-id="verify-history-and-logs">Verify History and Logs</h2>
<p>Did it run correctly? Was the corruption repaired?</p>
<p>Check the log file at <code>%windir%\Logs\DISM\dism.log</code></p>
<h2 data-sanitized-id="sfc---the-worthless-tool">SFC - The Worthless Tool</h2>
<p>System file checker is WORTHLESS! In the best scenario it might tell you about some corruption, but I have never seen it actually repair anything.</p>
<p>Yet every damn guide on the internet recommends you run it. Save your time, and use DISM instead.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/jZoR4MayBu0?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/5-terminal-commands/
title: 5 Essential Terminal Utilities
link: https://christitus.com/5-terminal-commands/
hash: ڌ��>7��/=�+'<�
attributes: {"enclosures":[]}
content:
<h2 data-sanitized-id="tldr">TLDR</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/5-terminal-commands/tldr.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>Too long didn’t read? The perfect solution for long man pages that we just want some quick examples and basic syntax for a command. TLDR is a vital tool to save you time when learning the terminal.</p>
<h2 data-sanitized-id="cmatrix">CMatrix</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/5-terminal-commands/cmatrix.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>How can you use Linux without using CMatrix… It’s hard to be cool without it.</p>
<h2 data-sanitized-id="trash-cli">Trash-CLI</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/5-terminal-commands/trash-cli.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>This is a life saver after you delete a directory or files in terminal and need to get them back. I highly recommend making the following alias in your <code>~/.bashrc</code> file.</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">alias rm='trash -v'
</span></span></code></pre></div><ul>
<li>
<p>Delete a file and send it to the trash:
<code>trash path/to/file</code></p>
</li>
<li>
<p>List all files in the trash:
<code>trash-list</code></p>
</li>
<li>
<p>Interactively restore a file from the trash:
<code>trash-restore</code></p>
</li>
<li>
<p>Empty the trash:
<code>trash-empty</code></p>
</li>
<li>
<p>Permanently delete all files in the trash which are older than 10 days:
<code>trash-empty 10</code></p>
</li>
<li>
<p>Remove all files in the trash, which match a specific blob pattern:
<code>trash-rm "*.o"</code></p>
</li>
<li>
<p>Remove all files with a specific original location:
<code>trash-rm /path/to/file_or_directory</code></p>
</li>
</ul>
<h2 data-sanitized-id="autojump">Autojump</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/5-terminal-commands/autojump.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>This is my most used terminal utility that saves me the most amount of time. The catch to this program is you must have navigated to the directory at least once in terminal first.</p>
<ul>
<li>
<p>Jump to a directory that contains the given pattern:
<code>j pattern</code></p>
</li>
<li>
<p>Jump to a sub-directory (child) of the current directory that contains the given pattern:
<code>jc pattern</code></p>
</li>
<li>
<p>Open a directory that contains the given pattern in the operating system file manager:
<code>jo pattern</code></p>
</li>
<li>
<p>Remove non-existing directories from the autojump database:
<code>j --purge</code></p>
</li>
<li>
<p>Show the entries in the autojump database:
<code>j -s</code></p>
</li>
</ul>
<h2 data-sanitized-id="progress">Progress</h2>
<p>Tired of wondering how much longer the cp, mv, dd, tar, cat, and other Linux coreutil functions take? Progress will tell you!</p>
<ul>
<li>
<p>Show the progress of running coreutils:
<code>progress</code></p>
</li>
<li>
<p>Launch and monitor a single long-running command:
<code>command &amp; progress --monitor --pid $!</code></p>
</li>
<li>
<p>Include an estimate of time remaining for completion:
<code>progress --wait --command rsync</code></p>
</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/HKB8RUWZIQA?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/why-we-dont-browse-the-internet-anymore/
title: Why We Don't Browse the Internet Anymore
link: https://christitus.com/why-we-dont-browse-the-internet-anymore/
hash: %ԅęi�z[ڹN�E�
attributes: {"enclosures":[]}
content:
<p>The problem with the modern internet is ads, sponsored posts, and pay walls. Enter RSS feeds as a solution.</p>
<p>Subscribe to the sites and information you want to see and not have an algorithm decide what influences you. This requires “fixing” RSS and downloading articles, but the payout is amazing. How many people use RSS? Here is poll I ran on Twitter.</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Do you use RSS?</p>— Chris Titus Tech (@christitustech) <a href="https://twitter.com/christitustech/status/1589727064957284352?ref_src=twsrc%5Etfw">November 7, 2022</a></blockquote>

<h2 data-sanitized-id="how-we-used-to-browse-the-internet">How we used to browse the Internet</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/why-we-dont-browse-the-internet-anymore/altavista.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>The era of altavista, dogpile, askjeeves, yahoo, excite, lycos, and others was an era of innovation and competition. There was a heated rivalry between Internet Exploader and Netscape, which Microsoft inevitably won with dirty business practices. That era was a time of discovery and businesses were figuring out how to make money on the internet.</p>
<p>Information was scattered everywhere and the web was decentralized among hundreds of companies. When we “logged on” you made decisions on what to do. Sometimes you wanted to play a game, or stumble upon a new website, or browse a news group. Almost nothing curated and uniform. This is often referred to as Web 1.0.</p>
<h2 data-sanitized-id="how-we-use-the-internet-today">How we use the Internet today</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/why-we-dont-browse-the-internet-anymore/google.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>We google anything we want, use our chromium browsers, and social media for everything else. Between Google, Facebook (I’m not calling it Meta), and Amazon we have everything. Facebook is dying off and for old people raging about some political garbage, Amazon we order anything want to appear on our doorstep, and Google is what powers almost every search we do.</p>
<p>When we find the site we are looking for, it ends up with tons of ads or paywalled. Even worse, some reputable sites sell “sponsored posts” where the advertising gets posted directly in the feed. Imagine watching a television show and then in the third episode its nothing but a giant Subway ad. This is our modern internet.</p>
<h2 data-sanitized-id="how-to-fix-it-with-rss">How to fix it with RSS</h2>
<p>Really Simple Syndication or RSS for short, is used to get updates from websites whenever something is posted. You have a listing of the entire website and you can pick the article you want to read. Even better you can subscribe to YouTube Channels and other social feeds to RSS as well.</p>
<p>The problem? Ads, Brief Summaries, and redirects. We fix this by using a feed aggregator and never leave our RSS reader.</p>
<p>The other problem with RSS Readers online are expensive using feedly($8), inoreader($10), and newsblur($3) per month. This used all be free with Google Reader, but in typical Google fashion they killed Reader.</p>
<h3 data-sanitized-id="feed-aggregation">Feed Aggregation</h3>
<p>I use docker self-hosted aggregator <a href="https://github.com/heussd/fivefilters-full-text-rss-docker">https://github.com/heussd/fivefilters-full-text-rss-docker</a> or if you want to pay money you can use <a href="http://ftr.fivefilters.org/">five filters aggregator</a></p>
<p>Here is my docker command to install and configure it on my docker server using port 50000</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">docker run -d \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">--name=full-test-rss \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">-p 50000:80 \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">--restart always \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">heussd/fivefilters-full-text-rss:latest
</span></span></code></pre></div><h3 data-sanitized-id="feed-reader">Feed Reader</h3>
<p>There are a couple different ways to pull in these RSS feeds. For browsers there is Vivaldi, external programs like Obsidian, and for self-hosted I recommend <a href="https://freshrss.org/">FreshRSS</a></p>
<p>I use my docker server again to host this on port 49999</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">docker run -d \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> --name=freshrss \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e PUID=1000 \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e PGID=1000 \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e TZ=Europe/London \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -p 49999:80 \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -v /path/to/data:/config \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> --restart unless-stopped \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> lscr.io/linuxserver/freshrss:latest
</span></span></code></pre></div><h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/nxV0CPNeFxY?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/best-browser-extensions/
title: Best Browser Extensions
link: https://christitus.com/best-browser-extensions/
hash: ��-��}��L@��m
attributes: {"enclosures":[]}
content:
<p>These extensions make life easier when using a browser.</p>
<h2 data-sanitized-id="the-list">The List</h2>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/authenticator/bhghoamapcdpbohphigoooaddinpkbai">Authenticator</a> - 2 Factor for websites</li>
<li><a href="https://chrome.google.com/webstore/detail/checker-plus-for-google-c/hkhggnncdpfibdhinjiegagmopldibha">Checker Plus</a> - Google Calendar with 1-click</li>
<li><a href="https://chrome.google.com/webstore/detail/clickclean/ghgabhipcejejjmhhchfonmamedcbeod">Click and Clean</a> - History and Cache cleaning</li>
<li><a href="https://chrome.google.com/webstore/detail/get-rss-feed-url/kfghpdldaipanmkhfpdcjglncmilendn">Get RSS Feed URL</a> - Easily grab the RSS feed for a website</li>
<li><a href="https://chrome.google.com/webstore/detail/gofullpage-full-page-scre/fdpohaocaechififmbbbbbknoalclacl">GoFullPage</a> - Full Page Screen Capture</li>
<li><a href="https://chrome.google.com/webstore/detail/midnight-lizard/pbnndmlekkboofhnbonilimejonapojg">Midnight Lizard</a> - Dark mode everywhere</li>
<li><a href="https://chrome.google.com/webstore/detail/momentum/laookkfknpbbblfpciffpaejjkokdgca">Momentum</a> - Focused Start Screen (Great for Brave users)</li>
<li><a href="https://chrome.google.com/webstore/detail/notifier-for-github/lmjdlojahmbbcodnpecnjnmlddbkjhnn">Notifier for GitHub</a> - Notification Panel for GitHub</li>
<li><a href="https://www.anrdoezrs.net/click-9109049-14329390">Roboform Password Management</a> (Bitwarden is a good alternative)</li>
<li><a href="https://chrome.google.com/webstore/detail/web-highlights-pdf-web-hi/hldjnlbobkdkghfidgoecgmklcemanhm">Web Highlights</a> - Highlight parts of a webpage</li>
</ul>
<h3 data-sanitized-id="security">Security</h3>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/auth.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Authenticator</strong> is great for simple two factor, but I wouldn’t use this for a bank account. These 2FA codes are synced to the cloud for convenience.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/clickandclean.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Click and Clean</strong> will clean our history, cache, and much more. The built in browser cleaning and history management isn’t good. This makes it a complete solution for security, privacy, and maintenance.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/roboform.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Password Manager</strong> is something everyone should use. I’ve used <a href="https://www.anrdoezrs.net/click-9109049-14329390">RoboForm</a> for over 10 years and my personal recommendation for automation. Bitwarden is a bit newer and some features like FIDO keys which make also makes it a strong choice. Both password manager offer easy export and import of ALL passwords, which is a vital feature when you use these services to avoid getting “locked in”.</p>
<p><em>Note: Roboform is currently running a 50% off sale via the link above for Cyber Monday/Black Friday and generally provide a 30% off link after.</em></p>
<p>The one thing I caution you against is using All-In-One password managers, like McAfee, Nord, and others. The bundles you get will lock you in to their password managers that can hold you hostage if they have breaches and you want to move on.</p>
<h3 data-sanitized-id="convenience">Convenience</h3>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/checker-plus.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Checker Plus</strong> perfect heads up calendar display with easy add for incoming events.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/rss-feeds.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Get RSS Feed URL</strong> will get those hidden RSS feeds for any website.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/fullscreen.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>GoFullPage</strong> captures the ENTIRE webpage and can output it to a PDF or PNG for later use.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/midnight-lizard.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Midnight Lizard</strong> Dark mode and other color customizations.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/momentum.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Momentum</strong> is an essential extension for any brave browser user. Brave has one of the worst start screens with crypto ads and other BS that no one likes. This extension fixes that.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/github-notifications.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Notifier for GitHub</strong> shows GitHub notifications.</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/best-browser-extensions/highlights.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p><strong>Web Highlights</strong> is a great way to highlight a page as you read, which helps your mind retain what you are reading, but also saves it into the logged in account which can be referred to later.</p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/j-eK_T-FWIo?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://christitus.com/one-tool-for-everything/
title: One Tool for Everything
link: https://christitus.com/one-tool-for-everything/
hash: rUv�dM��� J+��
attributes: {"enclosures":[]}
content:
<p>A massive update has arrived for the Windows Utility! Check out all the new features.</p>
<p>Run Directly from PowerShell with Admin</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">irm christitus.com/win | iex
</span></span></code></pre></div><h2 data-sanitized-id="new-features">New Features</h2>
<ul>
<li>Tooltip addition to Tweaks</li>
<li>Auto Login Added</li>
<li>Manually Set DNS Servers</li>
<li>Large number of new program additions</li>
</ul>
<h2 data-sanitized-id="bug-fixes">Bug Fixes</h2>
<ul>
<li>Program installed pops up before install complete</li>
<li>Improved Readme on Github</li>
<li>Better Scaling for large monitors</li>
<li>Undo Tweak Fixes</li>
<li>Better Button Placement</li>
</ul>
<h2 data-sanitized-id="live-tracker">Live Tracker</h2>
<p><a href="https://github.com/users/ChrisTitusTech/projects/1/views/1">https://github.com/users/ChrisTitusTech/projects/1/views/1</a></p>
<h2 data-sanitized-id="new-tweak-options">New Tweak Options</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/one-tool-for-everything/tweaks.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="github-project">GitHub Project</h2>
<p>Check out the official Github page @ <a href="https://github.com/ChrisTitusTech/winutil">https://github.com/ChrisTitusTech/winutil</a></p>
<h2 data-sanitized-id="donate-and-get-the-executable">Donate and Get the Executable</h2>
<p>Want to run from an exe file? Donate $10 @ <a href="https://www.cttstore.com/windows-toolbox">https://www.cttstore.com/windows-toolbox</a></p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/vXyMScSbhk4?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: yt:video:Q3pFqdaZWV4
title: Smart Anchor: The AE Tool You Never Knew You Needed
author: ;ukramedia
link: https://www.youtube.com/watch?v=Q3pFqdaZWV4
hash: T�at��?AZ�k�#m=
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/Q3pFqdaZWV4?version=3","title":"Smart Anchor: The AE Tool You Never Knew You Needed","description":"*/// About*\nIntroducing Smart Anchor - the ultimate time-saving tool for After Effects users! With Smart Anchor, you can easily adjust the anchor point on the fly, streamlining your workflow and allowing you to focus on creating stunning visual effects. But that's just the beginning - Smart Anchor also includes a host of other features that make it an essential addition to any After Effects toolkit. Check out the trailer video to see Smartanchor in action and see how it can revolutionize your AE workflow.\n\n*/// Chapters*\n00:00 - Adjust Anchors For Multiple Layers\n00:11 - Save Clicks with CTRL + CLICK Shortcut\n00:20 - Advanced Text Height Options\n00:45 - Lock Anchors To Custom Positions\n01:07 - Adjustable Layer Anchor Points\n01:26 - Ignore Ascenders &amp; Descenders When Centering Text\n01:43 - Set Anchors At Custom Layer Time\n02:02 - Quickly Remove Smart Anchors From Selected Layers\n02:11 - Where To Get Smart Anchor 2.0\n\n*/// Smart Tools Links*\nSmart Anchor: https://ukramedia.com/product/smart-anchor/\nSmart Tools Bundle: https://ukramedia.com/product/smart-t...\n\n*/// What's New In Smart Anchor 2.0*\n- *SCRIPT UI CHANGES*\n    - The Run button has been added and it changed the main functionality of the script. In the previous versions of Smart Anchor, the user had to click on any Anchor Point buttons to run the script. Now, the script runs when the Run button is clicked. This means that the Anchor Point buttons are now selectable. The main reason for this change is to stay consistent with the workflow of our other Smart Tools.\n    - Users can still apply Smart Anchor the old way without the Run button by holding down Control and clicking on any Anchor Point buttons.\n    - Separate Code Mode buttons were added to the top shelf.\n    - Tabs were introduced to separate Anchor, Text Height, and Anchor Time At. This will help to keep the UI more compact when new features are added in the future.\n    - Global Reset buttons were added to reset values in a single tab or multiple tabs\n    - A new Text Height tab has been added with 3 layer text height options: Full Height, Cap Height, and x-Height.\n    - A Custom Time text field has been added to manually insert the custom Anchor At Time value.\n    - The Get Comp Time button has been added to quickly insert the comp time into the Custom Time text field.\n    - The Remove Smart Anchor function has been fixed. The layer position doesn’t change when the Remove Smart Anchor button is pressed.\n\n- *PSEUDO EFFECT CHANGES*\n    - Anchor Based On Time properties have been simplified and no longer have separate X &amp; Y properties.\n    - Text x-Height Offset slider was added to allow users to manually adjust the x-Height value. This is needed because not all fonts have the same x-Height value.\n    - Additional Anchor Point options were added to the Y Anchor Point dropdown menu. These new Anchor Point options are for Text layers and will help users when creating Motion Graphic Templates (MoGrts).\n        - Top (Text x-Height)\n        - Top (Text Baseline)\n        - Center (Text Cap Height)\n        - Center (Text x-Height)\n        - Bottom (Text Baseline)\n    - The Custom Time property gets automatically updated each time the user runs the script. The updated Custom Time value comes from the Anchor At Time selection in the Script UI.\n    - Dividers were added to all dropdown menus to separate items.\n- *CODE CHANGES*\n    - The Expressions Code has been updated.\n\n*/// How To Upgrade to Smart Anchor 2.0*\nIf you purchased Smart Anchor or Smart Tools bundle from us in the past, you automatically get free upgrades. This means you also get Smart Anchor 2.0 for free at ukramedia.com. Thank you for your support!\n\n*/// Let's Connect*\nFacebook: https://www.facebook.com/ukramedia\nSergei's Facebook Page: https://www.facebook.com/sergeiprokhn...\nTwitter: https://twitter.com/ukramedia\nTikTok: https://www.tiktok.com/@ukramedia\nInstagram: https://www.instagram.com/ukramedia/\nPinterest: https://www.pinterest.com/ukramedia/\nLinkedin: https://www.linkedin.com/company/ukra...\nYouTube: https://www.youtube.com/c/ukramedia\nUkramedia Online Community: https://www.ukramedia.com/community\n\n#AeScripts #AfterEffects #AdobeAfterEffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i2.ytimg.com/vi/Q3pFqdaZWV4/hqdefault.jpg"]}]}


guid: https://christitus.com/docker-macos/
title: Docker Macos
link: https://christitus.com/docker-macos/
hash: z�rmK[ _�Cw��
attributes: {"enclosures":[]}
content:
<p>Don’t have a Mac and need MacOS? No problem, run it in a docker container.</p>
<p>Credit goes to this twitter user:</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr">Anthony <a href="https://twitter.com/LinusTech?ref_src=twsrc%5Etfw">@LinusTech</a> and <a href="https://twitter.com/christitustech?ref_src=twsrc%5Etfw">@christitustech</a> need to check out this project:<a href="https://t.co/ctx41h0j25">https://t.co/ctx41h0j25</a><br><br>It offers macOS Catalina, Big Sur, Monterey, High Sierra, and Mojave as Docker images.<br><br>PS:<br>Someone please tell me what's Anthony's twitter handle. I need to follow that man.</p>— Arinze (@justArRinze) <a href="https://twitter.com/justArRinze/status/1591779981390413826?ref_src=twsrc%5Etfw">November 13, 2022</a></blockquote>

<h2 data-sanitized-id="requirements">Requirements</h2>
<p>Install Docker Ubuntu 22.04</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="gdscript3" data-sanitized-class="language-gdscript3"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">sudo</span> <span data-sanitized-class="n">apt</span> <span data-sanitized-class="n">install</span> <span data-sanitized-class="n">apt</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">transport</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">https</span> <span data-sanitized-class="n">ca</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">certificates</span> <span data-sanitized-class="n">curl</span> <span data-sanitized-class="n">software</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">properties</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">common</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">y</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">curl</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">fsSL</span> <span data-sanitized-class="n">https</span><span data-sanitized-class="p">:</span><span data-sanitized-class="o">//</span><span data-sanitized-class="n">download</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">docker</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">com</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">linux</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">ubuntu</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">gpg</span> <span data-sanitized-class="o">|</span> <span data-sanitized-class="n">sudo</span> <span data-sanitized-class="n">apt</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">key</span> <span data-sanitized-class="n">add</span> <span data-sanitized-class="o">-</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">sudo</span> <span data-sanitized-class="n">add</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">apt</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">repository</span> <span data-sanitized-class="s2">"deb [arch=amd64] https://download.docker.com/linux/ubuntu jammy stable"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">sudo</span> <span data-sanitized-class="n">apt</span> <span data-sanitized-class="n">install</span> <span data-sanitized-class="n">docker</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">ce</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">y</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">sudo</span> <span data-sanitized-class="n">usermod</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">aG</span> <span data-sanitized-class="n">docker</span> <span data-sanitized-class="o">$</span><span data-sanitized-class="n">USER</span>
</span></span></code></pre></div><p><strong>Reboot or logout/login</strong></p>
<p>(Optional) GUI Webpage for Managing Docker - Portainer</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="gdscript3" data-sanitized-class="language-gdscript3"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">docker</span> <span data-sanitized-class="n">volume</span> <span data-sanitized-class="n">create</span> <span data-sanitized-class="n">portainer_data</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">docker</span> <span data-sanitized-class="n">run</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">d</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">p</span> <span data-sanitized-class="mi">8000</span><span data-sanitized-class="p">:</span><span data-sanitized-class="mi">8000</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">p</span> <span data-sanitized-class="mi">9443</span><span data-sanitized-class="p">:</span><span data-sanitized-class="mi">9443</span> <span data-sanitized-class="o">--</span><span data-sanitized-class="n">name</span> <span data-sanitized-class="n">portainer</span> \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">--</span><span data-sanitized-class="n">restart</span><span data-sanitized-class="o">=</span><span data-sanitized-class="n">always</span> \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">-</span><span data-sanitized-class="n">v</span> <span data-sanitized-class="o">/</span><span data-sanitized-class="k">var</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">run</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">docker</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">sock</span><span data-sanitized-class="p">:</span><span data-sanitized-class="o">/</span><span data-sanitized-class="k">var</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">run</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">docker</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">sock</span> \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="o">-</span><span data-sanitized-class="n">v</span> <span data-sanitized-class="n">portainer_data</span><span data-sanitized-class="p">:</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">data</span> \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">portainer</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">portainer</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">ce</span><span data-sanitized-class="p">:</span><span data-sanitized-class="mf">2.9</span><span data-sanitized-class="o">.</span><span data-sanitized-class="mi">3</span>
</span></span></code></pre></div><p>Open up browser and navigate to <a href="https://localhost:9443/">https://localhost:9443</a></p>
<p><em>Click Advanced and proceed with any certificate errors</em></p>
<h2 data-sanitized-id="macos-docker-setup">MacOS Docker Setup</h2>
<p>Setup the MacOS Docker Container with the following docker command</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">docker run -it \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> --device /dev/kvm \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -p 50922:10022 \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -v /tmp/.X11-unix:/tmp/.X11-unix \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e "DISPLAY=${DISPLAY:-:0.0}" \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e GENERATE_UNIQUE=true \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> -e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"> sickcodes/docker-osx:monterey
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl">
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"># docker build -t docker-osx --build-arg SHORTNAME=monterey .
</span></span></code></pre></div><p>Use Disk Utility to “erase” the 270GB virtual disk: <em>Note: This is just virtual and doesn’t erase your drive</em></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/docker-macos/disk-util.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="start-macos-docker-container">Start MacOS Docker Container</h2>
<p>Before we start the container find the name with:</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">docker ps -a
</span></span></code></pre></div><p><em>Look for the NAMES column and pick the container name.</em></p>
<p><img loading="lazy" src="https://christitus.com/images/2022/docker-macos/container.webp" alt="" data-sanitized-class="img-fluid"> </p>
<p>Start with the following command NAME = Name from column above</p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">docker start NAME
</span></span></code></pre></div><h3 data-sanitized-id="portainer-method-for-starting">Portainer Method for Starting</h3>
<p>I love portainer because you can easily manage your containers. Start, Stop, and see resource usage… Portainer does it all! Here is what mine looks like:</p>
<p><img loading="lazy" src="https://christitus.com/images/2022/docker-macos/portainer.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="optimize-the-container">Optimize the Container</h2>
<p>Source: <a href="https://github.com/sickcodes/osx-optimizer">https://github.com/sickcodes/osx-optimizer</a></p>
<p>Run the following from Root Prompt # <code>sudo su</code></p>
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="gdscript3" data-sanitized-class="language-gdscript3"><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">loginwindow</span> <span data-sanitized-class="n">autoLoginUser</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">true</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">mdutil</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">i</span> <span data-sanitized-class="n">off</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="n">a</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">nvram</span> <span data-sanitized-class="n">boot</span><span data-sanitized-class="o">-</span><span data-sanitized-class="n">args</span><span data-sanitized-class="o">=</span><span data-sanitized-class="s2">"serverperfmode=1 $(nvram boot-args 2&gt;/dev/null | cut -f 2-)"</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="o">/</span><span data-sanitized-class="n">Library</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">Preferences</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">loginwindow</span> <span data-sanitized-class="n">DesktopPicture</span> <span data-sanitized-class="s2">""</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Accessibility</span> <span data-sanitized-class="n">DifferentiateWithoutColor</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Accessibility</span> <span data-sanitized-class="n">ReduceMotionEnabled</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">universalaccess</span> <span data-sanitized-class="n">reduceMotion</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">universalaccess</span> <span data-sanitized-class="n">reduceTransparency</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">Accessibility</span> <span data-sanitized-class="n">ReduceMotionEnabled</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">1</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="o">/</span><span data-sanitized-class="n">Library</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">Preferences</span><span data-sanitized-class="o">/</span><span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">AutomaticDownload</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">false</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">AutomaticCheckEnabled</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">false</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">commerce</span> <span data-sanitized-class="n">AutoUpdate</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">false</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">commerce</span> <span data-sanitized-class="n">AutoUpdateRestartRequired</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">false</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">ConfigDataInstall</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">CriticalUpdateInstall</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">ScheduleFrequency</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">SoftwareUpdate</span> <span data-sanitized-class="n">AutomaticDownload</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">int</span> <span data-sanitized-class="mi">0</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">loginwindow</span> <span data-sanitized-class="n">DisableScreenLock</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">true</span>
</span></span><span data-sanitized-class="line"><span data-sanitized-class="cl"><span data-sanitized-class="n">defaults</span> <span data-sanitized-class="n">write</span> <span data-sanitized-class="n">com</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">apple</span><span data-sanitized-class="o">.</span><span data-sanitized-class="n">loginwindow</span> <span data-sanitized-class="n">TALLogoutSavesState</span> <span data-sanitized-class="o">-</span><span data-sanitized-class="ne">bool</span> <span data-sanitized-class="bp">false</span>
</span></span></code></pre></div><h2 data-sanitized-id="final-result">Final Result</h2>
<p><img loading="lazy" src="https://christitus.com/images/2022/docker-macos/macos-final.webp" alt="" data-sanitized-class="img-fluid"> </p>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/XWo2gnNbeGQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://htmhell.dev/adventcalendar/2022/1/
title: How to transfigure wireframes into HTML
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/1/
hash: �i9�2-�f�݉�:���
attributes: {"enclosures":[]}
content:
<p>Soon enough in your career as a web developer, you encounter the situation where a designer hands over a wonderful web design in all its large-screen glory. Your mission now is to transform it into code to present a prototype as soon as possible, starting with nothing but an empty text file.</p>
<h2 data-sanitized-id="facts-questions-and-the-truth">Facts, questions and the truth</h2>
<p>This task comes with a few challenges and most of the time there’s no single correct way to do it. In this article, I’m going to describe how I personally approach these tasks.</p>
<p>Our goal for today is to build an HTML prototype for an online newspaper homepage, “The Weekly Prophet”. The only information we have is the following wireframe:</p>
<a href="https://htmhell.dev/images/advent2022/8/01-wireframe-initial.jpg">
<img src="https://htmhell.dev/images/advent2022/8/01-wireframe-initial.jpg" alt="A wireframe of a newspaper called “The weekly prophet”. There’s a large header on top and below a horizontal navigation bar. The main content are four sections filled with articles: “Top stories”, “Latest news”, “Most viewed”, and “What’s going on in Hogwarts?”. At the end of the page there’s a section with a newsletter subscription form and a footer with three lists of links." width="1402" height="3072">
</a>
<p>There’s a lot to unpack here.</p>
<p>The first important fact is that in HTML there’s no such thing as placing elements on a page next to each other (we need CSS—Cascading Style Sheets—for that). There’s just <strong>one element at a time</strong>. When there’s no one-column layout for small screen sizes provided by a designer, we need to define an order of elements on our own.</p>
<p>The next big questions, especially when you’re new to web development, are: <strong>where to start now?</strong> How do I know which elements I need to build this? How should they be nested?</p>
<p>The truth is, it is probably hard to come up with a final version of the HTML code without ever thinking about CSS and its features, because <strong>a lot of markup decisions are based on what CSS can do</strong>. As this article is purely about HTML, the outcome is most likely not complete, but a good starting point from a semantics and accessibility point of view.</p>
<h2 data-sanitized-id="semantics-and-accessibility">Semantics and accessibility</h2>
<p>HTML might look like an easy-to-learn language, but comes with a lot of (hidden) power. It’s the heart of every web page. The better you understand the meaning and functionality of certain tags and attributes, the better your code will be. Sure, you can build the whole newspaper homepage by just using <code>div</code> and <code>span</code> elements, but that’s not what we’re here for.</p>
<p>We are going to think about…</p>
<ul>
<li>the meaning of sections of the page</li>
<li>the document’s outline and hierarchy of the content</li>
<li>the interactivity of elements</li>
</ul>
<p>…because when you build a solid foundation, everything you add on top (i.e., styling with CSS and interaction with JavaScript) will be better. When working <em>with</em> the features HTML gives you and not against them, you can save a lot of time and code (and money) down the road. And as a nice side effect, you automatically build an accessible product that will make your users happy and this is what our work should be all about.</p>
<h2 data-sanitized-id="dont-think-outside-the-box">Don’t think outside the box</h2>
<p>Enough of the talking, let’s start coding!</p>
<p>Every time I see a web design or a wireframe, I immediately start imagining boxes. <a href="https://mxb.dev/blog/the-css-mindset/#h-everything-is-a-rectangle">On a website, every element is a box</a>, so I start grouping elements that belong together, draw boxes around them, and give them names.</p>
<a href="https://htmhell.dev/images/advent2022/8/02-wireframe-landmarks.jpg">
<img src="https://htmhell.dev/images/advent2022/8/02-wireframe-landmarks.jpg" alt="The same wireframe of a newspaper called “The weekly prophet” as described above. The important areas are highlighted and numbered from one to eight." width="1388" height="3072">
</a>
<p>I identified the following eight areas in the wireframe:</p>
<ol>
<li>Header</li>
<li>Navigation</li>
<li>Section: Top Stories</li>
<li>Section: Latest News</li>
<li>Section: Most viewed</li>
<li>Section What’s going on in Hogwarts?</li>
<li>Subscription form</li>
<li>Footer</li>
</ol>
<p>Sections three to six contain all the interesting articles from the main content of the page.</p>
<p>I don’t start coding a very specific element on the page, but always begin with the overall page structure, the large content elements and then work my way <strong>from the outside to the inside</strong>.</p>
<h2 data-sanitized-id="step-1-a-minimal-html-page-starter">Step 1: A minimal HTML page starter</h2>
<p>I have a very small starter HTML template I always use when creating a new web page from scratch. It looks like this:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">DOCTYPE</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span> <span data-sanitized-class="token attr-name">lang</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>en<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meta</span> <span data-sanitized-class="token attr-name">charset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>utf-8<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>title</span><span data-sanitized-class="token punctuation">&gt;</span></span>Webpage starter<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>title</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span>Hello World!<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>I’m not going into every little detail here, there are <a href="https://www.matuzo.at/blog/html-boilerplate/">other articles and tutorials about that</a>. We are going to change the page’s title according to the text in the wireframe and focus on the document’s <code>&lt;body&gt;</code> from now on.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>title</span><span data-sanitized-class="token punctuation">&gt;</span></span>The Weekly Prophet – Magical News from the Wizarding World<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>title</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="step-2-landmarks">Step 2: Landmarks</h2>
<p>Now is the time to place our first content areas we’ve already defined above in our HTML document. The great thing about HTML is that for all these areas we have semantic tags that describe exactly what the specific area means, so let’s make use of them!</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		  The Weekly Prophet</span><br><span data-sanitized-class="highlight-line">		  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span>Magical News from the Wizarding World<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Top Stories<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Latest News<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Most Viewed<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>What's Going on in Hogwarts?<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Subscribe to our Owl Newsletter<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>When using semantic HTML tags like <code>header</code>, <code>nav</code>, <code>main</code>, and so on, we automatically define so-called <em>landmarks</em>, which are subsections of a page with a special role attached to them. This way, screenreader users, for example, can jump from one landmark to another and are enabled to get an overview of the page more quickly.</p>
<p>Sections are <a href="https://htmhell.dev/adventcalendar/2022/4/">only turned into landmarks when giving them an accessible name</a>, for example, by adding IDs to the <code>h2</code> headlines and using an <code>aria-labelledby</code> attribute on each section referencing the respective title.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>top-stories<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>top-stories<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Top Stories<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="step-3-reusable-sections">Step 3: Reusable sections</h2>
<p>Next, I’d like to create the “frame” of the page, that means everything except the main content. The header contains the current date, a search input field, and the title. When I look at the page, the first element that draws my attention is the title, so I would put that first in the HTML code. This way, a screenreader would start reading the title and not the date. I can change the order of elements according to the design later using CSS.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  The Weekly Prophet</span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span>Magical News from the Wizarding World<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>time</span> <span data-sanitized-class="token attr-name">datetime</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>2022-09-01<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Thu, September 1st 2022<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>time</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">placeholder</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Search…<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token comment">&lt;!-- see below --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h3 data-sanitized-id="the-time-element">The time element</h3>
<p>To provide additional meaning, we can wrap the date with a <code>&lt;time&gt;</code> tag. With the additional <code>datetime</code> attribute we specify the exact date and make the value more accessible to e.g. search engines.</p>
<h3 data-sanitized-id="the-search-field-form">The search <s>field</s> form</h3>
<p>The thing about wireframes and screen designs is that not all required HTML elements and attributes might be obvious at first sight. We only see one input field in the top right corner, but there’s a lot more functionality required. Just adding this one field is not enough. The search functionality might be added by JavaScript later, but wouldn’t it be nice if we had a fallback in case this doesn’t work? To achieve that, we need a form that is going to replace the search input from above:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span> <span data-sanitized-class="token attr-name">action</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/search<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search-input<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Search articles<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search-input<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">placeholder</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Search…<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>q<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>submit<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Submit search<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Using CSS, we can hide the elements we don’t want to display while still providing accessible and robust HTML code for everyone. Including an action and a submit button in the <code>form</code> makes it possible to send a search request without no JavaScript involved. The label helps screenreader users find out what the input field is all about—a placeholder cannot replace a label. We use the <code>role</code> attribute to specify a search landmark—this is the only landmark role without a dedicated HTML tag.</p>
<h3 data-sanitized-id="the-navigation">The navigation</h3>
<p>One center piece of any website is <a href="https://web.dev/website-navigation/">the navigation</a>. It’s a place to start for the user to get an overview of the site and its subsections. To build a navigation, there’s no magic required, just a list of some good old anchor elements a.k.a. hyperlinks.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Main<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/news<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>News<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/ministry-magic<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Ministry of Magic<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/gringotts<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Gringotts<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/hogwarts<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Hogwarts<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/quidditch<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Quidditch<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>I add an <code>aria-label</code> attribute to the navigation because there will be more <code>nav</code> elements in the footer; we need an indicator to distinguish the purpose of these navigation elements.</p>
<h3 data-sanitized-id="the-website-footer">The website footer</h3>
<p>At the end of the page, we can find a newsletter form and additional navigation content, similar to the header.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Subscribe to our Owl Newsletter<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span> <span data-sanitized-class="token attr-name">action</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/subscribe<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">method</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>post<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name-input<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Name<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name-input<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>address-input<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Address<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>address<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>address-input<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>submit<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Subscribe<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-categories<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Top Categories<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-categories<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>...<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-company<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>The Company<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-company<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>...<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-spells<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Spells and Charms<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>footer-spells<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>...<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The <code>aside</code> tag contains additional content that is not directly related to the main content. I could take it and place it on a different page and it would still make sense. Similar to the search field above, a form is required to collect user data for newsletter subscriptions. Make sure that every input field gets its own meaningful label.</p>
<p>The columns in the footer are wrapped by <code>div</code> elements. They don’t carry any semantic information, but I’m sure I’m going to need this structure later when creating a layout in CSS. I don’t fill the navigations with all the links, but you get the idea.</p>
<p>Using the <code>aria-labelledby</code> attribute, I describe the navigation and its content similar to the <code>aria-label</code> attribute used above. The difference this time is that I use the ID of the describing element—the headlines above in our case—as the attribute value.</p>
<h2 data-sanitized-id="step-4-thinking-in-components">Step 4: Thinking in components</h2>
<p>Next, I’d like to focus on the main content: the four sections containing all the interesting articles. Each section looks slightly different, but nonetheless, it’s articles everywhere. They all have a lot in common. In the image below there are all different variants of articles where the same parts are highlighted in the same color:</p>
<ul>
<li>title (2)</li>
<li>image (1)</li>
<li>teaser text (3)</li>
<li>author (4)</li>
<li>date and time (4)</li>
</ul>
<a href="https://htmhell.dev/images/advent2022/8/03-wireframe-articles.png">
<img src="https://htmhell.dev/images/advent2022/8/03-wireframe-articles.png" alt="A drawing of the five different article layouts that can be found in the wireframe. The first one is the largest one and contains all elements that are described in the following section of this article. There are other layouts that contain only an image and a title or just a title and a teaser text." width="2510" height="1576">
</a>
<p>With a lot of libraries, frameworks, and design systems out there, we live in a component-driven web development world. When implementing a design, we try to find out which elements function the same and create reusable components for them. This is what I plan to do for the articles.</p>
<p>The first article in the “Top Stories” section contains all parts listed above, so this is the HTML structure I would use for it:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h3</span><span data-sanitized-class="token punctuation">&gt;</span></span>Students returning to hogwarts<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h3</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A descriptive alternative text for the image<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>The day 73 kids waited the whole summer long is finally here: there first day at Hogwarts. The Sorting Hat is awaiting them in the castle already…<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span>Rita Skeeter<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>time</span> <span data-sanitized-class="token attr-name">datetime</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>2022-09-01<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>01/09/2022<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>time</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>All the other articles use a reduced version of the snippet above, depending on the section where they occur. Here are three particularities in the code snippet above I’d like to highlight:</p>
<h3 data-sanitized-id="images-and-alternative-text">Images and alternative text</h3>
<p>Images that provide content should always have a meaningful alternative text that describes what’s in the image. This way, people who are visually impaired can consume the same content just another way. I always try writing good image descriptions right from the beginning to not forget about it when deadlines and launch dates come closer.</p>
<p>A common mistake is to just use the article’s title as alternative text, but it’s not likely that the title describes what can be seen on the image. In case the image is just a decorative item that does not provide any useful content, add an empty alternative text (<code>alt=""</code>), so a screenreader will ignore it.</p>
<h3 data-sanitized-id="the-document-outline">The document outline</h3>
<p>One problem I find on many websites on my daily journeys through the World Wide Web is a wrong order of headlines. People tend to choose the headline level (from one to six) based on the headline’s font size as defined by the user agent’s (the browser’s) style sheet and not their meaning.</p>
<p>In the end, it doesn’t matter whether the <code>h1</code> headline is smaller than the <code>h3</code> headline because the page is designed this way; what matters is that when only looking at the headlines on a page (by actually <em>looking</em> at the page or by using a screenreader that only <em>reads</em> the headlines), the user should get an idea of the content and its hierarchy. Imagine writing an article, a thesis, or a book and structuring your content into main sections, chapters, and sub-chapters—it’s the same principle for the web pages you create.</p>
<p>This is why I chose the <code>&lt;h3&gt;</code> tag for the article headline, because the <code>h1</code> headline is reserved for the page title “The Weekly Prophet” (there should only be <em>one</em> <code>&lt;h1&gt;</code> on a web page), and the <code>h2</code> headlines are used as headlines for the content sections.</p>
<h3 data-sanitized-id="multiple-headers-and-footers">Multiple headers and footers</h3>
<p>Unlike the <code>main</code> or the <code>h1</code> element, it is allowed to have several <code>header</code> and <code>footer</code> elements on a single page. The tags are not reserved solely for the page header and footer, but can be used in sub-components as well to define additional meaning for elements within so-called <em>sectioning content</em>. In our example, the sectioning content element is the <code>article</code> and we define a header for image and title and a footer for the meta information about the author and publish date. In this case, the header and footer aren’t landmarks, but add useful semantic information nonetheless.</p>
<h2 data-sanitized-id="step-5-last-small-details">Step 5: Last small details</h2>
<p>In two of the article sections, we can find additional links to category sub-pages. These should be implemented as simple links.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/latest-news<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>View all articles<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/hogwarts<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Read more hogwarts news<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The wireframe is helpful here, as understandable link texts are already provided. Sometimes you have to work with designs that use just some generic texts for such links like “read more” or similar. When there are a lot of links with the same text on a page, it gets hard to find out where these links lead to without further context. Make sure to always provide meaningful link texts that tell the user what to expect when clicking on it.</p>
<h3 data-sanitized-id="one-more-thing">One more thing</h3>
<p>The section about the most viewed articles is about ranking. Therefore, I’d use an ordered list to wrap the articles that show up there.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Most Viewed<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ol</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token comment">&lt;!-- article content ---&gt;</span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token comment">&lt;!-- article content ---&gt;</span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token comment">&lt;!-- and so on… --&gt;</span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ol</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="wrapping-up">Wrapping up</h2>
<p>That’s it, we’re done, we’ve built a fundamental HTML structure based on the given wireframe. 🎉</p>
<p>Here are my key takeaways for you:</p>
<ul>
<li>always remember to use available semantic HTML tags to define the content’s meaning</li>
<li>use only one <code>h1</code>  and <code>main</code> tag per page</li>
<li>take care of proper headline order, count from one to six and don’t skip levels</li>
<li>provide descriptive alternative texts for images (or leave the alt attribute empty when the image is just decorative)</li>
<li>use built-in functionality like links and forms for the user to interact with your site</li>
</ul>
<p>To make sure there are no syntax or semantic errors in your code, I recommend using tools like the <a href="https://validator.w3.org/">W3C validator</a> to run a quick check on your code. Sometimes you get helpful insights about what’s wrong and how to fix it.</p>
<p>It’s not that hard to take responsibility for building good HTML and consequently an accessible site, you can start with small first steps and make your way to the top from there.</p>


guid: https://christitus.com/twitter-archive/
title: Twitter Archive Offline
link: https://christitus.com/twitter-archive/
hash: �(�N;CpU�e�k��
attributes: {"enclosures":[]}
content:
<p>Leaving Twitter? Why not download all your tweets from archive and store it yourself before deleting your account!</p>
<h2 data-sanitized-id="projects">Projects</h2>
<ul>
<li><a href="https://github.com/timhutton/twitter-archive-parser">Twitter Archive Parser</a></li>
<li><a href="https://github.com/nornagon/twitter-bookmark-archiver">Twitter Bookmark Tool - Download All Links</a></li>
<li><a href="https://github.com/caarlos0/twitter-cleaner">Twitter Cleaner</a></li>
<li><a href="https://github.com/walaura/Twitter-photo-downloader">Twitter Photo Downloader</a></li>
</ul>
<h2 data-sanitized-id="process-of-offline-twitter">Process of Offline Twitter</h2>
<ol>
<li>Download Twitter Archive
<img loading="lazy" src="https://christitus.com/images/2022/twitter-archive/twitter-archive.webp" alt="" data-sanitized-class="img-fluid">
<em>Note: This can take up to 72 hours to produce a downloadable zip</em></li>
<li>Unzip Archive to it’s OWN folder</li>
<li>Download the Archive parser
<div data-sanitized-class="highlight"><pre tabindex="0" data-sanitized-class="chroma"><code data-lang="fallback" data-sanitized-class="language-fallback"><span data-sanitized-class="line"><span data-sanitized-class="cl">wget https://raw.githubusercontent.com/timhutton/twitter-archive-parser/main/parser.py
</span></span></code></pre></div></li>
<li>Run <code>python3 parser.py</code>
<em>I recommend selecting Yes to download all messages</em></li>
<li>Open <code>Your archive.html</code> in your browser
<img loading="lazy" src="https://christitus.com/images/2022/twitter-archive/offline-twitter.webp" alt="" data-sanitized-class="img-fluid"> </li>
</ol>
<h2 data-sanitized-id="limitations">Limitations</h2>
<p>I put the other projects above to get around the limitations of using the Archive Parser.</p>
<ul>
<li>Bookmark Tool will change the t.co links to their proper links so it doesn’t use Twitter servers.</li>
<li>Cleaner will cleanup the archive</li>
<li>Photo Downloader will download the full photos in your tweets. By default it downloads the thumbnail and references twitter for the full image.</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/vwxxNCQpcTA?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://htmhell.dev/adventcalendar/2022/2/
title: You Don't Need ARIA For That
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/2/
hash: [��);l� �ۢG9gU
attributes: {"enclosures":[]}
content:
<p>In web development, writing semantic HTML is important for accessibility, and also provides some nice <a href="https://twitter.com/dennisl/status/1109875307601948672">side effects</a> such as supporting browser "reader" modes, SEO, graceful degradation, and exporting.</p>
<p>Implementing semantic HTML will also greatly reduce the need for <a href="https://www.w3.org/TR/wai-aria-1.1/">ARIA</a> (Accessible Rich Internet Applications). ARIA is a large set of HTML attributes to help accessibility for users of assistive technology, namely screen readers, by better supporting semantics not provided or not supported well via HTML.</p>
<p>ARIA usage certainly has its place. But overall, reduced usage of ARIA will, ironically, greatly increase accessibility. This is due to several reasons including:</p>
<ol>
<li>ARIA is very often implemented incorrectly. This is well known in the industry, but for data, reference the <a href="https://webaim.org/projects/million/#aria">WebAIM Million report</a> which states “Home pages with ARIA present averaged 70% more detected errors than those without ARIA”.</li>
<li>ARIA may not be supported well (even when implemented correctly) by the browser and/or screen reader, which unfortunately is often the case. Reference <a href="https://a11ysupport.io/">a11ySupport.io</a> and <a href="https://www.powermapper.com/tests/screen-readers/aria/">PowerMapper</a> for related information.</li>
<li>ARIA isn't magic (as some web professionals seem to think!). Designs must still be accessible, inclusive, and usable.</li>
<li>ARIA only provides semantics. It doesn't provide any functionality. It doesn't provide any keyboard interaction that's often expected from certain ARIA patterns (the tab panel for example). It doesn't solve accessibility issues outside semantics for assistive technology (such as alternative text, color contrast, reading order, clear label text, captions, etc.)</li>
</ol>
<p>The folllowing cases will illustrate how to use HTML properly so that ARIA is not required. In doing so, the techniques demonstrated will help developers follow the <a href="https://www.w3.org/TR/using-aria/#rule1">first rule of ARIA</a> (to use HTML first if possible), as well as providing more robust code, and most likely, a more accessible experience for the user.</p>
<h2 data-sanitized-id="use-cases">Use cases</h2>
<p>The cases below are just a sampling of issues and include form labels, buttons, links, and images. I find them to be prevalent issues, and in fact I came across all of them “in the wild” (in live websites) over the last couple weeks. There is a bad version followed by a good one and then a note. For demonstration purposes, the code snippets are greatly simplified from the webpages in which they were found.</p>
<p>Remember that correcting the ARIA redundancies may seem trivial on the surface, but can go a long way in:</p>
<ul>
<li>reducing code complexity — less code!</li>
<li>reducing maintenance issues — for example, use of one text node rather than duplicated (also, less code!)</li>
<li>reducing accessibility errors due to value calculations by the browser — for example, the developer may not understand the <a href="https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/#name_calculation">accessible name calculation</a> which can get a bit tricky.</li>
</ul>
<p>Now let's get to the use cases!</p>
<h3 data-sanitized-id="form-labels">Form labels</h3>
<h4>Example 1</h4>
<p data-sanitized-class="code-label">Bad: redundant <code>aria-label</code></p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Pickup<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Pickup<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>checkbox<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>... checked=<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token attr-name">"</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>svg...</span><span data-sanitized-class="token punctuation">&gt;</span></span>...<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>svg</span><span data-sanitized-class="token punctuation">&gt;</span></span> </span><br><span data-sanitized-class="highlight-line">    Pickup</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: use the inline text within the <code>label</code> (implicit association)</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Pickup<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>checkbox<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>... checked=<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token attr-name">"</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>svg...</span><span data-sanitized-class="token punctuation">&gt;</span></span>...<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>svg</span><span data-sanitized-class="token punctuation">&gt;</span></span> </span><br><span data-sanitized-class="highlight-line">    Pickup</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Remove <code>aria-label</code> for the win! The <code>label</code> wrapped around the <code>input</code> sufficiently provides an accessible name for the input. </p>
<p><strong>Warning:</strong> this example implements implicit input labeling which may have issues with some assistive technology such as Dragon NaturallySpeaking. It's recommended to use explicit association as in Example 2.</p>
<h4>Example 2</h4>
<p data-sanitized-class="code-label">Bad: unwarranted use of <code>aria-labelledby</code></p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sortBy<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Sort By:<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>select</span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sortBy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Relevance<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Most Recent<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Value<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>select</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: use the <code>for</code> and <code>id</code> attributes for explicit association</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sortBy<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Sort By:<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>select</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sortBy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Relevance<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Most Recent<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span>Value<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>select</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Use fundamental HTML (and not ARIA) for the win! The <code>for</code> and <code>id</code> attributes provide an accessible name for the input.</p>
<h3 data-sanitized-id="image-in-button">Image in Button</h3>
<p data-sanitized-class="code-label">Bad: redundant <code>aria-label</code> and unnecessary role</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Save $1 on Halloween candy and decor<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>presentation<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1507288.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Save $1 on Halloween candy and decor<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1507288.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Save $1 on Halloween candy and decor<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Remove two ARIA attributes (and duplicate text) for the win! The <code>alt</code> attribute provides the accessible name for the button.</p>
<h3 data-sanitized-id="linked-text">Linked text</h3>
<p data-sanitized-class="code-label">Bad: overwriting pertinent content</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>view location<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/foobar...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">data-qa</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>order-address-one<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>100 W Main St<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">data-qa</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>order-address-city<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Strangeville, OH 48000<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: use the existing inline text</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/foobar...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">data-qa</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>order-address-one<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>100 W Main St<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">data-qa</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>order-address-city<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Strangeville, OH 48000<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> There's no need to be overzealous here; the <code>aria-label</code> overwrites the address text as the link name, therefore the address text is not accessible to screen reader users. Linking the address text is sufficient.</p>
<h3 data-sanitized-id="linked-images">Linked images</h3>
<p data-sanitized-class="code-label">Bad: redundant <code>aria-label</code></p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Earn Cash Back<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/foo<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Earn Cash Back<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>foo.png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: use the alt text only</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/foo<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>...<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Earn Cash Back<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>foo.png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Remove <code>aria-label</code> and use fundamental HTML for the win! The <code>alt</code> attribute provides the link content.</p>
<h3 data-sanitized-id="decorative-images">Decorative images</h3>
<p data-sanitized-class="code-label">Bad: <code>role</code> attribute used to denote decorative image</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>presentation<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>foo.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>a star, a twirl shape, a balloon<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: use an empty <code>alt</code> value</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>foo.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span><span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Remove the <code>role</code> attribute (and remove the alt value) for the win! The empty <code>alt</code> attribute denotes that this is a decorative image.</p>
<h3 data-sanitized-id="script">Script</h3>
<p data-sanitized-class="code-label">Bad: <code>aria-hidden</code> on script tag</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span> <span data-sanitized-class="token attr-name">aria-hidden</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>true<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="code-label">Good: nothing extra needed for accessibility</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p data-sanitized-class="highlight"><strong>Note:</strong> Remove <code>aria-hidden</code> for the win! Script content (inline JavaScript) isn't output by assistive tech.</p>
<h2 data-sanitized-id="summary">Summary</h2>
<p>Removing ARIA redundancy can reduce code complexity, maintenance issues, and the chance of accessibility errors. Reducing reliance on ARIA makes code more simple and will most likely increase accessibility.</p>
<p>Writing semantic HTML is important for accessibility and also has other benefits. Semantic HTML will greatly reduce the need for ARIA, which is often implemented incorrectly and may not be fully supported. Be sure to use HTML first before using ARIA, such as when coding form labels, buttons and links, and decorative images.</p>
<h2 data-sanitized-id="further-reading">Further reading</h2>
<ul>
<li><a href="https://web.dev/learn/accessibility/aria-html/">ARIA and HTML</a> on web.dev</li>
<li><a href="https://briefs.video/videos/what-is-aria-even-for/">What Is ARIA Even For Webbed Briefs</a> by Heydon Pickering</li>
<li><a href="https://www.a11yproject.com/posts/aria-has-perfect-support/">Myth: ARIA has perfect support</a></li>
<li><a href="https://talks.yatil.net/1jBftF/">ARIA Serious‽ presentation</a> October 2019 by Eric Eggert</li>
<li><a href="https://webaim.org/articles/gonewild/">Web Accessibility Gone Wild</a> by WebAIM</li>
</ul>


guid: https://htmhell.dev/adventcalendar/2022/3/
title: Using SRI to protect from malicious JavaScript
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/3/
hash: De��_���î����gb
attributes: {"enclosures":[]}
content:
<p>At some point of developing a website, there might come a time where we need to <a href="https://saptaks.blog/posts/progressive-enhancement-is-not-anti-js.html">progressively enhance using JavaScript</a>. There are few different options of how you add JavaScript. Firstly, we can write our own script using vanilla JS only, and self host the JavaScript file. However, often we find ourselves needing to use a JavaScript framework or library to make our life a little easier. We can definitely download all the JavaScript framework and libraries we are using and self host them in our server, but most framework websites recommend using a CDN.</p>
<h2 data-sanitized-id="cdns-for-javascript-frameworks-and-libraries">CDNs for JavaScript frameworks and libraries</h2>
<p><a href="https://www.cloudflare.com/en-gb/learning/cdn/what-is-a-cdn/">CDN</a> or Content Delivery Networks are a group of servers which stores duplicate copies of data and serves them to the user from the server closest to them to improve performance. CDNs are often used to serve static files like CSS and JS files by frameworks and libraries. Developers used CDNs for serving JS files not only because CDNs are usually faster, but also since a lot of commonly used frameworks served via CDN used to already be cached in your browser. For example, let’s say there are 3 websites - websiteA.﻿com, websiteB.﻿com. Both of these websites use jQuery. To use CDN, both of these websites can use the following code in their HTML file:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://code.jquery.com/jquery-3.6.1.js<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token script"></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>script</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Now, when a user visits, websiteA.﻿com for the first time, the browsers requests for the jQuery file from <code>https://code.jquery.com</code> CDN and used to cache it. So, when the user would visit websiteB.﻿com, the jQuery file were already cached in the browser, thus improving performance a lot. However, most browsers have <a href="https://www.stefanjudis.com/notes/say-goodbye-to-resource-caching-across-sites-and-domains/">stoppped resource caching</a> to prevent tracking users across websites.</p>
<figure>
  <img src="https://htmhell.dev/images/advent2022/15/cdn-usage-ranking-desktop.png" alt="Bar chart which provides a view of CDN usage for mobile sites broken up for top 1,000, 10,000, 100,000, 1 million and 10 million popular sites as per Google CRUX data. For Top 1,000 sites the CDN adoption is 64%. For the top 10,000 sites, it's 63%. For the top 100,000 sites, it's 52%. For the top 1 million sites, it's 37%. For the top 10 million sites, it's 29%.">
  <figcaption><a href="https://almanac.httparchive.org/en/2022/cdn#fig-3">CDN usage by site popularity</a> on mobile as reported in Web Almanac 2022</figcaption>
</figure>
<p>Even though this change removes the performance improvements from resource caching, CDNs are still usually faster and simpler for serving CSS and JS files and does continue to be used widely. According to Web Almanac 2022, 64% of top 1,000 websites use <a href="https://almanac.httparchive.org/en/2022/cdn">CDN</a> to serve various content.</p>
<h2 data-sanitized-id="security-issue">Security issue</h2>
<p>Using CDN to serve JavaScript comes with certain risks. One of the reasons privacy and security focused users are bit squirmish about JS is because a malicious JS can really harm your user. It can range from being misused for tracking and surveillance to compromising users private data. So, if all websites use the same CDN to serve a JS file, an attacker now needs to gain control of only the CDN server instead of all individual servers. Once they gain control, they can inject malicious code into the JS file, and it gets served to all end users of websites that use the CDN.</p>
<h2 data-sanitized-id="how-does-sri-help?">How does SRI help?</h2>
<p>At this point, the solution to this seems to be to self host all your JavaScript codes instead of using a CDN. But that would be a step backward in terms of performance and not the favourable solution in many situations. This is where <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">Subresource Integrity (or SRI)</a> helps.</p>
<p>Subresource integrity is a way of telling the browser how to verify that the JS it has fetched from the CDN is an untampered JS file. SRI uses the very popular concept of file hashing to verify that the file is still the same. Let’s look into what a <code>&lt;srcipt&gt;</code> code with Subresource integrity to fetch jQuery would look like.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://code.jquery.com/jquery-3.6.1.js<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">integrity</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=<span data-sanitized-class="token punctuation">"</span></span></span><br>  <span data-sanitized-class="token attr-name">crossorigin</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>anonymous<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token script"></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>script</span><span data-sanitized-class="token punctuation">&gt;</span></span></code></pre>
<p>The above code is what you get if you go to <a href="https://releases.jquery.com/">https://releases.jquery.com/</a> and click on the release you want to use. Now let’s break it down to see what it means.</p>
<h3 data-sanitized-id="integrity">integrity</h3>
<p>The <code>integrity</code> attribute contains the file hash. The <code>integrity</code> attribute has 2 parts - the hashing algorithm and the hash of the file. In the above code, <code>sha256</code> is the hashing algorithm which tells the browser which algorithm to use while computing hash of the received file. The part after <code>sha256</code>- is the base64 encoding of the expected hash of the untampered file provided by the code author. So when the browser comes across the above code, it fetches the jQuery file from the CDN server, generates the hash for the file it received and compares it with the hash mentioned in the <code>integrity</code> attribute. If the hashes don’t match, then the browser will refuse to execute the script and throw a network error saying fetching of the resources failed.</p>
<h3 data-sanitized-id="crossorigin">crossorigin</h3>
<p>Since the CDN resource is not present in the same origin, the <code>crossorigin</code> attribute must be present to make the <a href="https://www.w3.org/TR/SRI/#is-response-eligible-for-integrity-validation">response eligible for integrity validation</a>. Without the <code>crossorigin</code> attribute, the browser will load the script as if the <code>integrity</code> attribute was not present. We set the value of <code>crossorigin</code> attribute to <code>"anonymous"</code> to ensure that no user credentials or cookie informations are sent to the CDN server.</p>
<h2 data-sanitized-id="how-to-generate-sri?">How to generate SRI?</h2>
<p>In most cases, the framework or library we are importing using <code>&lt;script&gt;</code> tag should have the SRI code already mentioned in their documentation. For example, as we saw before, if we go to jQuery’s release page, and click on the release we want, the example code already has the <code>integrity</code> and <code>crossorigin</code> attribute values mentioned. Bootstrap also has the <code>integrity</code> and <code>crossorigin</code> attributes mentioned in their quickstart page. But there are many other frameworks that don’t in which case we will need to generate the hash by ourselves. Also, it’s recommended to use SRI for the scripts written by the developer for the website specifically. There can always be a scenario where the attacker gets access to only certain files, so SRI will ensure that the resources served by the server are untampered.</p>
<figure>
  <img src="https://htmhell.dev/images/advent2022/15/sri-hash-function-usage.png" alt="Bar chart showing percent of HTML elements with SRI using various hash functions. SHA-384 is used in 58.4% of elements with SRI in desktop
websites and 60.7% of elements with SRI in mobile websites. SHA-256 is used in 32.4% of elements with SRI in desktop websites and
30.8% of elements with SRI in mobile websites. SHA-512 is used in 10.9% of elements with SRI in desktop websites and 9.9% of
elements with SRI in mobile websites.">
  <figcaption>
  <a href="https://almanac.httparchive.org/en/2022/security#subresource-integrity" rel="noopener noreferrer">Percentage usage of SRI</a> hash function as mentioned in Web Almanac 2022
  </figcaption>
</figure>
<p>To create a hash function, there are 3 different hash functions that are supported for SRI - sha256, sha384 and sha512. We need to use one of these 3 functions to compute the hash for the <code>.js</code> files and <code>.css</code> files and then use those values. The easiest way of doing this is using <a href="https://www.srihash.org/">https://www.srihash.org/</a>. All we need to do is paste the link to the resource we want to generate a hash for, and the website generates the HTML that we need to add. For example, if we wanted to get the HTML for the script tag to import react, all we need to do is paste <a href="https://unpkg.com/react@18/umd/react.production.min.js">https://unpkg.com/react@18/umd/react.production.min.js</a> from React’s CDN page in the input field, chose the hash function we want, and it generates the following output:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://unpkg.com/react@18/umd/react.production.min.js<span data-sanitized-class="token punctuation">"</span></span> <br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token attr-name">integrity</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sha384-tMH8h3BGESGckSAVGZ82T9n90ztNXxvdwvdM6UoR56cYcf+0iGXBliJ29D+wZ/x8<span data-sanitized-class="token punctuation">"</span></span></span><br>	<span data-sanitized-class="token attr-name">crossorigin</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>anonymous<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token script"></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>script</span><span data-sanitized-class="token punctuation">&gt;</span></span></code></pre>
<p>But if you fancy doing it manually, especially for your local JavaScript files and CSS files, we can do that as well using openssl in a command line.</p>
<pre data-sanitized-class="language-bash"><code data-sanitized-class="language-bash"><span data-sanitized-class="highlight-line">openssl dgst -sha384 -binary FILENAME.js <span data-sanitized-class="token operator">|</span> openssl base64 -A</span></code></pre>
<p>The above code will generate the base64 encoded hash to be put in the integrity attribute. For example, if we wanted to create the hash for the same react file manually, firstly we will need to download the JS file from <a href="https://unpkg.com/react@18/umd/react.production.min.js">https://unpkg.com/react@18/umd/react.production.min.js</a>, then open a terminal and enter <code>openssl dgst -sha384 -binary react.production.min.js | openssl base64 -A</code>. This gives me the output <code>tMH8h3BGESGckSAVGZ82T9n90ztNXxvdwvdM6UoR56cYcf+0iGXBliJ29D+wZ/x8</code> for React 18.2.0. Since I used the hash function <code>sha384</code> and with the above output, the value of my <code>integrity</code> attribute will be <code>sha384-tMH8h3BGESGckSAVGZ82T9n90ztNXxvdwvdM6UoR56cYcf+0iGXBliJ29D+wZ/x8</code>. Hence, we get a HTML same as the one we get from <a href="http://srihash.org/">srihash.org</a></p>
<p>The reason I really love Subresource Integrity is because it’s such an important feature that is baked using HTML attributes. It shows that a lot can be achieved, even in making a website secure just by learning HTML better. Just add an <code>integrity</code> attribute and <code>crossorigin</code> attribute to ensure that untampered JS framework codes are fetched. Also, SRI is supported by <code>&lt;link&gt;</code> tags as well so that one can ensure that the CSS files are also fetched untampered. In <a href="https://darknetdiaries.com/transcript/52/">episode 52 of Darknet Diaries</a>, Jack Rhysider and Jonathan Klijnsma discuss about how a tampered modernizr JavaScript file might have caused the data breach in British Airways, that could have been avoided using SRI</p>


guid: https://htmhell.dev/adventcalendar/2022/4/
title: Landmarks and where to put them
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/4/
hash: 8��� f� tf1�
attributes: {"enclosures":[]}
content:
<p>Heading elements (<code>h1</code> through to <code>h6</code>) are used to give structure to the content of your page. They're important for SEO, make your pages more readable and, of course, also help people that use assistive technologies navigate through your page. Somewhat less known are landmark elements. These are elements that are used to define the structure of your entire HTML and you probably know some of them already: <code>nav</code>, <code>main</code> and <code>footer</code> are all landmark elements (well, most of the time. We'll get to that.)</p>
<p>Many of these elements were only introduced with HTML5 (compared to the headers that have been with us for as long as HTML existed) so if you haven't used them extensively yet, that's not that unusual. Let's figure out what they are and where you can (and can not) use them.</p>
<h2 data-sanitized-id="landmarks-101">Landmarks 101</h2>
<p>When you look up landmark elements, you'll find that they also go by another name: sectioning elements. You can take that quite literally: they section off different parts of your page into unique semantic blocks.</p>
<p>Knowing which part of a website has which role is helpful to many. They can help browsers determine what part of the page to show in a reader mode, they let search engine know what pages on your site are most important (linked from the <code>nav</code>) and they let users natively move focus to the <code>main</code> content without you having to bring your own skip-links: assistive technologies can show a list of all landmarks and your visitors can use that to navigate across your page.</p>
<p><img src="https://htmhell.dev/images/advent2022/5/landmark.png" alt="VoiceOver on macOS showing the lis of landmarks for htmhell.dev."></p>
<p>In other words, landmarks are a bunch of elements that help you define the structure of a page: you use them to show which set-of-links is the navigation (<code>nav</code>), what part of the page is the intro (<code>header</code>) and the main content (<code>main</code>). If you page contains a stand-alone piece of content you could put that in an <code>article</code> and if it contains secondary information you put that in an <code>aside</code>. And if something it its own sectioned-off part you use ...a  <code>section</code>.</p>
<p>Here's an overview of the landmark elements in HTML, their ARIA role and what they mean:</p>
<ul>
<li><code>aside</code> (role: <code>complementary</code>) can be used to show content that is complementary to the main subject of the page. For example, links to related documents or meta info related to the main subject.</li>
<li><code>footer</code> (role: <code>contentinfo</code>) is where you put all the information about a page. Typically that's things like copyright info, related links, the author</li>
<li><code>form</code> (role: <code>form</code>) <em>can</em> be a landmark element if it has a accessible name (set with <code>aria-label</code>, <code>aria-labelledby</code> or <code>title</code> attributes)</li>
<li><code>header</code> (role: <code>banner</code>) is where your page's "introduction" goes. Things like your logo, search and main navigation all go in here.</li>
<li><code>main</code> (role: <code>main</code>) contains the main content or functionality of your page.</li>
<li><code>nav</code> (role: <code>navigation</code>) is where you provide navigational links. They can be for your entire website (think your main menu), but also for your current page (think table of contents).</li>
<li><code>section</code> (role: <code>region</code>) This is a "generic standalone section of a page". Essentially, if you have a part of the page that stands alone, try to go down this list and if none of them fit but it's still a separate part of the page, use a section. Like <code>form</code>s, it'll only be a landmark if it also has an accessible name.</li>
</ul>
<p>There is still one more landmark that we need to discuss: the <code>search</code> landmark. All the landmarks above are HTML elements with a specific landmark role, but the <code>search</code> landmark role has no associated HTML element. It only exists in ARIA. As you might guess, the search landmark is used to indicate search functionality and practically, you'd add a <code>search</code> role to a <code>form</code> element to change it from a generic form to a search form.</p>
<h2 data-sanitized-id="where-(not)-to-put-them-the-ideal-web-page-structure">Where (not) to put them: the ideal web page structure</h2>
<p>Now that you know which landmarks there are, how do you use them in a web page? "The ideal web page structure"  is quite a heavy promise, but we're limiting it to the ideal <em>landmark</em> structure. Here's what that looks like:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- logo etc --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- if it exists --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- what your page is all about --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token comment">&lt;!-- complementary information --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>aside</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token comment">&lt;!-- copyright notice etc --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- if you want to --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Your page begins with the <code>header</code> and ends with the <code>footer</code>. Your navigation and search landmarks will usually go into the <code>header</code> element and can sometimes fit well in the <code>footer</code> element as well.</p>
<p>Directly after the header is the <code>main</code> content. This is the most important part of your page so you put it as high as possible. Directly after the <code>main</code> element you can put any complementary information that relates to your entire page.</p>
<p>What this does it create a "landmark outline" of your page that looks like this:</p>
<ul>
<li>Banner</li>
<li>Navigation</li>
<li>Search</li>
<li>Main</li>
<li>Complementary</li>
<li>Contentinfo</li>
<li>Navigation</li>
</ul>
<p>Notice that unlike a heading structure, your landmarks don't add any hierarchy to a page. Each section of your page is meant to be its own part. It also doesn't matter how many other elements you add around or inside them. You are free to wrap everything in as many divs as <s>your javascript framework requires</s> you need to style your page.</p>
<p>When you add landmark elements, you're changing the semantics of your web page so there are some key things to keep in mind:</p>
<h3 data-sanitized-id="not-all-nesting-is-created-equally">Not all nesting is created equally</h3>
<p>Even though your landmarks don't add hierarchy, where you put your landmark elements will determine if they even are landmarks. Both <code>header</code> and <code>footer</code> elements are only landmarks if they are inside your <code>body</code> element, but not if they're inside other sectioning elements.</p>
<p>A <code>header</code>/<code>footer</code> in any of the following elements indicate they're the header or footer for just that sectioning element, and they are taken out of the landmark structure:</p>
<ul>
<li><code>article</code></li>
<li><code>aside</code></li>
<li><code>main</code></li>
<li><code>nav</code></li>
<li><code>section</code></li>
</ul>
<p>Depending on who you ask (the <a href="https://www.w3.org/WAI/ARIA/apg/example-index/landmarks/complementary.html">ARIA authoring practice guide</a>, in this case), adding an <code>aside</code> into any of the above is also a bad idea. If something is complementary then by definition it's not part of the <code>main</code> or <code>article</code>. This doesn't track with the official <a href="https://html.spec.whatwg.org/multipage/sections.html#the-aside-element">HTML5 specification</a>, that has examples of using <code>aside</code> for things like pull quotes in articles.</p>
<p>Neither is correct or wrong, but keep in mind though that the more landmarks you add, the longer it takes assistive tech to go through the list of landmarks and the more annoying it will be for your visitors.</p>
<h3 data-sanitized-id="sometimes-just-adding-landmark-elements-isnt-enough">Sometimes just adding landmark elements isn't enough</h3>
<p>As mentioned in the overview of landmarks, just adding a <code>form</code> or <code>section</code> won't make them landmarks. You need to give them an accessible name or explicit role, and there's a few ways to do that:</p>
<ol>
<li>Adding a <code>aria-labelledby</code> attribute that contains the <code>id</code> of another element with the title of the form or section.</li>
<li>Adding a <code>aria-label</code> or <code>title</code> attribute to the element. The title attribute will also be visible on hover so keep that in mind.</li>
<li>Adding an explicit <code>role</code> attribute with <code>form</code> or <code>region</code> as the value.</li>
</ol>
<h3 data-sanitized-id="you-cant-just-keep-adding-them">You can't just keep adding them</h3>
<p>The <code>banner</code> ,  <code>contentinfo</code> and  <code>main</code> landmark roles should only be added to your page once. There is nothing in HTML5 that prevents your site from having multiple of them but from a semantic standpoint it doesn't make sense and for people using assistive technologies it's confusing. Your page should have one header, one footer and one main area. If you need more, maybe you just need another page.</p>
<h3 data-sanitized-id="naming-landmark-elements">Naming landmark elements</h3>
<p>If you have multiple of the same elements, for example you use a <code>nav</code> element for your top-level website navigation, and also for the table of contents on a page, you should give each of them a unique accessible name. If you don't, then visitors using assistive technologies will not know which is which. You can add a name using <code>aria-labelledby</code>, <code>aria-label</code> or <code>title</code> attributes.</p>
<p>When adding a name to a landmark element, it can be very tempting to add the role as well because that's how you would describe it in natural speech. For example, for your top level navigation you might want to add an <code>aria-label</code> of "Main navigation".</p>
<p>If you do that however, what assistive technology will announce is "Main navigation <em>navigation</em>" and your visitor gets to hear that it's navigation twice. Assistive technogies already append the role, so you shouldn't. In this case, naming your navigation "Main" is enough.</p>
<h3 data-sanitized-id="dont-just-replace-your-divs-with-sections">Don't just replace your <code>div</code>s with <code>section</code>s</h3>
<p>A div is not a button, and a section is not a div. When HTML5 just came out, a lot of advice boiled down to "Use section elements because they're more semantic than divs" but of course, that only works if the divs you replace had semantic value. For the most parts, your <code>div</code>s wont have any specific semantics: they don't tell the browser what each part of the structure is for.</p>
<p>And that's fine! You can use your divs for styling, to structure your DOM in such a way that you can use CSS and JavaScript to build what you want to build. And when you have a portion of the page that is it's own standalone or self-contained part, you can add a section (and make sure to name it).</p>
<h2 data-sanitized-id="on-roles-and-elements">On Roles and Elements</h2>
<p>Throughout this article I've used Elements (e.g. <code>header</code>) and Roles (e.g. <code>banner</code>). So what's with those? Are they the same thing? Why do they have different names?</p>
<p>HTML5 is the official specification in terms of what elements have what semantic value. However, the HTML5 specification doesn't cover all possible semantics. To provide richer semantics, ARIA was created as a technology that sits on top of HTML that can help "plug the gaps".</p>
<p>It's generally better to use HTML where possible: the <a href="https://www.w3.org/TR/using-aria/#rule1">first rule of aria</a> is <em>don't use aria</em>:</p>
<blockquote>If you can use a native HTML element or attribute with the semantics  and behavior you require already built in, instead of re-purposing an  element and adding an ARIA role, state or property to make it  accessible, then do so.</blockquote>
<p>Practically this means that instead of adding a <code>role="banner"</code> to your div to make it a header element, you should just use the <code>header</code> element.</p>
<p>So why does <code>role="banner"</code> exist? It exists for some very pragmatic reasons: While yes, using a header element is better, not all websites are started anew, and not all websites are built with modern systems. Some systems might have no way of adding a <code>header</code> element. In those systems, using a <code>role</code> attribute means that you can still provide the correct semantics.</p>
<p>If you write HTML you should always prefer to use the HTML elements and if you do, you don't have to add the <code>role</code> attribute (there are <a href="https://www.scottohara.me/blog/2019/01/12/lists-and-safari.html">some places where you should</a>, but they're not landmark-related).</p>
<p>As for the names being different: for better or for worse ARIA and HTML are written by different people in different places, with different needs. While for ARIA it makes sense to call the navigation "navigation", HTML authors would go crazy if for every menu they had to write <code>&lt;navigation&gt;</code> instead of just <code>&lt;nav&gt;</code>. The names in ARIA in comparison are written to also make sense outside of the concept of a HTML page. A page has a footer, but any bit of content might have "content info" that gives additional information.</p>
<h2 data-sanitized-id="wrapping-up">Wrapping up</h2>
<p>Your page should almost certainly have a top level <code>header</code>, <code>main</code> and <code>footer</code>, but you don't want to add a bunch of them. If it's part of a larger website then you'll want to use a <code>nav</code> element to link to other pages. If you use multiple <code>nav</code> elements you'll want to name them so your visitor can tell them apart. You should try and use the HTML elements but if you absolutely can not, ARIA gives you the <code>role</code> attribute. Landmarks have a name and a role, and both get read out by assistive technologies.</p>
<p>Used resources:</p>
<p><a href="https://www.w3.org/WAI/ARIA/apg/example-index/landmarks/HTML5.html">https://www.w3.org/WAI/ARIA/apg/example-index/landmarks/HTML5.html</a></p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning">https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning</a></p>
<p><a href="https://www.w3.org/TR/wai-aria-1.2/#landmark">https://www.w3.org/TR/wai-aria-1.2/#landmark</a></p>
<p><a href="https://html.spec.whatwg.org/">https://html.spec.whatwg.org</a></p>


guid: https://christitus.com/bypass-paywalls/
title: Bypass Paywalls
link: https://christitus.com/bypass-paywalls/
hash: w��i��X f'�B�J
attributes: {"enclosures":[]}
content:
<p>Tired of ads, paywalls, and other garbage in your web browsing experience? These add-ons will improve your experience!</p>
<blockquote data-sanitized-class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/christitustech?ref_src=twsrc%5Etfw">@christitustech</a> u missed alot goodies, i made a list <a href="https://t.co/KU0ohchDOw">https://t.co/KU0ohchDOw</a></p>— indrid cold (@nerdz0ne) <a href="https://twitter.com/nerdz0ne/status/1596178362271207425?ref_src=twsrc%5Etfw">November 25, 2022</a></blockquote>

<h2 data-sanitized-id="the-extensions">The Extensions</h2>
<ul>
<li>
<p><strong>YouTube Enhancer</strong> - <a href="https://chrome.google.com/webstore/detail/enhancer-for-youtube/ponfpcnoihfmfllpaingbgckeeldkhle">https://chrome.google.com/webstore/detail/enhancer-for-youtube/ponfpcnoihfmfllpaingbgckeeldkhle</a></p>
<ul>
<li>Adds screenshots, studio, auto-settings, and much more!
<img loading="lazy" src="https://christitus.com/images/2022/bypass-paywalls/youtube-enhancer.webp" alt="" data-sanitized-class="img-fluid"> </li>
</ul>
</li>
<li>
<p><strong>Self-Destructing Cookies</strong> - <a href="https://chrome.google.com/webstore/detail/self-destructing-cookies/igdpjhaninpfanncfifdoogibpdidddf">https://chrome.google.com/webstore/detail/self-destructing-cookies/igdpjhaninpfanncfifdoogibpdidddf</a></p>
<ul>
<li><em>This is a privacy add-on that deletes cookies when the browser or tab is closed. Note: This will cause some sites to log you out if a sign-in is required.</em></li>
</ul>
</li>
<li>
<p><strong>Cookie Remover</strong> - <a href="https://chrome.google.com/webstore/detail/cookie-remover/kcgpggonjhmeaejebeoeomdlohicfhce/related">https://chrome.google.com/webstore/detail/cookie-remover/kcgpggonjhmeaejebeoeomdlohicfhce/related</a></p>
<ul>
<li><em>This will remove the current cookies for the site you are on by clicking the cookie icon in the top right</em>
<img loading="lazy" src="https://christitus.com/images/2022/bypass-paywalls/cookie-remover.webp" alt="" data-sanitized-class="img-fluid"> </li>
</ul>
</li>
<li>
<p><strong>Bypass Paywall</strong> - <a href="https://github.com/iamadamdev?tab=repositories">https://github.com/iamadamdev?tab=repositories</a></p>
<ul>
<li>Load with dev mode in chrome.
<img loading="lazy" src="https://christitus.com/images/2022/bypass-paywalls/dev-mode-load.webp" alt="" data-sanitized-class="img-fluid">
<img loading="lazy" src="https://christitus.com/images/2022/bypass-paywalls/bypass-paywalls.webp" alt="" data-sanitized-class="img-fluid"> </li>
</ul>
</li>
<li>
<p><strong>Clickbait Removal</strong> - <a href="https://chrome.google.com/webstore/detail/clickbait-remover-for-you/omoinegiohhgbikclijaniebjpkeopip">https://chrome.google.com/webstore/detail/clickbait-remover-for-you/omoinegiohhgbikclijaniebjpkeopip</a></p>
<ul>
<li>Remove all thumbnails and put parts of video in. Also removes CAPS from the titles
<img loading="lazy" src="https://christitus.com/images/2022/bypass-paywalls/clickbait-remover.webp" alt="" data-sanitized-class="img-fluid"> </li>
</ul>
</li>
</ul>
<h2 data-sanitized-id="walkthrough-video">Walkthrough Video</h2>
<div>
<iframe allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/_fG32rdWdes?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" title="YouTube video" sandbox="allow-scripts allow-same-origin"></iframe>
</div>


guid: https://htmhell.dev/adventcalendar/2022/5/
title: Reading the meter
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/5/
hash: l��~M�u����R�Y
attributes: {"enclosures":[]}
content:
<p>The <code>&lt;meter&gt;</code> element is a little known and rarely used semantic element. It's a non-interactive <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#form-associated_content">form element</a> that renders as a partially filled horizontal bar. Browsers provide user-agent styles, but the <code>&lt;meter&gt;</code> element can also be styled.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>200<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>130<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The example above in Safari, Chrome and Firefox on MacOS.</p>
<p><img src="https://htmhell.dev/images/advent2022/7/meter-browsers.png" alt="The meter element rendered with slightly different shapes, sizes and colors in Safari, Chrome and Firefox."></p>
<p><code>&lt;meter&gt;</code> is sometimes confused with the <code>&lt;progress&gt;</code> element as they are visually similar, but <code>&lt;meter&gt;</code> represents a current value in a known range, while <code>&lt;progress&gt;</code> represents something that is <em>in</em> progress, like a file upload.</p>
<p>The definition found <a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element">in the HTML spec</a> includes some examples of potential uses.</p>
<blockquote>The meter element represents a scalar measurement within a known range, or a fractional value; for example disk usage, the relevance of a query result, or the fraction of a voting population to have selected a particular candidate.</blockquote>
<p>The spec also states that it should not represent an arbitrary range, meaning there should be a known maximum value.</p>
<h2 data-sanitized-id="attributes">Attributes</h2>
<p>Six attributes determine how the <code>&lt;meter&gt;</code> element renders and its basic semantics. The only required attribute is <code>value</code>, and all attributes must be a valid <a href="https://www.freecodecamp.org/news/floating-point-definition/">floating point number</a> (e.g., 5, -22, 7.25).</p>
<p>The following attributes set the value and range.</p>
<ul>
<li><code>value</code> - Current value. Must be between <code>min</code> and <code>max</code>. It can be the only attribute if it's expressed as a decimal fraction (e.g., 0.65, which would represent 65%).</li>
<li><code>min</code> - Minimum value for the range. Must be less than <code>max</code>. Defaults to 0 if not specified.</li>
<li><code>max</code> - Maximum value for the range. Must be greater than than <code>min</code>. Defaults to 1 if not specified.</li>
</ul>
<p>The following attributes set boundary segmentation. The bar can render in different colors based on their value. They also can provide additional semantic information for screen readers to announce.</p>
<ul>
<li><code>low</code> - Upper boundary of the low end of the range, or where the low range ends. Must be greater than <code>min</code> and less than <code>high</code> or <code>max</code>.</li>
<li><code>high</code> - Lower boundary of the high end of the range, or where the high range begins. Must be less than <code>max</code> and greater than <code>low</code>.</li>
<li><code>optimum</code> - Indicates the optimum point in the range. If unspecified, the midpoint between minimum and maximum values is the optimum.</li>
</ul>
<p>A summation from the HTML spec ...</p>
<ul>
<li>minimum value ≤ actual value ≤ maximum value.</li>
<li>minimum value ≤ low boundary ≤ high boundary ≤ maximum value.</li>
<li>minimum value ≤ optimum point ≤ maximum value.</li>
</ul>
<p>All of the following are valid:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>.65<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>35<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="semantics-and-labeling">Semantics and labeling</h2>
<blockquote>Authors are encouraged to include a textual representation of the gauge's state in the element's contents, for users of user agents that do not support the <code>&lt;meter&gt;</code> element. – <a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element">HTML spec</a></blockquote>
<p>There are several screen readers in use today, and without access to all of them it's hard to know how well <code>&lt;meter&gt;</code> is supported.</p>
<p>According to a <a href="https://webaim.org/projects/screenreadersurvey9/">survey of screen reader users</a> by WebAIM released in 2021, the most commonly used <a href="https://webaim.org/projects/screenreadersurvey9/#used">desktop/laptop screen readers</a> among respondents were JAWS and NVDA, and the most commonly used <a href="https://webaim.org/projects/screenreadersurvey9/#mobilescreenreaders">mobile screen reader</a> was VoiceOver. On desktop/laptop the most common <a href="https://webaim.org/projects/screenreadersurvey9/#browsercombos">browser and screen reader combinations</a> were JAWS and Chrome (32.5%) and NVDA and Chrome (16%).</p>
<p>In 2018 Scott O'Hara <a href="https://scottaohara.github.io/a11y_styled_form_controls/src/meter/">tested and documented</a> the effect of styling on the <code>&lt;meter&gt;</code> element:</p>
<blockquote>JAWS 2018 + Chrome (latest)  — Chrome + JAWS will announce both styled and unstyled <code>meter</code> elements and their current value, with no indication of their low, high, or max values. If a <code>meter</code> is provided an accessible name by `aria-label` or <code>aria-labelledby</code>, it will be completely ignored by JAWS.</blockquote>
<blockquote>NVDA 2018.2.1 + Chrome (latest) — Chrome + NVDA do not have issues with announcing styled meters unless they are given an accessible name via aria-label or aria-labelledby. Doing so will result in NVDA only announcing the accessible name and none of the meter's current state.</blockquote>
<blockquote>NVDA 2018.2.1 + Firefox 63 (nightly) — NVDA will announce nothing but the accessible name to meter elements, regardless of if they are styled or not.</blockquote>
<blockquote>VoiceOver + Safari 11.1.1 &amp; 12.0 on macOS High Sierra — VoiceOver will completely ignore a styled meter element unless it has an accessible name set by aria-label or aria-labelledby. But even then, VoiceOver will only announce the accessible name and none of the meter's current state.</blockquote>
<blockquote>VoiceOver + Safari on iOS 11.4 &amp; 12.1 — VoiceOver will completely ignore the existence of meter elements, regardless of if they are styled or not.</blockquote>
<p>Using NVDA and Narrator via <a href="https://assistivlabs.com/">Assistiv Labs</a> and VoiceOver with Safari on MacOS and iOS we can we can see if support for the <code>&lt;meter&gt;</code> element has improved since 2018. The tests below use the following versions of screen readers and browsers:</p>
<ul>
<li>NVDA (2022.3) + Chrome (106)</li>
<li>NVDA (2022.3) + Firefox (105)</li>
<li>Narrator (21H2) + Edge (106)</li>
<li>VoiceOver + Safari MacOS 15.6.1</li>
<li>VoiceOver + Safari iOS 15.6.1</li>
</ul>
<p>Narrator (Windows) and VoiceOver (Mac) are included in their respective operating systems and <a href="https://www.nvaccess.org/download/">NVDA</a> is a free open source screen reader available for Windows. <a href="https://www.freedomscientific.com/products/software/jaws/">JAWS</a> is paid screen reader for Windows and is not included in these tests.</p>
<p>Using our original example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>.65<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>35<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/QWrJVPm">View at CodePen</a></p>
<ul>
<li>NVDA + Chrome announces "progress bar" + the value (e.g, "progress bar .65", "progress bar 10").</li>
<li>NVDA + Firefox announces "progress bar" + the value (e.g, "progress bar .65", "progress bar 10").</li>
<li>Narrator + Edge announces the value as a percent + "meter" (e.g., "65% meter").</li>
<li>VoiceOver MacOS announces the value as a percent + "level indicator" if <code>min</code> and/or <code>max</code> are the only attributes present (e.g., "65%, level indicator). If <code>low</code>,  <code>high</code>, or <code>optimum</code> are present the value is announced as "critical value", "suboptimal value" or "optimal value" + "level indicator" (e.g., "optimal value, level indicator").</li>
<li>VoiceOver iOS announces the same as MacOS but does not include "level indicator" (e.g., "65%", "optimal value").</li>
<li>None of them explicitly announce the <code>min</code>, <code>max</code>, <code>low</code>, <code>high</code> or <code>optimum</code> values.</li>
</ul>
<h3 data-sanitized-id="fallback-text">Fallback text</h3>
<p>Using fallback text within the <code>&lt;meter&gt;</code> is the textual representation mentioned in the spec. Adding fallback text to our original example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>.65<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>65% complete<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>10 out of 100<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>30/100<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>35<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>35 out of 100 items<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>20 centimeters long out of 100 total<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/QWrJVPm">View at CodePen</a></p>
<ul>
<li>NVDA + Chrome ignores fallback text and announces value only (e.g, "progress bar .65", "progress bar 10").</li>
<li>NVDA + Firefox announces progress bar + fallback text (e.g., "progress bar 65% complete").</li>
<li>Narrator + Edge ignores fallback text and announces value only (e.g., "65% meter").</li>
<li>VoiceOver MacOS announces fallback text + level indicator if <code>min</code> and/or <code>max</code> are the only attributes present (e.g., "65% complete, level indicator"). If <code>low</code>, <code>high</code>, and/or <code>optimum</code> are present the fallback text is announced + "critical value", "suboptimal value" or "optimal value" + "level indicator (e.g., "20 centimeters long out of 100 total, critical value, level indicator").</li>
<li>VoiceOver iOS announces the same as MacOS but does not include "level indicator" (e.g., "65% complete").</li>
</ul>
<p>In addition to NVDA + Chrome and Narrator + Edge, fallback text is also not announced in NVDA + Edge and MacOS + Chrome. Support for the feature likely comes from the browser engine rather than the screen reader given that both Chrome and Edge use Blink.</p>
<h3 data-sanitized-id="labeling">Labeling</h3>
<p>Labeling can provide additional information or meet the requirements of your use case (e.g., you need a visible label). Using our original example and adding various labeling techniques:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-1<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Tasks<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>.65<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>cookies eaten<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>10 out of 100<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">title</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>articles written<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>30/100<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-2<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Shows watched<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>35<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-2<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-3<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Length in centimeters<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-describedby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>meter-3<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/QWrJVPm">View at CodePen</a></p>
<ul>
<li>NVDA + Chrome announces all labeling techniques (e.g., "Tasks, progress bar 0.65").</li>
<li>NVDA + Firefox announces all labeling techniques (e.g., cookies eaten, progress bar 10 out of 100).</li>
<li>Narrator + Edge announces all labeling techniques (e.g., "articles written, 13% meter")</li>
<li>VoiceOver MacOS announces all labeling techniques except <code>title</code> (e.g., "30/100, level indicator" without announcing "articles written").</li>
<li>VoiceOver iOS announces all labeling techniques including <code>title</code>.</li>
<li>Using <code>label</code> or <code>aria-label</code> added a double announcement of the label (e.g., "Tasks, 65% complete, tasks, level indicator" or "Tasks, Tasks 65% meter") for VoiceOver and Narrator.</li>
</ul>
<p>There have been a few of improvements in screen reader support for the <code>&lt;meter&gt;</code> element since 2018.</p>
<ul>
<li>NVDA as of version 2020.4 using an accessible name (<code>aria-label</code> or <code>aria-labeledby</code>) no longer voids announcement of the <code>&lt;meter&gt;</code>'s state.</li>
<li>VoiceOver on iOS no longer ignores an unstyled <code>&lt;meter&gt;</code> element.</li>
</ul>
<p>It's unknown if accessible names still cause JAWS to ignore the content of the <code>&lt;meter&gt;</code> element.</p>
<h2 data-sanitized-id="color-contrast">Color Contrast</h2>
<p>Browsers provide user-agent styles for the <code>&lt;meter&gt;</code> element, and each browser uses slightly different colors. Generally the default colors don't provide sufficient contrast against a white background to pass Web Content Accessibility Guidelines (WCAG) AA 2.1 standard of at least a 3.1 contrast ratio between graphical elements and adjacent colors (<a href="https://www.w3.org/TR/WCAG21/#non-text-contrast">success criterion 1.4.11 non-text contrast</a>). A black or very dark background is the best bet for color contrast using the default styling.</p>
<img src="https://htmhell.dev/images/advent2022/7/meter-contrast.png" alt="Green, yellow and red meter bars against white and black backgrounds for Safari, Chrome and Firefox." loading="lazy" width="800" height="672">
<p>Keep in mind there can be variations between operating systems and displays, as well as browsers. My machine (2017 iMac 5k retina with default calibration) produced the following results (<a href="https://docs.google.com/spreadsheets/d/1x530peUSnh5Ir_77pkmZf6yVFxK700pMqB8QdbeOZvU/edit?usp=sharing">Google sheet with hex colors and contrast ratios</a>):</p>
<ul>
<li>Black background
<ul>
<li>Chrome, Firefox, Safari - all three color passed.</li>
</ul>
</li>
<li>White background
<ul>
<li>Chrome - green and red passed, yellow failed.</li>
<li>Firefox - red passed, green and yellow failed.</li>
<li>Safari - all three colors failed.</li>
</ul>
</li>
</ul>
<p>Other items of note:</p>
<ul>
<li>Firefox provides borders that have at least 3.1 contrast ratio against a white background, but don't meet that contrast threshold with the adjacent fill color.</li>
<li>In Safari the unused portion of the bar is transparent against a dark background.</li>
<li>Using Windows High Contrast Mode the <code>&lt;meter&gt;</code> bar fill rendered using the "selected text" color regardless of whether or not it was styled.</li>
</ul>
<h2 data-sanitized-id="using-optimum-to-render-different-colors">Using <code>optimum</code> to render different colors</h2>
<p>When using a combination of <code>min</code>, <code>max</code> and <code>value</code> the bar color will be green regardless of the value. When including any combination of <code>low</code>, <code>high</code> and <code>optimum</code> the bar colors can be changed without any additional styling.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter#attr-optimum">MDN sums up using optimum</a>:</p>
<blockquote>When used with the <code>low</code> attribute and <code>high</code> attribute, it gives an indication where along the range is considered preferable. For example, if it is between the <code>min</code> attribute and the <code>low</code> attribute, then the lower range is considered preferred. The browser may color the meter's bar differently depending on whether the value is less than or equal to the optimum value.</blockquote>
<p>An example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- Bar colors: yellow, green, yellow --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>40<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>90<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- Bar colors: red, yellow, green --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>40<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>90<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- Bar colors: green, yellow, red --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>40<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>10<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>90<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/KKRJwqW">View at CodePen</a></p>
<p>It's best to play around with your values to see how it behaves, but generally</p>
<ul>
<li>Using only <code>low</code> and <code>high</code> will render orange/amber or green.</li>
<li>Adding <code>optimum</code> can additionally render red.</li>
</ul>
<p>Daniel Aleksandersen discovered <a href="https://www.ctrl.blog/entry/html-meter-segment-boundaries.html">browsers can render the segment boundaries differently</a> depending on how they interpret the spec.</p>
<blockquote>Firefox’s implementation is consistent: the values of the attributes are excluded from the segments with the same name (exclusive). Like Firefox, Chrome and Safari exclude the <code>low</code> attribute value from the low segment. Unlike Firefox, Chrome and Safari include the <code>high</code> attribute value in the high segment (inclusive).</blockquote>
<p>There's a <a href="https://github.com/whatwg/html/issues/3520">bug filed against the spec</a> to call for clarification. In the meantime he's also <a href="https://www.ctrl.blog/entry/html-meter-segment-boundaries.html">discovered a workaround</a> if you encounter the issue.</p>
<h2 data-sanitized-id="styling">Styling</h2>
<p>Considering contrast issues, potential rendering differences or the needs of your use case you may want to style the <code>&lt;meter&gt;</code> element.</p>
<p>In 2013 <a href="https://css-tricks.com/html5-meter-element/">CSS Tricks created a comprehensive post</a> that still seems to be considered the go-to for <code>&lt;meter&gt;</code> styling. A more <a href="https://uipencil.com/2022/08/30/how-to-create-a-meter-scale-from-pure-html-html-meter-tag/">recent post at UI Pencil</a> has a straightforward bar color, shape and size example. Creating the example from that post <a href="https://codepen.io/superterrific/pen/ZEoVyKW">at CodePen</a> allowed for screenreader testing to see how styling might impact screen reader support.</p>
<img src="https://htmhell.dev/images/advent2022/7/meter-styled.png" alt="Three meter bars styled with colors different than the default colors." loading="lazy" width="568" height="466">
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Battery Life<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>Current value = 15</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>15<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    15% battery remaining</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>Current value = 59</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>59<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    59% battery remaining</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>Current value = 88</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>88<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    88% battery remaining</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/ZEoVyKW">View at CodePen</a></p>
<ul>
<li>NVDA + Chrome styling has no effect, announces "progress bar" + value (e.g., "Current value = 15, progress bar 15").</li>
<li>NVDA + Firefox styling has no effect, announces "progress bar" + fallback text (e.g., "Current value = 15, progress bar 15% battery remaining").</li>
<li>Narrator + Edge styling has no effect, announces value as percent + meter (e.g., "Current value = 15, 15% meter").</li>
<li>VoiceOver MacOS ignores the <code>&lt;meter&gt;</code> when styled, including fallback text (e.g., "Current value = 15"). Will announce an accessible name (e.g., <code>aria-label</code>) but add "empty group".</li>
<li>VoiceOver iOS ignores the <code>&lt;meter&gt;</code> when styled, including accessible name (e.g., <code>aria-label</code>).</li>
<li>Including an accessible name had no negative impact on NVDA and Narrator.</li>
</ul>
<p>The example above includes the text labels as <code>&lt;p&gt;</code> tags. Including the value in this way worked well for VoiceOver as it only announced the text (e.g., Current value = 15). The downside of this approach is that it added a bit of verbosity for NVDA and Narrator.</p>
<h2 data-sanitized-id="use-case-examples">Use case examples</h2>
<p>The previously mentioned 2013 CSS Tricks article has a <a href="https://css-tricks.com/html5-meter-element/#aa-experiment-2-osx-style-disk-usage">disk space usage example</a> and accompanying <a href="https://codepen.io/pankajparashar/pen/ALgGqm">CodePen</a>. It's a good example of extending the <code>&lt;meter&gt;</code> element with styling while supporting people using assistive technology. The <code>&lt;meter&gt;</code> element semantically communicates the total disk usage while being styled to visually display the segments (audio, movies, photos, apps, other). If the <code>&lt;meter&gt;</code> information is not announced the adjacent text and unordered list ensures all the vital information is communicated.</p>
<p>Leslie Cohn Wein posted about a recent <a href="https://leslie.dev/posts/writing-semantic-html-even-when-you-dont-know-any-better/">budgeting use case</a> where talking through the scenario helped to clarify the semantics between <code>&lt;meter&gt;</code> and <code>&lt;progress&gt;</code>, and for her use case <code>&lt;meter&gt;</code> was the better choice.</p>
<p>Lea Verou recently posted about attempting to use the <a href="https://lea.verou.me/2022/08/on-ratings-and-meters/"><code>&lt;meter&gt;</code> element for star ratings</a>, and her explorations for creating a web component that's still a work in progress. Sven Wolfermann also created a <a href="https://codepen.io/maddesigns/pen/oQoMre">star rating example at CodePen</a> inspired by Verou's work.</p>
<h2 data-sanitized-id="should-you-use-the-lessmetergreater-element?">Should you use the <code>&lt;meter&gt;</code> element?</h2>
<p>On first glance the <code>&lt;meter&gt;</code> element might seem straightforward for accessibility given that it's a semantic element, but testing has shown the support is not uniform.</p>
<p>If you're building something for an internal team where the all of the devices, browsers and assistive technology in use are known, you're likely to be in a much better position to make the <code>&lt;meter&gt;</code> element accessible to all. If you're building for a wider audience it's tougher to ensure.</p>
<p>Given the lack of sufficient contrast against light backgrounds, styling the <code>&lt;meter&gt;</code> element with at least a 3.1 contrast ratio against the background or adjacent colors is a good approach. Styled <code>&lt;meter&gt;</code> elements have relatively good support for desktop/laptop, but VoiceOver on iOS, a <a href="https://webaim.org/projects/screenreadersurvey9/#mobilescreenreaders">popular mobile screen reader</a>, ignores the <code>&lt;meter&gt;</code> when styled.</p>
<p>Using visually hidden text instead of fallback text or accessible names presents an option that can make using the <code>&lt;meter&gt;</code> element more accessible, regardless of whether or not it's styled.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"> <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>65<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"> <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>visually-hidden<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>65 out of 100 items<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"> <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meter</span> <span data-sanitized-class="token attr-name">min</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">max</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>100<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">low</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>30<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">high</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>80<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">optimum</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>85<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>20<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>meter</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"> <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>visually-hidden<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>20 centimeters long out of 100 total<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p><a href="https://codepen.io/superterrific/pen/YzvQBNK?editors=1100">View at CodePen</a></p>
<p>Above code not styled:</p>
<ul>
<li>NVDA + Chrome announces "progress bar" + value + text (e.g., "progress bar 65. 65 out of 100 items").</li>
<li>NVDA + Firefox announces "progress bar" + value + text (e.g., "progress bar 65. 65 out of 100 items").</li>
<li>Narrator + Edge announces value as a percent + "meter" + text (e.g., "65% meter. 65 out of 100 items").</li>
<li>VoiceOver + MacOS announces value as percent + "level indicator" + text (e.g., "65% level indicator. 65 out of 100 items").</li>
<li>VoiceOver + iOS announces value as percent + text (e.g., "65%. 65 out of 100 items").</li>
</ul>
<p>Above code styled:</p>
<ul>
<li>NVDA + Chrome announces "progress bar" + value + text (e.g., "progress bar 65. 65 out of 100 items").</li>
<li>NVDA + Firefox announces "progress bar" + value + text (e.g., "progress bar 65. 65 out of 100 items").</li>
<li>Narrator + Edge announces value as a percent + "meter" + text (e.g., "65% meter. 65 out of 100 items").</li>
<li>VoiceOver + MacOS announces only text (e.g., "65 out of 100 items").</li>
<li>VoiceOver + iOS announces only text (e.g., "65 out of 100 items").</li>
</ul>
<p>This approach ensures announcement for mobile VoiceOver users and provides more consistently supported announcement than fallback text, albeit at the expense of some verbosity.</p>
<p>One issue to note with this approach is that there's a pause between the <code>&lt;meter&gt;</code>'s content and visually hidden text for the combinations that announce both. This may be confusing and not achieve the goal if it's unclear that the <code>&lt;meter&gt;</code>'s content and visually hidden text are related. Testing with screen reader users would help to clarify if this approach works.</p>
<h2 data-sanitized-id="conclusion">Conclusion</h2>
<p>In 2018 <a href="https://scottaohara.github.io/a11y_styled_form_controls/">Scott O'Hara said</a> of the <code>&lt;meter&gt;</code> and <code>&lt;progress&gt;</code> elements...</p>
<blockquote>Unfortunately, neither of these elements are consistently accessible to screen readers. Styling each can actually make them even more inaccessible</blockquote>
<p>There have been improvements since his <a href="https://scottaohara.github.io/a11y_styled_form_controls/src/meter/">initial tests</a>, but there are still inconsistencies and unknowns. And styling can still render the <code>&lt;meter&gt;</code> inaccessible for VoiceOver + Safari on MacOS and iOS.</p>
<p>If you are going to use the <code>&lt;meter&gt;</code> element, use it with caution and keep these things in mind:</p>
<table>
<thead>
<tr>
<th>Screen reader + browser</th>
<th>Announces fallback text</th>
<th>Announces accessible name</th>
<th>Styling breaks announcement</th>
<th>Announces extra information based on high, low, optimum</th>
</tr>
</thead>
<tbody>
<tr>
<td>NVDA + Chrome</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>NVDA + Firefox</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Narrator + Edge</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>VoiceOver + Safari MacOs</td>
<td>Yes unless styled</td>
<td>Yes including when styled</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>VoiceOver + Safari iOS</td>
<td>Yes unless styled</td>
<td>Yes unless styled</td>
<td>Yes</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<ul>
<li>Don't assume the <code>&lt;meter&gt;</code> element's semantics are uniformly supported or announced across screen readers.</li>
<li>Pay attention to contrast. When using default colors a dark background is best.</li>
<li>If you're supporting light and dark mode or themes, make sure your <code>&lt;meter&gt;</code> bar fill colors work across the board.</li>
<li>If styling, assume it will break or nullify semantic support for assistive technology and provide semantic information (e.g., value, additional labeling) using methods with broad support.</li>
<li>Accessible names (<code>aria-label</code>, <code>aria-labeledby</code>) may cause some screen readers to ignore the <code>&lt;meter&gt;</code> element content and only announce the accessible name (<a href="https://scottaohara.github.io/a11y_styled_form_controls/src/meter/">source</a> - JAWS, and potentially other screen readers not tested here).</li>
<li>As always, it's best to test with a screen reader, and if you can hire screen reader users to test, even better.</li>
</ul>
<h2 data-sanitized-id="resources">Resources</h2>
<ul>
<li><a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element">HTML Spec</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter">MDN</a></li>
<li><a href="https://scottaohara.github.io/a11y_styled_form_controls/src/meter/">Styled Meter Accessibility Tests 2018</a></li>
<li><a href="https://www.ctrl.blog/entry/html-meter-segment-boundaries.html">The HTML meter element and it's (undefined) segment boundaries</a></li>
</ul>
<h2 data-sanitized-id="special-thanks">Special thanks</h2>
<p>Many thanks to <a href="https://ericwbailey.website/">Eric Bailey</a> for reviewing this post. His thoughtful feedback notably improved the outcome and increased my understanding. And a special thank you to <a href="https://www.matuzo.at/">Manuel Matuzovic</a> for his unwavering dedication to saving us all from HTMHell.</p>


