Forms are inevitable on a web journey. Here are some commented examples to understand each component
Table of contents:
Let's take this search field form (from How to transfigure wireframes into HTML by Lara Aigmüller) as an example.
form tag -> to open an area in the document where the user can provide information
action attribute -> indicates an URL where the form data should be sent. If omitted, it defaults to current page.
role attribute -> for accessibility purposes (value is search to identify search functionnality)
label tag -> to help associate the text for an input element with the input element itself (clicking on the text will select the corresponding button; helpful for assistive technologies)
for attribute -> association method with an input id where values are the same. Another method could be:
<label>
<input type="search" id="search-input" placeholder="Search…" name="q" />
Search articles
</label>
input tag -> allows several ways to collect data
type attribute -> many possible values, see below
id attribute -> the most important attribute in the universe. Used to identify specific HTML elements. Each id attribute's value must be unique from all other id values for the entire page.
placeholder attribute -> used to give people a hint about what kind of information to enter into an input but this is actually not a best-practice for accessibility (users can confuse the placeholder text with an actual input value).
name attribute -> value to represent the data being submitted, mandatory to be processed on the server-side. Helps grouping radio buttons (selecting one deselects the other - see survey form example).
value attribute -> initial value (for submit and button types: text that will display) - for instance ->
<form method="post" action="./contact">
<input id="name" type="text" name="name" value="" placeholder="Name" required>
<input id="email" type="email" name="email" value="" placeholder="Email" required>
<textarea id="message" rows="6" name="message" placeholder="Message" required></textarea>
<div data-sitekey="..."></div>
<button id="submit" name="submit" type="submit">Send email</button>
</form>
Let's take this contact form (from Bludit plugin) as an example.
form tag method attribute -> specifies how to send form-data
input tag required attribute -> data is mandatory to allow submission
div tag data-sitekey attribute -> I'll do some research on this topic later on. For now let's just say it's used to prevent spaming using CAPTCHA.
Question of the day: is there a "better" solution between button and input tag when type is submit? After some research I believe the answer is: no, functionnaly, it's identical. However, button elements are much easier to style and inner HTML content can be added. Note however that the first input element with a type of submit is automatically set to submit its nearest parent form element.
This is an example from FreeCodeCamp Responsive Web Design course:
<form action="https://freecatphotoapp.com/submit-cat-photo" target="_blank">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label>
<input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor
</label>
<label>
<input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor
</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked>
<label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy">
<label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic">
<label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
form tag, target attribute -> defines where to display the response after submitting the form. Default value is _self (ie current window)
fieldset tag -> used to group related inputs and labels together
legend tag -> acts as a caption for the content in the fieldset element
input tag
value atribute -> even if optionnal, it's best practice to include it with any checkboxes or radio buttons on the page. Otherwise, the form data would include name-value=on, which is not useful.
checked attribute -> force selection by default
button tag type attribute submit value -> note this is the default if the attribute is not specified for buttons associated with a <form>, or if the attribute is an empty or invalid value. button tag should always have a type attribute because different browsers may use different default types.
What type of input do you need?
min="2000-01-02"
)<input type="file" accept="image/*,.pdf">
<input type="button" value="Let's play!">
If type attribute is submit or image and if you want to proceed with a different action from the rest of the form with this input, use form+regularFormAttributeName to override form attributes for this specific button (ie formaction, formenctype, formmethod, formtarget, formnovalidate
<form action="/action_page.php">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
<input type="submit" formaction="/action_page2.php" formenctype="multipart/form-data" formmethod="post" formtarget="_blank" formnovalidate="formnovalidate" value="Submit as...">
</form>
Allow text edition on several lines. Use if you dare:
<textarea name="textarea" rows="10" cols="50">Please write here.</textarea>
Use for dropdown lists. Example from W3Schools:
<label for="cars">Choose a car:</label>
<select id="cars" name="cars" size="3" multiple>
<optgroup label="Swedish Cars">
<option value="volvo" selected>Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
selected attribute defines a pre-selected option.
size attribute defines the number of visible values
multiple attribute allow the selection of several options
Group options with optgroup element. Useful when lists are longs.
Specifies a list of pre-defined options for an input tag, showed depending on the user's input. Example from W3Schools:
<form action="/action_page.php">
<input list="browsers">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
</form>
Represents the result of a calculation. Example from W3Schools:
<form action="/action_page.php" oninput="x.value=parseInt(a.value)+parseInt(b.value)">
0 <input type="range" id="a" name="a" value="50"> 100 +
<input type="number" id="b" name="b" value="50"> =
<output name="x" for="a b"></output>
<br/>
<input type="submit">
</form>
For form and input tags :valid and :invalid pseudo-classes
The end of year came so quickly I did not find the time to write a short recap. So here it is!
2023 expectations: friends & family being well; my wedding being happy
2023 expectations: none in particular
2023 expectations: publish one book
2023 expectations: continue, finish projects, earn certifications
2023 expectations: see how it goes with 1 night per month in Paris
Here could be a CSS boilerplate for any project:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
border: 1px solid orange;
font-family: sans-serif;
}
Using * we are targeting all elements.
margin and padding properties set to 0 are for cancelling default browser margin and padding (see this previous article). Remember:
margin: 0 auto;
box-sizing property is new to me. It sets how the total width and height of an element is calculated (this explanation and others as well are from MDN Web docs, completed by W3Schools): it can be either unrestricted or restricted to the parent's container.
.box { width: 350px; border: 10px solid black; }
renders a box that is 350 (box width) + 10 (right border ) +10 (left border) = 370px wide.
This means that you may have elements sharing a same width and height but if they have different paddings and/or borders, their total size will be different.
.box { width: 350px; border: 10px solid black; }renders a box that is 350px wide. This makes the world a little easier to live in, dosen't it?
border property to debug positioning drama - you should of course delete or comment (just in case haha) this line for going-live and chose a good contrasting color . I confess, when it comes to add some CSS I often feel not knowing why it's not behaving as expected. So just like many fellows, I'm adding borders to elements and yes, it helps a lot. To avoid repeating it, I put it inside the all selector (*).
font-family property to sans-serif just to make a first step out of raw HTML, it's totally subjective.
I recently discovered about Font Awesome and Unicode emojis. I thought: this a great way to have images without actually hosting them! As I'd like my projects to require a minimum of ressources that may suit my needs. But wait. I'd like these projects to also be as accessible as possible. How can you achieve that when this HTML element (for font awesome) and character (for Unicode emoji) are not HTML images (<img>) and therefore cannot have an alt attribute containing the relevant alternative text?
Let's dig this out!
Well, for Font Awesome, the answer is on their website, they have a dedicated section! It is beautifully sumed up on Upyouray11.com so I'll just try to sum up the sum up, so to have a reference somewhere on my own blog.
Hide it from assistive technologies with aria-hidden attribute, value true.
<i aria-hidden="true" class="fas fa-car"></i>
Hide the icon itself but indicate the link purpose (menu, home, cart...) with aria-label attribute on the action HTML element
<a href="/" aria-label="Home">
<i aria-hidden="true" class="fas fa-home"></i>
</a>
Hide the alternative text in a span element via CSS so it's dedicated to assistive technologies
HTML would be
<i aria-hidden="true" class="fas fa-plant" title="Vegetarian"></i> <span class="screen-reader-only">Vegetarian</span>
Note that we are adding a title attribute to help sighted mouse users
CSS would be
.screen-reader-only { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
Hide it from assistive technologies with aria-hidden attribute, value true in an additionnal span element:
<span aria-hidden="true">📖</span>
Nest the emoji into a span element and give it a role attribute, value img and the alternative text in aria-label attribute's value:
<span role="img" aria-label="open book">📖</span>
Now, let's apply this in this blog's contents!
I still can't remember wich property apply to which axis so let's build a cheat-set! Again, many thanks to FreeCodeCamp courses for the detailed explanations.
For starters, in our HTML document we'll need a container as well as children boxes. For instance:
<body>
<main>
<section>
<h2>section 1</h2>
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section>
<h2>section 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</section>
<section>
<h2>section 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</section>
</main>
</body>
Here the container is main and it's children boxes are section. Let's tell the browser how to position elements on the page:
main {
display: flex;
justify-content: space-evenly;
}
Explanations & other possibilites
First thing first, we have to declare we're using the flex model. Use display property value flex for that.
Main axis
The main axis is declared with flex-direction property:
The justify-content property determines how the items inside a flex container are positioned along the main axis. It can take this values (find all on mdn web docs):
The flex-wrap property determines how the flex items behave when the flex container is too small. Otherwise, items will shrink if needed. It can take this values:
The gap CSS property sets the gaps (gutters) between rows and columns. It is a shorthand for row-gap and column-gap. It can take one or two lenght value(s) (such as 1em for instance) or percentage value(s).
Cross axis
The align-items property controls alignment of all items on the cross axis. It can take this values:
Here's a list of screen sizes by device:
(Thanks FreeCodeCamp!)
In the CSS document, place the @media rule after the first no-rule is applied. For instance:
main {
width: 55%;
max-width: 400px;
}
@media screen and (max-width: 500px) {
main {
width: 85%;
}
}