Whether you are a developer or designer, you’re used to working with HTML, CSS and JS to code the look and feel of websites and apps. You usually code using the same techniques until you find out that the little box on the header won’t align as you need although you tried 76 different combinations, or for some mysterious reason the element can’t be focused. That’s when you open a new tab and search for something like “align to right + flexbox”, and look for any solution from StackOverflow or MDN. This is what happened to me and how I found out about these tips and I would like to share with you.
Tip 1: Some elements can’t be flex containers…
I was working on a form that has lots of fields structured like this:
And I needed them to appear next to each other in a row. So I applied display: flex to the container element which was a <fieldset>.
The Problem
After adding the property to the <fieldset> and reloading the page I saw that the form looked exactly the same as before, I was surprised and thought I had made a mistake. So I started testing and changing properties in different places, but it still didn’t work. I reached out to my teammates for ideas but nothing seemed to work, so I googled the issue and found the following link 👇
https://stackoverflow.com/questions/28078681/why-cant-fieldset-be-flex-containers
The Solution
One of the answers in that link points to Bugzilla and it explains that browsers render <fieldset> and <button> in a particular way, here is the full text:
<button> is not implementable (by browsers) in pure CSS, so they are a bit of a black box, from the perspective of CSS. This means that they don’t necessarily react in the same way that e.g. a <div> would.
This isn’t specific to flexbox – e.g. we don’t render scrollbars if you put “overflow:scroll” on a button, and we don’t render it as a table if you put “display:table” on it. Stepping back even further, this isn’t specific to <button>. Consider <fieldset> and <table> which also have special rendering behavior:
In these cases, Chrome agrees with us and disregards the “flex” display mode. (as revealed by the fact that “abc” and “def” end up being stacked vertically). The fact that they happen to do what you’re expecting on <button style=”display:flex”> is likely just due to an implementation detail. In Gecko’s button implementation, we hardcode <button> (and <fieldset>, and <table>) as having a specific frame class (and hence, a specific way of laying out the child elements), regardless of the “display” property. If you want to reliably have the children reliably arranged in a particular layout mode in a cross-browser fashion, your best bet is to use a wrapper-div inside the button, just as you would need to inside of a <fieldset>. So the solution is to wrap the content with a <div> and apply flexbox to it. I find this behaviour a little odd since <fieldset> it’s the natural container for form elements from a semantic perspective. Another alternative would be to avoid using flexbox entirely and float the inner elements, but you lose all the flexbox utilities.
Tip 2: Disable easily various form elements
While working on the same development as the case before, I was tweaking a “Edit Button” that would allow a user to make changes to the content of various form elements. The original state of these elements would be ‘disabled’ and after clicking on the <button> they will become editable for the user.
The Problem
I began disabling them one by one, but had some issues with a couple of elements because it is a Rails application and some elements where a bit complicated to modify their HTML. On top of that we were using select2 and were having issues trying to manipulate it through jQuery.
The Solution
I searched for an easy way to modify them through jQuery and end up discovering that <fieldset> has a really useful “trick”: if you add the disabled attribute to it, all it’s child form elements will be disabled. Here is the full text from MDN:
If this Boolean attribute is set, all form controls that are descendants of the <fieldset>, are disabled, meaning they are not editable and won’t be submitted along with the <form>. They won’t receive any browsing events, like mouse clicks or focus-related events. By default browsers display such controls grayed out. Note that form elements inside the <legend> element won’t be disabled.
I ended up using this attribute to disable all the form elements at once and switching it’s value through jQuery: $(“fieldset”).prop(‘disabled’, false);
Bonus track:
This is one is a personal finding that I’m sure has been there for a while, but I had just found out about it just recently. If you use the jQuery function trigger() you can easily reset all form values to its previous state: $(“#myForm”).trigger(“reset”); Hope you find this tips useful! Thanks for reading and if you have any comments reach us @Leniolabs_ on Twitter. 👋👋