Commit Graph

35 Commits

Author SHA1 Message Date
Javi Martín
7cf8469fac Improve RTL text support in flex-with-gap mixin
Even if it was looking OK using `margin-left`, there were probably edge
cases where it wouldn't behave as we expected.

As mentioned in the previous commit, this won't be necessary once
everyone uses browsers supporting the `gap` property in flexbox layouts,
but this won't happen for a few years.

In a few months we might also consider using the `margin-inline-start`
property, which is currently supported by about 97% of the browsers [1].

[1] https://caniuse.com/css-logical-props
2021-10-19 02:33:53 +02:00
Javi Martín
4fea839c54 Extract mixin to add a gap to a flexbox layout
This way we remove duplication and it'll be easier to add better support
for RTL languages.

In a few years this might not be necessary since support for the `gap`
property in a flexbox layout will improve. At the time of writing,
however, only 86.5% of the browsers support it [1].

[1] https://caniuse.com/flexbox-gap
2021-10-19 02:33:53 +02:00
Javi Martín
e241bab130 Fix accordion icon overlap in admin menu
Since the icon was absolutely positioned, in some languages it
overlapped with the text.

Using a flex layout solves this issue. It also improves the appearance
of elements whose text spans over multiple lines; previously the second
line would go under their section icon.

We're also using the `$global-left` variable so the icon is properly
displayed in languages written from right to left. We could use the
`margin-inline-start` property instead, but it isn't universally
supported in every browser yet.

Since the layout is now incompatible with the old (and obsolete) way to
add icons to the menu (using classes which would use the
`[class^="icon-"]` selector), we're removing this code.
2021-09-30 13:35:10 +02:00
Javi Martín
fabe97e506 Use a switch control to enable/disable features
We were using buttons with the "Enable" and "Disable" texts to
enable/disable settings. However, when machine learning settings were
introduced in commit 4d27bbeba, a switch control was introduced to
enable/disable them.

In order to keep the interface consistent, we're now using switch
controls in other sections where settings are enabled/disabled. We can
even use the same code in the machine learning settings as well.

We're also removing the confirmation dialog to enable/disable a setting,
since the dialog is really annoying when changing several settings and
this action can be undone immediately. The only setting which might need
a confirmation is the "Skip user verification" one; we might add it in
the future. Removing the confirmation here doesn't make things worse,
though; the "Are you sure?" confirmation dialog was also pretty useless
and users would most likely blindly accept it.

Note Capybara doesn't support finding a button by its `aria-labelledby`
atrribute. Ideally we'd write `click_button "Participatory budgeting"`
instead of `click_button "Yes"`, since from the user's point of view the
"Yes" or "No" texts aren't button labels but indicators of the status of
the setting. This makes the code a little brittle since tests would pass
even if the element referenced by `aria-labelledby` didn't exist.
2021-09-23 13:25:20 +02:00
Javi Martín
35a45837ff Add default focus outline to buttons
We were using a focus outline on links, but weren't doing the same for
buttons. Since sometimes browsers use a default outline which is barely
visible, this was very disorienting when browsing using the keyboard; we
were navigating through links that clearly indicated where the keyboard
focus was, and when reaching a button suddenly we had this almost
imperceptible feedback. Even if I'm used to it, my first reaction is
always "where did the focus go?" until I realize it's now on a button.

This is even more confusing because we've got buttons looking like links
and links looking like buttons.

Note that in the rules for the `:focus` styles we're including buttons
and the `[type="button"]` attribute. This seems redundant since those
styles are already covered by the `button` selector. However, Foundation
adds styles to buttons with the `[type]` attribute. Since the attribute
selector has precedence over the tag selector, we need to use the
attribute selector as well in order to override Foundation's styles.
2021-09-15 13:38:36 +02:00
Javi Martín
3cd2529791 Fix huge header in participatory budgets
The budget header was supposed to be huge, but only in the participatory
budgets index or show actions. It was still huge, with plenty of empty
space, when there was no budget, or in the "submit my ballot" and
"select a heading" pages.
2021-08-09 20:07:51 +02:00
Javi Martín
297956b579 Extract placeholder selector for budget header
This way it'll be easier to reuse its main properties.
2021-08-09 20:07:51 +02:00
Javi Martín
c0a6bf54fc Fix invisible error message in attachments
In commit cc6f9391f we made the images and documents file inputs
invisible (instead of using `display: none`) in order to make it
possible to attach images and documents using the keyboard.

However, since the error messages associated to these inputs has the
same HTML class as the inputs, we were also hiding them (the `display:
none` didn't affect the error messages because they've also got the
`is-visible` class).

Using the `[type=file]` selector we make it more explicit that we only
want to style these inputs.

I'm not adding a test for this scenario because technically the text is
there and I'm not sure how to test for the presence of invisible
elements.
2021-07-27 23:57:41 +02:00
Javi Martín
cc6f9391fc Fix attaching files using the keyboard
We were hiding the file input and styling the label as a button instead.
Since clicking on a label has the same effect as clicking on the input,
the input worked properly for mouse and touch screen users.

However, hiding the input makes it inaccessible for keyboard users,
since labels don't get keyboard focus, but inputs do.

So we must not hide the input but make it invisible instead. But we
still need to hide the input (alongside the label) after a file has been
attached.

We could add some extra JavaScript to hide the input when we hide the
label. Since the JavaScript is already quite complex and my first few
attempts at changing it failed, I've opted to assume that the input (and
its label) must be hidden whenever there's already a file name, and
implement that rule with CSS.

Note we're using the `:focus-within` pseudoclass to style a label when
focus is on the input. This rule (at the time of writing) is only
supported by 93.5% of the browsers. Keyboard users without a screen
reader and using the other 6.5% of the browsers will still be able to
focus on the field but might not notice the field has received focus.
Since the percentage of affected users will decrease over time and until
now 100% of keyboard users were completely unable to focus on these
fields, for now we think this is a good-enough solution.
2021-07-13 17:09:05 +02:00
Javi Martín
a7e2f1ae30 Move file name before the destroy attachment link
This way screen reader users will hear the name of the file before
hearing about the link to destroy it. We were already displaying it this
way visually by having the file name on the left and the destroy link on
the right.

Thanks to this change we can also simplify the code which dynamically
changed the layout.
2021-07-13 16:58:22 +02:00
Javi Martín
8116e75aee Simplify showing/hiding attached file name
Note we have to render the `<p>` tag in one line because at the time of
writing browsers don't consider elements with whitespace inside as empty
[1].

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
2021-07-13 16:58:13 +02:00
decabeza
909fd00714 Update styles and layout for new debates form 2021-07-13 15:27:14 +02:00
Javi Martín
8398d176b5 Allow more elements in investment form header
Since we're going to reuse this pattern in other forms, we shouldn't
rely on the header having just one element. There could be a subtitle.
So we're changing the CSS to be less dependent on a very specific HTML
structure.

Regarding the subtitle, the original idea was to have both an <h1> and
an <h2> element inside the header. However, the W3C advices against it
[1]:

> h1–h6 elements must not be used to markup subheadings, subtitles,
> alternative titles and taglines unless intended to be the heading for
> a new section or subsection.

So we ended up including the subtitle inside he <h1>. We could also add
it in a separate <p> tag. However, in this case I think it's better to
include it in the <h1> (and in the <title> tag) because it helps to
uniquely identify the current page from other pages.

Due to some rounding issues in Firefox, we're manually moving the polygon
6px so there isn't a blank space between it and the icon on the right.
And due to rounding issues in Chrome, we're adding one extra pixel to
the bottom of the polygon defining the clip-path.

[1] https://www.w3.org/TR/html52/common-idioms-without-dedicated-elements.html#common-idioms-without-dedicated-elements
2021-07-13 15:27:14 +02:00
Javi Martín
701378d02c Add padding to the whole header
Instead of adding the padding to each individual element inside the
container, why not adding padding to the container itself? The answer is
"because we want the background of the children elements to take the
width of the whole screen". But this generates either HTML cluttered
with elements to add padding or repetitive padding definitions in the
CSS.

So now we only define the padding once, and when an element requires a
full width background or border, we use the `full-width-background`
mixin.

In this case the code is a bit more complex because the header is also
used in the dashboard and admin layouts:

* In the public layout, the body has a margin, so we include the mixin
  to take margin into account
* In the dashboard layout, the header itself has a margin, so we include
  the same mixin
* In the admin layout, the headet doesn't have a margin but gets the
  whole width, so in this case we include the mixin which dosen't take
  the margin into account

In the future, the idea is to apply this principle to the <body>
element and remove the `@include grid-column-gutter` in the CSS as well
as the `small-12 column` classes in the HTML.

Note we use the `calc()` function inside the mixin instead of using it
in the `$full-width-margin` variable. That way we avoid nested `calc()`
operations, which don't work in Internet Explorer.

Also note we're using `flex-grow: 1` to make one element appear on the
left of the screen and the other one on the right. It would be easier to
use `justify-content: space-between` (which is actually the default for
the top-bar element). However, there's a bug in Internet Explorer and
old versions of Firefox; they include the absolutely-positioned
`::before` element we use to set the full width background when
calculating where to position the elements. The bug was fixed in Firefox
52 (released in 2017).

Finally, we're removing the padding from our logo. In order to allow
logos like the new one and at the same time provide backwards
compatibility to logos in existing CONSUL installations, we're relaxing
the validation rule for the logo width.
2021-07-09 03:45:55 +02:00
Javi Martín
9cc4d52723 Use a global maximum width for the <body> element
We weren't using a global maximum width for the <body> element because
we wanted the background of some elements to cover the whole screen. If
the body didn't cover the whole screen, then we would have to find a way
to extend the background beyond the limits of the body.

Elements can take the whole screen width using a width of 100 viewport
width (vw) units, which weren't as widely supported when CONSUL
development started as they are today.

However, there's a gotcha will vw units; they don't take into account
the vertical scrollbars browsers add when scroll is needed. That means
that an element with a width of 100vw would cause a *horizontal*
scrollbar when the vertical scrollbar appears on the screen. So
approaches like this one wouldn't work:

```
body {
  margin-left: auto;
  margin-right: auto;
  max-width: $global-width;
}

@mixin full-background-width {

  &::before {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
  }
}
```

We could add `overflow-x: hidden` to the body to avoid the horizontal
scrollbar. However, on certain screens sizes that could cause some
content to disappear if there isn't enough horizontal space for all the
elements.

If we tried some other solution based on using `max-width` with `margin:
auto` on the <body> element, it would result in a body having a fixed
width and a variable margin (depending on whether there's a scrollbar).
So it wouldn't be possible to set a negative margin on child elements
based on the margin of the body, because that margin would be different
depending on the existence of a scrollbar.

So, instead, we're adding a fixed margin to the body, which depends on
the viewport width and the font size of the <html> element. With this
approach, when a vertical scrollbar appears, the margin of the <body> is
still the same; what changes is its width. That means we can set a
negative margin on child elements based on the margin of the <body>. No
horizontal scrollbar will appear.

Note we're slightly duplicating the code by using two variables
(`$body-margin` and `$full-width-margin`) to do the same thing. We could
simply use `$body-margin` and then use `calc(-1 * #{$body-margin})` in
our `full-width-background` mixin. We aren't doing so because some old
versions of the Android browser and Internet Explorer can't handle this
operation. Since our whole layout is based on these properties, in this
case supporting old browsers is quite important.

For similar reasons we're using a breakpoint instead of using the
`max()` function like: `Max(0px, calc(50vw - #{$global-width / 2}))`. At
the time of writing, `max()` is only supported in about 91% of the
browsers.

With this change, we no longer need to add `row` elements to make sure
we don't exceed the maximum width; the <body> element takes care of
that.

Also note banners sometimes have a full background and sometimes they
don't, depending on which page they appear. We're adding specific rules
for them.

Finally, the code for full width borders is a bit brittle; sometimes we
want the border to cover an element, and sometimes we don't. For
example, we had to slightly change the way the border of the "tabs" in
legislation processes is rendered. Without these changes, the borders
wouldn't overlap as we intended. We also had to add a `z-index` to
navigation links so their bottom outline is visible when they're
focused. The recommendations have a border with the same color as the
background so it's painted on top of the border of the `help-header`
section.
2021-07-07 22:32:06 +02:00
Javi Martín
1214e6dd29 Load SVG icons using asset-data-url
Back in commit 925f04e3f3 from pull request #4206 we wrote about our way
to load SVG icons:

> Using this technique will result in one HTTP request per icon, which
> might affect performance

We considered using CSS with Data URIs, and wrote:

> 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.

Back when I wrote that, I didn't know Sass had a function named
`asset-data-url` which generated Data URIs automatically given a
filename. I searched for it, but somehow I only found Compass helpers
doing a similar thing.

Note we're using CSS variables to reduce the size of the generated CSS.
If we used `mask-image: asset-data-url(...)`, the generated CSS would
include the value returned by `asset-data-url` twice: once for the
`mask-image` property and once for the `-webkit-image` property.

The percentage of browsers supporting `mask-image` and not supporting
CSS variables is really small (less than 1%), so in that regard things
remain more or less the same and unsupported browsers will render the
icons using the `font-family: "Font Awesome 5 Free` property.

After these changes, the size of the generated CSS increases from 475KB
to 533KB. If we didn't use CSS variables, the generated CSS would use
591KB.

We believe this is acceptable because the SVG icons we use are very
small files (about 1-1.5KB big) and, downloaded separately, they also
amount to about 45KB, which is similar to the CSS file increase we get.
Using `asset-data-url` we download them in one request instead of having
one request per file (about 35 extra requests).
2021-07-05 13:46:11 +02:00
Javi Martín
53d49c223e Fix font icon line-height
We forgot to include this property when replacing our use of `%fa-icon`,
and it was causing the admin menu to have a blank space at the bottom.

So we're including it again to make sure nothing else breaks because of
this omition.
2021-07-02 18:33:16 +02:00
Javi Martín
d8e9dcb92d Fix content property in SVG font icons
In commit 4d49ec8ef we replaced an `@extend .fa-` clause with a
`content: fa-content()` clause.

With the `@extend` clause, the `content:` property appeared wherever the
`.fa-` selector was defined, so we later overwrote it in our `%svg-icon`
selector, which was defined later in the generated CSS.

Defining the property with `content: fa-content()`, on the other hand,
caused the `content:` property to appear wherever we used the mixin with
`@include has-fa-icon`. That meant our `%svg-icon` selector would appear
before it, and would not overwrite it.

We could modify a few things and make the code more complicate in order
to avoid that. In this case, however, it's easier to add an `!important`
flag; after all, it is indeed important that SVG icons have no content
so screen readers don't try to announce illegible characters.
2021-07-02 15:59:15 +02:00
Javi Martín
0a5dd094b3 Merge pull request #4561 from consul/ie_flex
Fix footer overlap on Internet Explorer 11
2021-07-02 13:50:06 +02:00
Javi Martín
b7f6c4c43e Fix footer on Internet Explorer 11
There are two bugs in Internet Explorer which caused our footer to be
rendered incorrectly.

First, the `flex: 1` property doesn't work so well when `flex-direction`
is set to `column`. We're replacing it with `flex-grow: 1`. No need to
set other `flex-basis` nor `flex-shrink` in this case since in this case
the default values will work just fine.

Second, it didn't handle the body height being set to `100%` so well,
and the footer was rendered after that 100% point, even if the content
still continued.

So we're using `min-height` instead, which is actually a bit more
accurate (since the body is usually taller than the document root
element). This causes a different issue since on IE the `flex-grow: 1`
property becomes useless. This will only affect IE users with very large
screens, though, and it's way better than rendering the footer
overlapping the main content, so we can live with that. The page won't
look as great as in other browser, but it will still be usable.
2021-06-30 16:43:03 +02:00
Javi Martín
4d49ec8efe Limit Font Awesome imports to reduce CSS size
We were using Font Awesome fonts and selectors to support the browsers
which don't support mask images (at the time of writing, about 5% of the
browsers). However, we were only importing the selectors in order to
extend them. This resulted in our compiled CSS including styles for
every Font Awesome icon (currenty, more than a thousand), even if we
only use a few of them.

So we're using Font Awesome variables instead of using the selectors it
provides. Since variables are only compiled in the CSS if they're
actually used, this reduces the size of our compiled CSS considerably.
In production environments, the size is reduced from 539KB to 475KB,
meaning we reduce its size in about 12%.

The downside here is we can't easily use Font Awesome variables in our
Sass mixins because we can't use interpolation in variable names (that
is, we can't use `$fa-var-#{icon}`). So we're using a map containing all
Font Awesome variables in order to access it in the mixin.

Note installations using `.fa-*` selectors will now have to add extra
`@import` clauses.
2021-06-30 16:41:39 +02:00
Javi Martín
58d123ad51 Merge pull request #4552 from consul/table_icons_with_text
Use icons with text in admin table actions
2021-06-30 16:31:18 +02:00
Javi Martín
450d954526 Don't add default margin to font awesome icons
We were removing the margin half of the time, and sometimes removing it
made us use `!important` rules.
2021-06-30 15:01:47 +02:00
Javi Martín
db55a744ec Include disabled state in base button mixin
So all disabled buttons have the same styles.
2021-06-30 14:14:43 +02:00
Javi Martín
d0f8560c33 Fix SVG icons on old browsers
We were using an `@extend` selector inside a `@supports` condition,
which didn't generate the `@supports` clause as we intended to, so
browsers with no support for mask images were still applying properties
which were meant for browsers with support for mask images.
2021-06-21 20:16:45 +02:00
decabeza
49b4061990 Show heading name and amount on single heading new form
Note we're using an extra `<span>` element but we could use a CSS grid
layout instead. We're not using it because browser compatibility is only
94.56% at the time of writing.
2021-06-11 14:43:18 +02:00
decabeza
8b2bc29b01 Update new budget investment form header 2021-06-11 14:43:17 +02:00
Alberto
03e598a53d Improve layout in budget groups form 2021-06-08 18:30:03 +02:00
Javi Martín
9d72aed37d Fix mixin for general button styles
Using the placeholder selector, we weren't overwriting the rules in the
mixin called with `@include` in some cases because in the generated CSS
the placeholder selector appeared before the code generated by the calls
to `@include`.
2021-06-08 18:27:32 +02:00
taitus
bfbbda00e3 Add new mixin to render buttons as links 2021-03-31 13:21:10 +02:00
decabeza
72a24128a6 Improve upload image and documents buttons 2021-03-24 15:48:24 +01:00
Javi Martín
4bb12c573f Fix invisible text selection on brand text
When an element had a text using the brand color and was a child of an
element with a brand background, the selection was invisible.
2021-03-24 15:48:24 +01:00
Javi Martín
f124828cd8 Fix invisible text selection on brand backgrounds
Since we were defining the selection to have the same text color and
background color as the element they were in, it resulted in the
selection being invisible.

It wasn't that noticeable because we were using this color combination
mainly in links and buttons, and selecting their text is not as common.
But we plan to use the `$brand` color on budget headers as well, and
this issue is more obvious there.

Browsers like Chrome weren't that affected because they automatically
make the selection semi-transparent and so the selected text still had a
slightly different color. In order to prevent this effect when the
selection is white, we're using a 0.99 opacity (in this case Chrome
ignores numbers higher that 0.998).
2021-03-24 15:48:24 +01:00
Javi Martín
e2d540d203 Extract code to define brand background
Setting the color to `$white` or `#fff` while setting the background to
`$brand` is a pattern we were using in many places. Since we're going to
edit it in order to fix the `::selection` behavior, we're defining the
pattern in one place.
2021-03-24 15:48:24 +01:00
Javi Martín
c08aa6ade5 Split SCSS mixins in several files
One file was OK when we only had a couple of mixins, but recently we've
been adding quite a few.

We can now avoid a SCSS Lint warning by excluding just the file with the
affected mixin.
2021-03-24 15:48:24 +01:00