Assignment 4
The fourth and final assignment in this course consists of three exercises where you will be creating web components.
Submit your completed assignment before the deadline. Submission instructions can be found on the main assignment page.
Learning outcomes
After this lab assignment, you should have gained knowledge about the following:
- How to create Web Components
- How to dispatch synthetic events
- How ARIA attributes are used
Assignment points
Exercises 1 and 2 have optional tasks.
- 1 point: Complete all required tasks.
- 2 points: Complete all required tasks and one optional task.
General requirements
Create a directory the assignment and a subdirectory for each exercise.
Exercise 1 - Your first Web Component
Required task
Create a Web Component (<info-message> that displays an informational message using slots for the title and message. In this exercise you will also be using the open source icon library Fork Awesome.
There are prepared files for this assignment: a4e1.zip
These zip-file contains
a4e1.html, the web page that uses two<info-message>web componentsa4e1.css, the CSS file fora4e1.htmlandinfomessage.js, an empty file where you are supposed to define the web component
Visuals
Below is an image of how your web component should look like. It uses an icon from the Fork Awesome library (see below for information on how to use Fork Awesome icons).
HTML (a4e1.html)
Keep the original contents of the a4e1.html file. You only need to add the link to the Fork Awesome css (see below). The HTML uses the <info-message> web component that you need to define.
HTML Template for the web component
Use the following HTML as template for the web component, i.e. use is when you define your template in infomessage.js. Refer to the lecture slides for an outline for defining a custom element/web component.
<div class="infobox">
<div class="heading">
<div class="icon center">
<i class="fa fa-info-circle fa-lg fa-inverse fa-fw" aria-hidden="true"></i>
</div>
<div class="title">
<p><slot name="title">TITLE GOES HERE</slot></p>
</div>
</div>
<div class="message">
<slot name="message">MESSAGE</slot>
</div>
</div>
Using Fork Awesome
You can either link to the Fork Awesome stylesheet via their CDN (Content Delivery Network), or download the library and link to the local file (fork-awesome.min.css).
If you use the CDN version use the code below. You will need to link to if both from your HTML Template and the main page (a4e1.html) for the icons to work.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
If you download and use a local version, you must keep the directory structure intact (the css file refers to the directory ../fonts for the fonts).
The template HTML code above uses the fa-info-circle icon. You can read more about how to use Fork Awesome icons on their web site: Fork Awesome Examples.
Exercise 2 - Toggle button
Required task
Create a <toggle-button> Web Component that toggles on/off when clicked. The <toggle-button> should also fire an input event when its value changes. The current value should be accessible via its .value property.
There are prepared files for this assignment: a4e2.zip
The zip-file contains
a4e2.html, the page that uses four<toggle-button>elementsa4e2.css, the CSS fora4e2.htmla4e2.js, javascript that listens forinputevents from the<toggle-button>elements and displays their valuestoggle-button.js, an empty file where you are supposed to define the<toggle-button>web component
Visuals
a4e1.html should look something like this when you have created the CSS for the toggle widget.
Below is an image of what it should look like after you have toggled widget 2 and 4.
ARIA attributes
The two relevant ARIA attributes for the <toggle-button> are the role and the aria-pressed attributes. The clickable web component HTML should have role="button" as it functions as a two state button. The attribute aria-pressed should be set as "false" if the button is in its “off”-state, and set to “true” when the button is in its “on”-state.
HTML (a4e2.html)
In a4e2.html you can see the toggle-button elements which are the custom elements you have to implement, e.g.
<toggle-button label="Toggle 1"></toggle-button>
HTML Template for the web component
Use the following as the template for your web component:
<div class="wrapper">
<p>label text</p>
<div class="toggle" aria-pressed="false"></div>
</div>
The label text should be replaced by the text in the label attribute of the custom element when the custom element is created. The value of the ARIA attribute aria-pressed should reflect the state of the <toggle-button> (see Behavior below).
Behavior
Implement the ability for toggling the color of the widget between white and green. When the widget is white, its value should be 0. I.e. console.log((toggleButton.value) should print out 0. The value when showing green should be 1.
This means your class should have an instance variable with the name value that stores the value of the button (0 or 1).
Also change the value of the attribute aria-pressed accordingly (more info: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role).
Fire input events
The web component should also fire input events when the user clicks it that bubble. See the lecture slides, and the following two pages for more info:
- https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events
- https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
Optional task 1
Note: If you complete Optional task 1 you need to submit both the required and optional task. Make a copy of a4e2.html and name it a4e2-optional.html and copy toggle-button.js to toggle-button-optional.js and use that for the optional task.
For Optional task 1 allow the user to specify two images that are used to show the state of the <toggle-button>:
<toggle-button label="Toggle 1" pressed="green.png" not-pressed="red.png"></toggle-button>
Change the use of the custom elements in a4e2-optional.html to reflect the code above.
If you implement the optional task, red.png should be shown initially. When the user clicks on the widget, green.png should be shown. Clicking again switches the images.
You can use these image URL:s if you do not want to use your own images:
Exercise 3 - Accordion
Required task
Create an <accortion-component> web component that contains headings with expandable content.
There are prepared files for this assignment: a4e3.zip
The zip-file contains
a4e3.html, web page that uses the<accordion-component>web componenta4e3.css, the CSS fora4e3.htmlaccordion.js, an empty file where you are supposed to define the<accordion-component>web component
Visuals
a4e2.html should look something like this when you have created the CSS for the accordion widget.
Tip: You can use the CSS below to add different triangles when the accordian is opened and closed.
.accordion button::before {
content: "▶︎ ";
}
.accordion button[aria-expanded="true"]::before {
content: "▼︎ ";
}
ARIA attributes
- Role The element containing the content of an accordion panel has
role="region" - State When a button’s content
divis visible, the value of thebutton’saria-expandedattribute should betrue. When its contentdivis not visible, the button’saria-expandedvalue should be set tofalse. - Relationship You are not required to apply these attributes for the assignment.
aria-controls: this attribute is set on a button and and its value is theidof the contentdivit controls the visibility ofaria-labelledby: this attribute is set on a contentdivand its value is theidof thebuttonit belongs to.
- Misc An element with the
hiddenattribute will not be visible in the browser, nor will it be read by any assistive technologies. Because of this, thehiddenattribute is often used when creating accessible UI components rather than just settingdisplay: none. Just settingdisplay: nonewill hide it from seeing users, but it may still be read by some assistive tools.
HTML (a4e3.html)
The idea here, is to let the user write only what is necessary from a content author’s perspective. Here is the HTML that is the user is required to write.
<accordion-component>
<h2>Accordion 1 title</h2>
<div><p>Content for Accordion 1<p></div>
<h2>Accordion 2 title</h2>
<div><p>Content for Accordion 2<p></div>
<h2>Accordion 3 title</h2>
<div><p>Content for Accordion 3<p></div>
</accordion-component>
HTML Template for the web component
Use the following HTML as the template for your web component:
<div class="accordion">
<ul>
</ul>
</div>
You will need to create elements using JavaScript to put the content of the web component into the appropriate elements in the shadow DOM. This is what the final shadow DOM should look like for the <accordion-component> example above.
<div class="accordion">
<ul>
<li>
<button aria-expanded="false">Accordion 1 title</button>
<div role="region" hidden=""><p>Content for Accordion 1</p></div>
</li>
<li>
<button aria-expanded="false">Accordion 2 title</button>
<div role="region" hidden=""><p>Content for Accordion 2</p></div>
</li>
<li>
<button aria-expanded="false">Accordion 3 title</button>
<div role="region" hidden=""><p>Content for Accordion 3</p></div>
</li>
</ul>
</div>
Important: Some methods and properties, e.g. element.children and document.getElementsByClassName() return a live HTMLCollection. “Live” means that any changes to the DOM will be immediately reflected in the HTMLCollection. If you intend to move any elements in the HTMLCollection to a new place in the DOM, do NOT do this from inside of a e.g. a for-loop where you are using indexes. Instead, copy the elements to an array and loop through the array: let myElements = Array.from(myHTMLCollection) and loop over the array.
If you try to loop over a live HTMLCollection of e.g. the children of a node and move any of the children to another place in the DOM, the HTMLCollection will shrink and you will have a smaller HTMLCollection than you initially had.
Note: You cannot change the tagName of a DOM node, e.g. you cannot change a h2 to a button. Instead you have to create a new button element, then copy the .innerHTML and optionally destroy the h2 element (use element.remove()).
Behavior
- If an unexpanded accordion title is clicked, its content is revealed (remove the
hiddenattribute) and the value of the title’saria-expandedattribute is set to"true". - If a expanded accordion title is clicked, its content is hidden (add the
hiddenattribute) and the value of the title’saria-expandedattribute is set to"false". - There are no dependencies between accordions, i.e. any number of accordions may be opened or closed at the same time.
Optional Task 2
- Animate the accordions opening and closing using anime.js
Page contact: Johan Falkenjack
Last update: 2022-12-02





