Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Building Real-Life Applications With Functional Elements of HTML 5.2

DZone's Guide to

Building Real-Life Applications With Functional Elements of HTML 5.2

We look at some of the new elements that have been added to HTML 5.2 that allows web developers to integrate better features into their sites and applications.

· Web Dev Zone
Free Resource

Tips, tricks and tools for creating your own data-driven app, brought to you in partnership with Qlik.

What do you do when you need a widget-like functionality? At present, there is a whole generation of developers who, as a rule, are googling for ready-made jQuery plugins. Can't we do better than that? With the advances of web-components, we are expected to compose UIs from these building blocks. They are many. One can find one for almost any task. They are highly customizable. One can reuse the functionality, but with your own original representation. They are isolated. One doesn't need to worry about the collisions in the compound system. But in reality, the APIs required by true web-components still have poor support in user-agents. One has to load an emulator library like Polymer. When it comes to component-based frameworks, one can painlessly import a component or rather go with a set like Material UI. But what would you say about standardized, library/framework-agnostic solution with not dependencies? Interesting that with HTML 5.1 and HTML 5.2 we get a number of new functional elements, solving classic developer tasks such as dialog, expandables, date pickers, and others. At the time of writing this article, the support for spec among browsers isn't that good, but the elements can be polyfilled where it lacks. Let's see what's available and how we can use it.

Expandables With Summary/Details

A pair of elements, details and summary, were introduced in HTML 5.1 and are now widely supported. They implement a disclosure widget that can be adopted for collapse, dropdown menus, tree navigation, and other tasks. By default, any child elements of details except summary are hidden. As one clicks summary, the properties of open details change to true and the hidden content comes into view. To put it in practice, we made the following HTML:

<details>
  <summary>Lorem ipsum dolor sit amet</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sollicitudin, justo eu consequat rutrum, leo tellus euismod quam, et consectetur nibh nunc vitae risus. Vestibulum auctor nunc dolor, et hendrerit elit aliquet at. Nulla urna odio, elementum eget ligula sit amet, finibus ullamcorper nibh. Mauris a magna purus. Curabitur sit amet massa vitae odio cursus convallis. Morbi vel dapibus orci. Integer sed arcu varius, sollicitudin est quis, rhoncus justo. Etiam feugiat purus nibh, vel consequat velit posuere eget. Fusce ullamcorper fringilla sapien eu sodales. Cras ipsum odio, vulputate a massa id, efficitur tempor ante.  </p>
</details>

<details>
  <summary>Lorem ipsum dolor sit amet</summary>
  <p>Lorem ipsum dolor sit amet...  </p>
</details>

As we hit the summary of the first block, we get the content of the inner paragraph (Lorem ipsum dolor sit amet...)

It already looks fine, but still, we want to customize the look and feel. I suggest adding reset styles the following lines:

summary {
  display: block;
  cursor: pointer;
  outline: 0;
}

summary::-webkit-details-marker {
  display: none;
}

By applying the  ::-webkit-details-marker  pseudo selector we remove the default marker symbol. That works for Chrome and Safari. As for Firefox, the rule display is blocked; assigning it in summary selector does the trick. Actually, the browser doesn't render the symbol if the box model set different from display: list-item. But keeping these styles we encourage the dev-team never to go with the default marker.

Now, we are going to play with styles a bit to make it look nicer:

.expandable--default {
  padding: 0.8rem 0;
  border-bottom: 1px solid gray;
}
.expandable--default[open] > summary::before {
  content: "▽";
}
.expandable--default summary {
  cursor: pointer;
  position: relative;
  outline: 0;
  font-size: 1.8rem;
  line-height: 2rem;
  padding-left: 2rem;
}
.expandable--default summary::before {
  content: "▷";
  position: absolute;
  left: 0;
  top: 0;
  display: inline-block;
}

We declare expandable-- the default implementation of the expandable abstract class in PCSS. This is the class we will be using to refer to an expandable of the default type. We do not have a class for summary and make the selectors tag-dependent. In this case, it won't be a problem as the functionality itself is strictly bound to these elements. You just cannot switch to other tags without breaking the widget behavior. So we extend summary with a pseudo-element representing the marker in the default state (summary::before with right arrow). When the detail's content is visible (.expandable--default[open] > summary::before) we change the content of the pseudo-element with the down arrow. Now we can apply the styles to the HTML:

<details class="expandable expandable--default">
  <summary>Lorem ipsum dolor sit amet</summary>
  <p>Lorem ipsum dolor sit amet...  </p>
</details>

<details class="expandable expandable--default">
  <summary>Lorem ipsum dolor sit amet</summary>
  <p>Lorem ipsum dolor sit amet...  </p>
</details>

Now it looks notably better:

Why not give it some animation?

.expandable--default[open] > summary::before {
  transform: rotate(90deg);
}

.expandable--default summary::before {
  //...
  transition: transform 200ms;
  will-change: transform;
}

We made the marker-arrow rotate from a right-facing position to backward-facing one.

See the Pen Expandable made with summary/details elements of HTML5.1 by Dmitry Sheiko on CodePen.

What about some other use case? Here is a CodePen with tree navigation based on details/summary:

Polyfill

In case any of your users are still using IE you can polyfill the elements with this

Modal Dialogs

Modal dialogs are used by almost every application. For a simple dialog, we can go without any JavaScript at all. For advanced ones, we apply plain JavaScript or a UI library or even an environment integration API. Since version 5.1, HTML has been extended with a new element dialog. It has teh method showModal that shows the contents of the elements in a modal window. If you supply a URL to the method, it will load the referred external document. One can call the method close to hide the modal. With the attribute open one can make the modal visible by default:

<dialog open>
  <p>Lorem ipsum dolor sit amet</p>
  <button  id="close">close</button>
</dialog>

<script>
    const dialog = document.querySelector( "dialog" ),
          closeBtn = document.querySelector( "#close" );

    closeBtn.addEventListener( "click", e => dialog.close(), false );
</script>

What is more, if you have a form with attribute method set to dialog within a dialog, the form submission can be done by pressing a submit button that would close the dialog. Let's look at an example to get a better grip on it:

.btn {
  cursor: pointer;
}
.input {
  width: 100%;
  font-size: 1.6rem;
  padding: 0.4rem 0.8rem;
  margin: 0.8rem 0;
}

.dialog-default::backdrop { /* native */
  background: hsla(0,0%,6%,.97);
}
.dialog-default + .backdrop { /* polyfill */
  background: hsla(0,0%,6%,.97);
}
.dialog {
 // abstract class
}
.dialog-default {
  max-width: 400px;
  margin: 0 auto;
  padding: 6rem 4rem;
  border-radius: .4rem;
  background: #222729;
  background-image: radial-gradient(circle at 50% 0,#2e3437,#1d2223);
  box-shadow: 0 0 .1rem rgba(0,0,0,.3);
  color: white;
  text-align: center;
  border: 0;
  position: relative;
}

.dialog-default .btn-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  border: 0;
  background: transparent;
  color: white;
  font-size: 1.8rem;
  outline: 0;
}

Here we set our styles for the dialog. We use the ::backdrop pseudo-selector to access the dialog underlay (`+ .backdrop` the same for the Google polyfill). Within dialog, we place a close button aligned to the right-top corner. Now we can make the HTML:

<button id="show" class="btn"  title="Show dialog">Show dialog</button>
<dialog class="dialog dialog-default">
  <button  id="close" class="btn btn-close" title="Close dialog">X</button>
  <h2>Never miss our newsletters!</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sollicitudin, justo eu consequat rutrum, leo tellus euismod quam, et consectetur nibh nunc vitae risus. Vestibulum auctor nunc dolor, et hendrerit elit aliquet at.</p>
  <form method="dialog">

    <input class="input" placeholder="Enter Email (not really)" />

    <button type="submit">Confirm</button>
  </form>
</dialog>

Here we have a "Show dialog" button and the dialog with close button, header, paragraph, and a form. The form comprises the submit button. Next goes the JavaScript:

const dialog = document.querySelector( "dialog" ),
      showBtn = document.querySelector( "#show" ),
      closeBtn = document.querySelector( "#close" );

showBtn.addEventListener( "click", e => dialog.showModal(), false );
closeBtn.addEventListener( "click", e => dialog.close(), false );

We subscribe a handler for the click event on the show button, which calls showModal. Similarly, we call a close method in the subscribed handler in order to click on the close button.

See the Pen Modal window with dialog element of HTML 5.1 by Dmitry Sheiko on CodePen.

Polyfill

The element is currently supported by Chrome and Opera, and is under consideration by Microsoft Edge. So you may need a polyfill. Lucky for us, Google made one. What you need to do is simply include its styles and JavaScript into the document.

<link rel="stylesheet" type="text/css" href="./node_modules/dialog-polyfill/dialog-polyfill.css" />
<script src="./node_modules/dialog-polyfill/dialog-polyfill.js"></script>

Now, register dialog elements of the DOM to the polyfill:

<script>
    Array.from( document.querySelectorAll( "dialog" ) )
      .map( el => dialogPolyfill.registerDialog( el ) );
</script>

Responsive Images

RWD is nothing new. We write a lot of media queries in CSS nowadays. And you probably know that when it comes to images, HTML now allows us to set queries at the element level. With the srcset attribute of the img element, and the picture/source elements, we can fully control how the user agent will render an image depending on a case.

We can make the img element load different (e.g. by size) images depending DPI (Retina aspect):

<img srcset="img/low-res.jpg 1x, img/high-res.jpg 2x, img/ultra-high-res.jpg 3x" alt="…">

We can load different (e.g. by size) images depending on the current viewport size:

<img
  srcset="img/medium.jpg 375w,
          img/large.jpg 480w,
          img/xl.jpg 768w"
  alt="…">

We can even control the displayed image size according to its viewport:

<img
  sizes="(min-width: 40em) 80vw, 100vw"
  srcset="img/medium.jpg 375w,
          img/large.jpg 480w,
          img/xl.jpg 768w"
  alt="…">

With the picture element, it's even easier to set the rules. Inside it, we declare img with the default source and then provide sources for every case. The element, picture, supports the attribute srcset and has one extra media to set media queries:

<picture>
  <source srcset="img/xl.jpg" media="(min-width: 1000px)">
  <source srcset="img/large.jpg" media="(min-width: 800px)">
  <img srcset="img/medium.jpg" alt="…">
</picture>

So the element represented by picture will load the image from a source with the best matching media query. If none are found, it will simply render the image from the default one. That's handy as we can, in the same way, make the image fallback to the default source if it fails to load an alternative format, e.g. WebP:

<picture>
  <source type="image/webp" srcset="images/butterfly.webp">
  <img src="images/butterfly.jpg" alt="a butterfly">
</picture>

Polyfill

I'v been using Picturefill polyfill for quite some time and am quite happy with it.

Input Types: Month, Week, Ddatetime, and Datetime-Local

Datepicker is one of the most used widgets. Since HTML 5.1, we've had access to new input types to select the week, month, and local date time:

<input type="week" />
<input type="month" />
<input type="datetime-local" />


Since HTML 5.2, <input type="datetime-local" /> is meant to select a specific global date, while <input type="datetime-local" /> represents a local date and time, with no time-zone offset information.

At the moment, it's supported only in Chrome. I could not find a decent polyfill for week and month types. And the one I found for datetime has ugly dependencies to jQuery, jQuery UI, and Modernizr. It is still worth mentioning, though:

<html lang="en">
  <head>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/themes/base/jquery.ui.all.css" />
    <link rel="stylesheet" href="datetime-local-polyfill.css" />
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
    <script type="text/javascript" src="datetime-local-polyfill.js"></script>
  </head>
  <body>

<form>
  <input type="datetime-local" name="myDateTimeLocal0" value="2017-09-14T12:00" min="2016-01-01T12:00" max="2018-01-01T12:00" />
</form>

</body>
</html>


Menu and Menuitem

HTML 5.1 introduced the menu and menuitem elements to help you build a content menu:

<a contextmenu="popup-menu">
  Right click here for the context menu.
</a>

<menu type="context" id="popup-menu">

  <menuitem type="command" label="Command" onclick="alert('Run action')">Action</menuitem>
  <menuitem type="radio" name="group1" checked="true">Radio button 1</menuitem>
  <menuitem type="radio" name="group1">Radio button 2</menuitem>
  <menuitem type="checkbox" disabled>Disabled menu item</menuitem>
</menu>

It's still supported in Firefox:


However, in HTML 5.2, this feature is considered at risk. So I would not recommend you to use it yet.

Explore data-driven apps with less coding and query writing, brought to you in partnership with Qlik.

Topics:
web dev ,html ,web application development

Published at DZone with permission of Dmitry Sheiko, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}