Desktop sharing is one of the essential things I do every day. For almost 10 years now, I’m using x11vnc to get GUI access on remote Ubuntu desktops. There are many VNC servers, but x11vnc is the best I have found so far, as it works well even under extremely severe bandwidth constraints, i.e., it can easily live with 1 Mbit/s in the uplink when using the highest compression scheme. And if nothing happens on the desktop, there is almost no data transmitted. As the name implies, x11vnc is based on the x11 display server. That’s a bit of a problem these days, as all Linux distributions that use the Gnome desktop, including Ubuntu, are trying very hard for years now to switch to the newer Wayland display server. One of the problems that have plagued all attempts so far was the lack of a usable remote desktop solution. But now, it looks like Ubuntu will make Wayland the default compositor in the upcoming 22.04 Long Term Support (LTS) version. X11 is still supported, but once Wayland becomes the default, I wonder how much love x11 will still get!? So long story short, I was wondering what kind of remote desktop sharing solution Gnome and Ubuntu are proposing for 22.04 and whether it works as well as x11vnc. The answer was not as bad as I thought, but also not as good as I hoped.
Broken in the Daily Build
It’s still early April 2022 so Ubuntu LTS 22.04 has not yet been released. However, there are daily builds available, so I download the latest one to have a closer look at the built-in desktop sharing. To my surprise, the functionality is totally broken in my daily build, but I’m not the first to notice. More about that later. So I assume for now that in whatever way the current problem will be fixed before 22.04 is released, the result will pretty much look like what is currently built into Ubuntu 21.10. So I got the latest image of that release and continued there.
Wayland, Desktop Sharing and Ubuntu 21.10
In Ubuntu 21.10, desktop sharing works in Wayland mode and I could activate it in the settings. I then used Remmina and its VNC plugin to connect remotely. In the local network, this works very nicely and the remote UI is responsive to mouse clicks and key presses. A positive surprise!
However, I could already see there and then that the bandwidth requirements are huge. Double digit Mbit/s datarates were not out of the ordinary. While this is no problem in the local network, such data rates are a total showstopper when connecting to a device over a slow Internet connection with 1-2 Mbit/s. Also, connecting to moving devices and quickly changing backhaul speeds, e.g. in trains (yes, I do that) is just out of the question at such speeds.
Minimum Data Rates
So what’s the slowest Internet connection Ubuntu’s Wayland based remote desktop sharing is still usable with? I experimented for quite a while and in the highest compression setting, I could get down as low as 2 Mbit/s. Anything less and the session becomes unresponsive. Even at 2 Mbit/s, responsiveness is considerably worse compared to x11vnc. In addition, desktop sharing takes the full 2 Mbit/s of bandwidth at all times, even if nothing changes on the screen. This significantly slows down other applications running over the slow remote line at the same time. So while I’m glad it works at all, I’m not so happy that some of my major use cases can’t be covered with that solution.
In addition, there are a number of other things that would make my live difficult with Ubuntu’s Wayland desktop sharing. Fortunately, I found a workaround for each of them:
No Localhost Option
The first thing that bugged me was that when desktop sharing is activated, it is open to all incoming IP addresses. That’s a problem, because VNC only uses 8 character passwords. That’s not strong enough by far. X11vnc shares the same problem, but I usually run the vnc server in ‘localhost’ mode, i.e. it only accepts incoming connections from 127.0.0.1. To access desktop sharing, I establish an ssh session and activate port forwarding. The way around this with Ubuntu’s built in Wayland desktop sharing is to use the Universal Firewall (ufw) and limit incoming access to port 5900 to localhost. I haven’t tried if this works, but I’m pretty confident that this can be made to work.
In Ubuntu’s settings menu, Remote Desktop Sharing can and has to be activated per Wi-Fi SSID. That’s nice but many devices I support frequently change Wi-Fi networks and I can’t get to the GUI remotely to activate desktop sharing in a new Wi-Fi. Fortunately, I usually do have SSH connections to those machines, even if they change networks frequently, and running
systemctl --user start gnome-remote-desktop
on the shell activates the remote desktop server if it is not running.
Restarting Hung Sessions
You might have noticed that nothing is perfect. Internet connectivity on the move in particular. If a VNC connection is interrupted, the vnc server hangs, and it’s not possible to log-in again. Also, there’s no way on the GUI to get things going again. But once the ssh link is up again, killing the remote desktop server and starting it again on the shell gets things running again.
Over slow connections, VNC suffers from characters that keep repeating. I didn’t have much of a problem with that, as x11vnc can handle very slow connections. With gnome-remote-desktop with the VNC backend, this is much more of a problem over slow connections. The fix: On the remote host, disable ‘repeat keys’ in the ‘Universal Access’ settings. Cool, I can use this for my current x11 setup as well in special situations.
Summary and Way Forward
Over relatively fast and un-metered Internet connections, Ubuntu’s Wayland desktop sharing with gnome-remote-desktop and the VNC backend works quite well. Unfortunately, my low bandwidth use-case is the norm rather than the exception for me, so it’s not a solution for me. Fortunately, it’s also possible to switch from Wayland to x11 for a user when logging in, and Ubuntu remembers this decision across reboots. In the next episode I’ll therefore have a closer look how x11vnc behaves in Ubuntu 22.04 LTS. Also, there is still the possibility that Ubuntu will switch to the RDP backend of the gnome-remote-desktop package they use for remote desktop sharing, which might change things again. If that happens, I’ll have a closer again.
And to check if the current GUI session runs over X11 or Wayland, the following shell command comes in handy:
I2C is a wonderful interface. With four wires and only two GPIOs, you can connect a whole lot of sensors and devices – in parallel, at that! You will see I2C used basically everywhere, in every phone, laptop, desktop, and any device with more than a few ICs inside of it – and most microcontrollers have I2C support baked into their hardware. As a result, there’s a myriad of interesting and useful devices you can use I2C with. Occasionally, maker-facing companies create plug-and-play interfaces for the I2C device breakouts they produce, with standardized pinouts and connectors.
Following a standard pinout is way better than inventing your own, and your experience with inconsistent pin header pinouts on generic I2C modules from China will surely reflect that. Wouldn’t it be wonderful if you could just plug a single I2C-carrying connector into an MPU9050, MLX90614 or HMC5883L breakout you bought for a few dollars, as opposed to the usual hurdle of looking at the module’s silkscreen, soldering pin headers onto it and carefully arranging female headers onto the correct pins?
As with any standard, when it comes to I2C-on-a-connector conventions, you would correctly guess that there’s more than one, and they all have their pros and cons. There aren’t quite fifteen, but there’s definitely six-and-a-half! They’re mostly inter-compatible, and making use of them means that you can access some pretty powerful peripherals easily. Let’s start with the two ecosystems that only have minor differences, and that you’ll encounter the most!
The JST-SH buddies
There’s two ecosystems of I2C modules that are based on four-pin JST-SH (1mm pitch) connectors, and they’re very interchangeable! One of them is Sparkfun’s QWIIC, and other is Adafruit’s STEMMA QT (pronounced ‘cutie’). Both of them are straightforward to add to your PCB, as long as you have a few JST-SH four-pin connectors ready. What’s more – Adafruit and Sparkfun connectors have the same pinout!
The connectors being used are JST-SH, surface-mount, with 1 mm pitch. Their JST family is SR/SH and the part number for the original JST part is SM04B-SRSS-TB, but you can find cheap third-party connectors with the same dimensions on LCSC using “1x4P SH 1mm” search terms. Both QWIIC and STEMMA have pages to refer to when doing your own designs. Now, what are the differences between the two?
QWIIC limits itself to 3.3 V on both host (i.e. MCU board, providing power) and device (i.e. sensor, consuming power) side – a reasonable decision, simplifying things a lot. An overwhelming majority of devices we work with nowadays are 3.3 V, to the point where level-shifting problems are mostly unheard of. Perhaps, the eventual move to 1.8 V will shake that up, but we are not there yet, and factors like LED forward voltages will necessitate some kind of higher-than-1.8 V reference in our project when we get there, anyway. So, 3.3 V power and two 3.3 V logic level I2C signals on a single connector – plain and simple. Chances are, you can already add QWIIC to your sensor or MCU board – without any additional components required but the connector itself!
In contrast, STEMMA QT is built to expand on the possible educational and convenience value, in line with other Adafruit offerings. As such, it allows for 5 V hosts – with devices designed to work in the 3.3 V-5 V power and logic level range, making sure that your Arduino Uno is not left out of the game. This is possible because every module has a low-dropout voltage regulator like the AP2112K or the MIC5219, which helps keep things almost-3.3 V when you feed the board with 3.3 V. The reasoning is simple – apart from 5 V hosts like Arduino Uno, you might also want to chain your STEMMA devices with some power hungry-devices, like I2C-savvy servos or RGB strips. In short, plugging anything into anything, with any kind of chain, shouldn’t result in magic smoke escaping – an event rarely on the TODO list of a maker’s project. One more upside of STEMMA QT is standardization of device board sizes, letting you easily mechanically integrate new sensors into the project before they even arrive to you, and spawning nifty hacks like this STEMMA Qt 3D-printable hotswap socket!
To sum up the voltage compatibility situation – all STEMMA QT devices will work with QWIIC hosts; and all QWIIC devices will work with 3.3 V STEMMA Qt hosts; as a result, any QWIIC host is also technically a STEMMA QT host. QWIIC devices will be fiercely incompatible with 5 V STEMMA QT hosts, but such hosts are rare, and you just have to be on the lookout when interfacing QWIIC devices with STEMMA hosts. Another minor hiccup with both of these standards is lack of interrupt signals – that, I will expand on below, in the “Breakout Garden” section. For now, let’s take a look at STEMMA QT’s bigger sister!
Chaining QWIIC And STEMMA modules
Oh, right, chaining! Both QWIIC and STEMMA QT are chaining-friendly – many modules offering a second JST-SH connector on the opposite side of the board, with the same signals passed through. This lets you wire up your projects in a comfortable way, not having to locate a spot in your project where you can put your MCU while not having it too far from all of your sensors, or not resorting to breadboards for splitting your I2C bus into multiple stubs. Many host boards also offer multiple sockets wired in parallel, and there’s “splitter” boards available that turn a single JST-SH cable with I2C into, say, three extra sockets.
As long as your addresses don’t conflict, you will generally be fine wiring an I2C bus for a project in such a way. Oh, and make sure to not overload your I2C bus with all the pullups added in parallel – they tend to be 10 kΩ for STEMMA QT and 2.2 kΩ for QWIIC, and at least in case of QWIIC, it seems you’re typically able to cut two trace jumpers with an xacto knife to disconnect the pullups on any module. With all non-Pico-based Raspberry Pi boards having 1.8 kΩ onboard pullups on their I2C ports, you might find yourself needing to do that quite early on as you chain devices.
The Bigger, Blacker Connector
STEMMA has the same pinout as STEMMA QT and QWIIC, but a different, larger connector. It, too, is flexible when it comes to voltages you can output on the host end, and in turn, must be able to accept on the device end. Most of the advantages in STEMMA QT section apply to STEMMA, save for QWIIC compatibility and reduced physical size.
STEMMA connectors are JST PH connectors with 2 mm pitch, with JST part number being S4B-PH-SM4-TB, and cheap third-party connectors available with “1x4P PH 2mm” search terms. They’re a bit easier to tackle with a soldering iron than the 1 mm pitch SH connectors, and for larger boards, they’re a good fit.
JST-PH is one of those cases where surface-mount sockets turn out to be way more resilient than the through-hole ones. With a tougher retention mechanism, your fingernails will no longer suffice – you’ll likely want to use your trusty pair of blue flush cutters for unplugging these! I2C-carrying STEMMA also has an GPIO and analog STEMMA counterpart, using 3-pin JST PH connectors for things like WS2812 strips – where 5 V compatibility becomes exceptionally handy. However, 4-pin connectors are firmly reserved for I2C, and such consistency is hard to not appreciate in educational and prototyping environments – checking the dozens of tutorials Adafruit has involving STEMMA devices, the “Wiring” sections in those are extra straightforward! On some STEMMA hosts, you will also be able to rewire the port to either 3.3 V or 5 V through a solder jumper.
Just Can’t Get Into The Grove
The Grove connector standard, oldest of them all, is now somewhat of a black sheep among the I2C connector ecosystems, and is here half as a piece of history, half as a cautionary tale. Contrary to principles of open-source ecosystems, Grove uses a proprietary connector, which has makers scramble for its proper identification as they try to find a source that is not SeeedStudio. Unlike all the other standards listed here, when you see a 4-pin Grove connector, you don’t know if it’s for I2C, UART, two digital GPIOs or something analog, which ruins the whole “plug and play” idea.
To those of you unfortunate to have to interface with Grove, it also uses 3.3 V – 5 V range of possible voltages, but is less interested in explicitly advertising which one is used, or letting you change that – both things that STEMMA does without breaking a sweat. It uses the same pinout for I2C as QWIIC/STEMMA do. If you have a STEMMA-compatible (JST-PH) cable, you can sand it down a bit to make it fit into a Grove connector.
In other words, there’s a good reason you don’t see Grove connectors used more often. I couldn’t help but notice that Tom’s Hardware, when writing the conclusion section of their own I2C connector ecosystem overview article, failed to find an advantage of Grove that wasn’t generic to every other ecosystem they talked about. Unless you want to resign to paying SeeedStudio for every connector and cable you ever need, and are okay never being compatible with connector ecosystems worth investing effort into, I strongly recommend you avoid using Grove on your boards. Let’s spend time on the next – underappreciated – option instead.
A Stroll In The Breakout Garden
The Breakout Garden ecosystem by Pimoroni uses an elegant pinout – taking a row of five pins off the Raspberry Pi GPIO header, pins 1 to 9, including 3.3 V, SDA, SCL, a GPIO pin and, of course, GND – in this order. They sure don’t hold a patent to this pinout – a whole lot of hackers, myself included, have been using this pinout for ages on our I2C-equipped boards. Such a pinout, for a start, means that you can plug any Breakout Garden board onto a Raspberry Pi directly.
You’re not limited to that, either – Pimoroni also offers nice slide-in connectors that let you hotswap Breakout Garden modules. And, if you don’t want to use the slide-in sockets, just solder angled male pin headers and treat them like any other module. Breakout Garden modules typically have a 3.3 V – 5 V input voltage range. They also claim reverse polarity protection on every module, so, inevitably plugging a module backwards shouldn’t delay your project.
With the Breakout Garden pinout, you also get an extra GPIO, which is most commonly either NC or used as an interrupt pin. Interrupt pins are under-appreciated when working with I2C devices – they let you offload your CPU and your I2C bus, avoiding polling and letting your I2C peripheral signal you when it wants your attention, something not possible through the I2C bus alone. For a few modules, like this haptic actuator driver, the GPIO is used as a “trigger” pin instead, for action synchronisation. That does hurt the concept of chaining somewhat, of course – to be fair, though, so does the bulky hotswap socket. Not that you can’t connect Breakout Garden boards in parallel – after all, INT pin is typically disable-able for I2C devices, which will absolutely come handy, given the the puzzling decision of wiring all the INT pins together on their 6-socket Raspberry Pi HAT.
Adding basic support for “Breakout Garden”-like connection in your project is as simple as adding a five-pin 2.54mm (0.1″) pin header – and with that, you instantly get Raspberry Pi GPIO header compatibility. When it comes to creating your own modules, I couldn’t find any dimensions or an official “how to create” modules, so you’re probably not meant to do that – which doesn’t mean that you can’t reverse-engineer the schematics and the dimensions and then try anyway, but it sure is quite discouraging. If you want to add a Breakout Garden socket, they have two rows of pins that are exactly 5.08mm (0.2″) apart, and provide convenient plug & play connectivity, though with the cost of £1 per socket (not including shipping), the slide-in sockets are the most expensive to use of these all.
Conveniently Crimped Cables
In the market for some JST-SH accessories? You really can’t go wrong with the SMD connectors; however, you absolutely can go wrong when it comes to pre-crimped cables. Crimping JST-SH with its 1 mm pitch is far from easy, and buying your own cables is your best bet – except for when they come miswired. A year ago, I was preparing for a project and bought a bundle of JST-SH cables, pictured to the right. Upon closer inspection, something felt off.
Turned out that they had their cable ends wired in the opposite direction, one’s pinout reverse to that of the other – with likely disastrous consequences when used as an interconnect. The cables I bought will require some careful rewiring with tweezers, and next time you are shopping for third-party JST-SH cables so that you can wire up your next project, you will know to inspect the pictures before pressing the “Buy Now” button.
Mentions Of Variable Honorableness
If you’ve ever worked with DFRobot parts, you might’ve seen JST-PH 4-pin (or 3-pin) connectors on their boards, too – they’re from their ecosystem called Gravity. Puzzlingly enough, Adafruit claims that STEMMA is compatible with Gravity, apart from their non-I2C devices – since Gravity does the same thing that Grove does, where a 4-pin connector doesn’t guarantee I2C. However, checking the pinout for Gravity I2C devices, it seems that every single pin is in a different spot, in particular, ground and power being reversed. Just like STEMMA, they use 3-pin connectors for digital and analog devices. The fun part is, they also managed to change the pinout for those at some point, also reversing the power pin polarity – while still using the same connector, a no-no for connector standards. Proceed with caution!
EasyC is basically QWIIC copied to a T, with the same pinout, connectors, chaining abilities and 3.3 V voltage limit – but not mentioning QWIIC in any way in their webpages and resources, which is a disappointment. Interoperability of different ecosystems is part of what makes them valuable, and arguably, you could be more inclined to buy from them if you knew that the standard they’re using is a widely accepted one – as opposed to “random pinout on some connector”. EasyC is driven by a Croatia-based e-radionica company, producing a medium-sized assortment of useful modules, including quite a few Chinese module clones and remixes – at European prices. Design files for their modules are not linked to from product files, but at least some of them seem to be on their GitHub! Interestingly enough, they also stock a 5cm “EasyC” cable which, upon closer inspection, has the same reversed wiring as the cables I told about in the previous section. Perhaps, putting a bit more thought into the EasyC ecosystem would be warranted.
Sometimes we see companies making an attempt at a JST-SH thing, but not quite getting there. An example of that is a somewhat recent board by Lolin, the Lolin D1 Mini Pro, with a JST-SH 4-pin connector on it labelled “I2C”. You could be forgiven for thinking that this is a QWIIC-like pinout; given that this connector is marked “I2C”, one could argue they’ve been tricked, backstabbed and quite possibly, bamboozled. Instead of GND-VCC-SDA-SCL pinout, this board is using GND-SDA-SCL-VCC, and it appears there’s even a few accessories like shields made with this pinout in mind. It’s as if someone sent Lolin a letter saying “hey, you should put I2C on a JST-SH connector” and then refused to elaborate further. Thankfully, with the GND pins matching, the likelihood of destroying things is not as extreme.
Building Your Own Things? Need Guidance?
Which one of the standards should you follow when designing your own boards? I have provided you with all the information you could ever need to make your own decisions, but if you’re looking for a recommendation or a guideline, I will happily provide one, too.
I personally don’t use full-sized STEMMA (JST-PH) connectors, as way too often, they’re bulky enough to make the PCB itself seem small, and can make small boards a bit unwieldy due to their height – plus, they can be harder to unplug. The JST-SH connectors, however, are way too enticing due to the prospect of being compatible with two ecosystems at once, as long as I avoid 5V hosts. And – a simple, standard pinout 5-pin header provides a surprising amount of benefits for how quickly you can add it!
In short, I recommend that you combine a Breakout Garden-like pin header and the QWIIC/STEMMA QT JST-SH connector on your boards. This way, you will always have compatibility with three out of the four ecosystems worth talking about, and connecting your I2C board to a Raspberry Pi will be as straightforward as getting five jumper cables. With this combination, you will never have to think about I2C header pinouts ever again, and you’ll have an interrupt signal handy for the times when you really could use one.
Do you have to add level shifting? Not if you don’t use 5 V in your projects, and especially not if you’re making a breakout for an IC that has a wide range of input voltages, like, say, I2C EEPROMs and RTCs. I personally work with mainly 3.3 V, and I don’t have reels of AP2112 regulators to sprinkle on every board I make – thankfully, I don’t have 5V I2C hosts, either. In case you do want to make your devices 5 V-compatible, you can’t go wrong with the classic, incredibly elegant, and inexpensive MOSFET solution for I2C level shifting!
Out of these, QWIIC, STEMMA and Breakout Garden have so far stood the test of time, with hobbyist electronics companies backing them all the way there. It is only fair that we benefit from the standards they created. Hopefully, the insights and the instructions provided get us closer to universal interoperability days, when one hacker’s MCU board can seamlessly interface with other hacker’s sensors. From there, one day, our favourite SSD1306 OLED breakouts might start arriving into our mailboxes equipped with a JST-SH connector and an extra cable. Today is not that day, but with every JST-SH footprint we add to our PCB, I believe we will see to it soon.
element provides visual and audible feedback to users about completion. This
visual feedback is valuable for scenarios such as: progress through a form,
displaying downloading or uploading information, or even showing that the
progress amount is unknown but work is still active.
This GUI Challenge worked with
the existing HTML <progress> element to save some effort in accessibility. The
colors and layouts push the limits of customization for the built-in element, to
modernize the component and have it fit better within design systems.
If there is no value, then the element's progress is
The max attribute defaults to 1, so progress is between 0 and 1. Setting max
to 100, for example, would set the range to 0-100. I chose to stay within the 0
and 1 limits, translating progress values to 0.5 or 50%.
If you have healthy vision, it can be easy to associate a progress indicator
with related elements and page areas, but for visually impaired users, it's not
so clear. Improve this by assigning the
attribute to the top-most element that will change when loading is complete.
Furthermore, indicate a relationship between the progress and the loading zone
While the implicit role of a <progress> element is
progressbar, I've made it explicit
for browsers that lack that implicit role. I've also added the attribute
indeterminate to explicitly put the element into a state of unknown, which is
clearer than observing the element has no value set.
screen reader technology, since giving the progress focus as progress changes,
will announce to the user how far the updated progress has reached.
The progress element is a bit tricky when it comes to styling. Built-in HTML
elements have special hidden parts that can be difficult to select and often
only offer a limited set of properties to be set.
The layout styles are intended to allow some flexibility in the progress
element's size and label position. A special completion state is added that can
be a useful, but not required, additional visual cue.
The width of the progress element is left untouched so it can shrink and grow
with the space needed in the design. The built-in styles are stripped out by
setting appearance and border to none. This is done so the element can be
normalized across browsers, since each browser has its own styles for their
The value of 1e3px for _radius uses scientific number
notation to express a
large number so the border-radius is always rounded. It's equivalent to
1000px. I like to use this because my aim is to use a value large enough that
I can set it and forget it (and it's shorter to write than 1000px). It is also
easy to make it even larger if needed: just change the 3 to a 4, then 1e4px is
equivalent to 10000px.
overflow: hidden is used and has been a contentious style. It made a few
things easy, such as not needing to pass border-radius values down to the
track, and track fill elements; but it also meant no children of the progress
could live outside of the element. Another iteration on this custom progress
element could be done without overflow: hidden and it may open up some
opportunities for animations or better completion states.
CSS selectors do the tough work here by comparing the maximum with the value, and if they match, then the progress is complete. When complete, a pseudo-element is generated and appended to the end of the progress element, providing a nice additional visual cue to the completion.
Set two custom properties on the <progress> element, one for the track color
and the other for the track progress color. Inside the
media query, provide new color values for the track and track progress.
Earlier we gave the element a negative tab index so it could be programmatically
customize focus to opt into the smarter focus ring style. With this, a mouse
click and focus won't show the focus ring, but keyboard clicks will. The
YouTube video goes into this in more depth and
is worth reviewing.
Customize the styles by selecting the parts of a <progress> element that each
browser exposes. Using the progress element is a single tag, but it's made of a
few child elements that are exposed via CSS pseudo selectors. Chrome DevTools
will show these elements to you if you enable the setting:
Right-click on your page and select Inspect Element to bring up DevTools.
Click the Settings gear in the top-right corner of the DevTools window.
Under the Elements heading, find and enable the Show user agent shadow
WebKit-based browsers such as Safari and Chromium expose
::-webkit-progress-bar and ::-webkit-progress-value, which allow a subset of
CSS to be used. For now, set background-color using the custom properties
created earlier, which adapt to light and dark.
Notice that Firefox has a track color set from accent-color while iOS Safari
has a light blue track. It's the same in dark mode: Firefox has a dark track but
not the custom color we've set, and it works in Webkit-based browsers.
Custom properties are great for many things, but one of my favorites is simply
giving a name to an otherwise magical looking CSS value. Following is a fairly
but with a nice name. Its purpose and use cases can be clearly understood.
The goal is an infinite animation that goes back and forth. The start and end
keyframes will be set in CSS. Only one keyframe is needed, the middle keyframe
at 50%, to create an animation that returns to where it started from, over and
Not every browser allows the creation of pseudo-elements on the <progress>
element itself or allows animating the progress bar. More browsers support
animating the track than a pseudo-element, so I upgrade from pseudo-elements as
a base and into animating bars.
This function is where the UI/UX orchestration occurs. Get started by creating a
setProgress() function. No parameters are needed because it has access to the
state object, progress element, and <main> zone.
Since I chose to stick with the progress default maximum of 1, the demo
languages, are not always great at
Here's a roundDecimals() function that will trim the excess off the math
With the values updated, sighted users will see the progress change, but screen
reader users are not yet given the announcement of change. Focus the
<progress> element and the browser will announce the update!
There are certainly a few changes I'd like to make if given another chance. I think there's room to clean up the current component, and room to try and build one without the <progress> element's pseudo-class style limitations. It's worth exploring!
Let's diversify our approaches and learn all the ways to build on the web.
Create a demo, tweet me links, and I'll add it
to the community remixes section below!