We were jumping from h1 to h3 and some of these sections (cards and
processes) had h3 tags inside them.
My best guess is we were using h3 so the titles were smaller. So I'm
adding a CSS mixin to easily use a font size of a different heading tag.
* Add a header element as component markup wrapper
* Allow component to receive an optional block
* Add reusable styles for header links
Co-autored-by: Javi Martín <javim@elretirao.net>
This way we'll be able to apply it to the SDG icon, which is not
included in font-awesome.
Note we're adding a font-icon selector so it's defined before the
admin-menu-icon selector and so in case of conflicting rules the ones in
the admin-menu-icon selector are used.
We were using a "push" div in order to force the footer to the bottom,
and were using a wrapper with a minimum height and negative margins.
The same thing can be accomplished using flex and making the wrapper
fill the empty space, which in my humble opinion simplifies the code and
makes it easier to follow.
We could further simplify the code by removing the wrapper div or the
footer wrapper, although I'm not sure the benefits overcome potential
inconveniences caused to other institutions who might have custom styles
based on the existence of these wrappers.
Combining the max-width and the white-space property resulted in the
text exceeding its bounds if the text was longer than what the max-width
property allowed.
The `width: max-content` property, on the other hand, is compatible with
the max-width property.
The planned budget investments redesign includes using icons in some
tables, so we might as well use them everywhere.
The original design used Foundation to show the tooltips. We're using
CSS in order to keep the ERB/HTML code simple. One advantage of using
CSS is we can show the tooltip on focus as well, just like accessibility
guidelines recommend [1]. On the other hand, Foundation tooltips appear
on the sides when the link is at the bottom of the page, making sure
they're visible in this case, while CSS tooltips do not. Neither CSS
tooltips nor Foundation tooltips are dismissable, which might be an
accessibility issue.
Note we aren't changing any ERB files in order to replace links with
icons; we're only changing CSS and one line of Ruby code.
[1] https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus
There are a dozen ways to add an icon used for decoration. Each of them
offers advantages and disadvantages regarding these topics:
* Accessibility
* Ease of use for developers
* Ease of customization for CONSUL installations
* Maintainability
* Resulting file size
* Number of HTTP requests
* Browser support
* Robustness
We were using one of the most common ones: icon fonts. This technique
shines in many of these aspects. However, it misses the most important
one: accessibility. Users who configure their browser to display a
custom font would see "missing character" icons where our icons should
be displayed. Some users have pointed out they use a custom font because
they're dyslexic and webs using icon fonts make it extremely painful for
them [1].
Screen reader users might also be affected, since screen readers might
try to read the UTF-8 character used by the icon (even if it uses a UTF
Private Use Area) and will react to it in inconsistent ways. Since right
now browser support for different techniques to prevent it with CSS
ranges from non-existant (CSS speech module) to limited (use an
alternative text in the `content` property [2]), we've been adding an
HTML element with an `aria-hidden` attribute. However, by doing so the
ease of customizations for CONSUL installations is reduced, since
customizing ERB files is harder than customizing CSS.
Finally, font icons are infamous for not being that robust and
conflicting with UTF settings in certain browsers/devices. Recently Font
Awesome had a bug [3] because they added icons out of the Private Use
Area, and those icons could conflict with other UTF characters.
So, instead of loading Font Awesome icons with a font, we can add them
using their SVG files. There are several ways to do so, and all of them
solve the accessibility and robustness issues we've mentioned, so that
point won't be mentioned from now on.
All these techniques imply having to manually download Font Awesome
icons every time we upgrade Font Awesome, since the `font-awesome-sass`
gem doesn't include the `sprites/` and `svgs/` folders Font Awesome
includes in every release. So, from the maintenance poing of view,
they're all pretty lacking.
Method 1: SVG sprites with inline HTML
We can use SVG files where template icons are defined, like so:
<svg>
<use xlink:href="solid.svg#search"></use>
</svg>
This technique has great browser support and it only generates one HTTP
request for all icons. However, it requires adding <svg> tags in many
views, making it harder to customize for CONSUL installations. For
developers we could reduce the burden by adding a helper for these
icons.
Downloading all the icons just to use one (or a few) might also be
inconvenient, since the total file size of these icons will be up to a
megabyte. To reduce the impact of this issue, we could either minimize
the SVG file, compress it, or generate a file with just the icons we
use. However, generating that custom file would be harder to maintain.
Method 2: CSS with one SVG icon per file
We can use the separate SVG files provided by Font Awesome, like so:
background: url("solid/search.svg");
Or, if we want to add a color to the icon:
backgound: blue;
mask-image: url("solid/search.svg");
Using this technique will result in one HTTP request per icon, which
might affect performance. Browser support is also limited to browsers
supporting mask-image, which at the time of writing is 95% of the
browsers, with the notable exception of Internet Explorer 11.
On the plus side, using CSS makes it easy to customize and (IMHO) easy
to work with on a daily basis.
Method 3: CSS with SVG sprites
We can use the aforementioned sprites provided by Font Awesome and use
them with CSS:
backgound: blue;
mask-image: url("solid.svg#search");
The number of HTTP requests and file size are similar to Method 1, while
browser support, ease of customization and ease of use are similar to
Method 2.
There's one extra gotcha: this method requires doing minor changes to
the files provided by Font Awesome, which means this solution is harder
to maintain, since we'll have to do the same changes every time we
upgrade Font Awesome. Mainly we need to add these changes to every
sprite file:
- <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
+<!--
+This is a modified version of Font Awesome Free regular sprite file.
The icons are exactly as they originally were; the only changes are:
+
+* <symbol> tags have been replaced with <svg> tags and a <style> tag
has been added
+* A <style> tag has been added
+* The style="display:none" attribute of the main <svg> tag has been
removed
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+ <style>
+ svg svg { display: none }
+ svg svg:target { display: inline }
+ </style>
And then replace every <symbol> tag with a <svg> tag.
Method 4: CSS with Data URI
Finally, we can write the icons directly in the CSS:
backgound: blue;
mask-image: url('data:image/svg+xml;utf8,<svg...');
This method does not generate any extra HTTP requests and only downloads
the icons we need. However, maintaining it is really hard, since we need
to manually copy all the <svg> code for every icon we use, and do it
again every time we upgrade Font Awesome.
In this commit, we implement Method 2. To improve browser support, we're
falling back to font icons on browsers which don't support mask images.
So 5% of the browsers might still conflict with users changing the fonts
or with screen readers trying to announce the icon character. We believe
this is acceptable; the other option for these browsers would be to show
those icons as a background image, meaning the icons would always be
black, meaning users of these browsers would have trouble to distinguish
them if the background was dark as well.
Since we aren't sure whether the performance hit of having one HTTP
request per icon is overcome by only requesting the icons we actually
use, we aren't taking this factor into account when choosing between
methods 2 and 3. We believe this method will be the less painful one to
maintain and customize. Generating SVG sprites with just the icons we
use would increase performance, but it would make it harder for existing
CONSUL installations to use icons we haven't included in the sprites.
[1] https://speakerdeck.com/ninjanails/death-to-icon-fonts
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/content#Browser_compatibility
[3] https://blog.fontawesome.com/fixing-a-unicode-bug-in-5-14-0/
Even if "r" is shorter, "regular" is easier to understand, and we're
going to store these icons in a folder named "regular", which is the
convention Font Awesome uses.
Instead of having a header with a bottom margin followed by an element
with a negative margin, it makes more sense to have no margin on either
element.
On high-resolution screens where neither the menu nor the main content
were filling the screen, there was a blank space at the bottom which
looked weird.
This way we can simplify the HTML and easily apply font awesome icons to
any element.
Note the mixin uses `extend`, which we generally try to avoid. It's OK
in this case, since `fa-` classes only have one rule, affecting the
content of its `::before` pseudo-element. Unfortunately we can't use
`include fa-content($fa-var-#{$icon})` because it's not valid SCSS. We
could make the mixin accept an icon instead of an icon name, and call it
using `has-fa-icon(r, $fa-var-plus-square)`. However, IMHO that would
make the code a bit more complex with no real benefit.
We were using `overflow: scroll` as a workaround with a problem we had
with the equalizer. But now we never need an extra vertical scroll bar,
and we only need an extra horizontal scroll bar on small screens.
Since the dashboard was using the class `admin-content` as well, we need
to apply to the dashboard the same changes we've done in the admin
section. I've extracted them into a mixin.