Frontend Sprint: 100 Quick Tips on HTML, CSS and JavaScript

100 useful tricks, best practices and free tips on HTML, CSS and JavaScript for new and continuing frontend developers.

Semantics and accessibility

1. The most popular HTML tags are div and span. These are ordinary containers with no hidden meaning.

2. Previously, they were used to design everything and everywhere, but the HTML5 standard brought many more suitable tags.

3. You now have about 110 tags to choose from. The probability that you will not be able to find one that is suitable is very small.


4. When choosing a text selection method, think carefully about the meaning you put into it.

5. For example, the b and strong tags look the same (bold text), but the first one does not carry any semantic meaning, and the second one emphasizes the importance of the highlighted fragment.

6. The same situation with i and em. These are italic fonts, but em (emphasis) places a logical emphasis on the text, but i does not.

7. For headings, use h1 — h6.

8. If the selected text is not of semantic importance, it is better to use for it a regular span. For example, you can select icons in this way.


9. When creating a new structural component, focus on its semantics and select the appropriate elements.

10. For headers and footers, header and footer tags are intended. On one page there can be a lot of them, for example, the footer of the site with contact details and the footer of articles with information about the author.

11. But the main in document should be only one – it contains unique information that is different from page to page. Usually the markup looks like this:


12. For the semantic content design, use the article and section tags.

13. In a nutshell, an article is self-contained content like an article, note, or comment that can be easily moved somewhere else, for example, to share on social networks.

14. And section is a separate thematic section of the document, as a rule, with its own title.

15. Inside the article you can place the address block with contact information.

16. The main navigation page is made in the form of a tag nav.

17. Another useful tag is noscript. Its role is to provide feedback for users with disabled JavaScript.

18. Be sure to review all existing HTML elements in the documentation.

19. Many semantic elements have their own default styles, which may differ from your design. Do not be afraid to change them in your CSS.

20. Consider the hierarchy and relationship of the elements. Each tag has allowed content and valid parent containers. You can find out which ones in the MDN documentation.

21. For example, earlier inside a tag it was impossible to place block elements and headers. In order to preserve the validity of the document, it was necessary to make a link to the child element and absolutely position it over the parent.

22. In the current standard, the a tag can itself serve as a container for other elements besides links, and this is very convenient.


23. To improve the semantics and even greater accessibility of the project, you can use a set of ARIA attributes.

24. For example, for modal windows, the role attribute with the value dialog is used.

<div role="dialog">

25. Mark the main header and footer as follows:

<header role="banner">
<footer role="contentinfo">

26. If an element does not have a visible label, it can be denoted using the aria-label attribute.

<svg aria-label="Facebook">

27. It is also very simple to hide decorative elements, for example, icons, from the screen reader:

<svg aria-hidden="true">

28. ARIA attributes can be combined with CSS pseudo-elements to create wonderful accessible components like this slider.

29. Using ready-made libraries of components, resist the temptation to remove all semantic attributes. Accessibility of the application should be for the developer in the first place.

30. WAI-ARIA takes on even greater significance if the HTML markup does not use semantic elements. In this case, only attributes can make the page accessible.

31. Accessibility is gradually becoming the recognized standard of frontend development. In many countries, it is fixed at the level of legislation. Therefore, do not stay away from progress, learn the best practices of creating accessible sites.


32. Many HTML elements have default styles. For example, display: block at div or display: inline at span. There is no need to explicitly specify such properties in your CSS code.

33. Use CSS variables to store base values. This avoids the use of “magic numbers” and makes your code clearer and easier to maintain.

$space-xxs : .4rem;
$space-xs : .8rem;
$space-sm : 1.6 rem;
$space : 2.4 rem;
$space-md : 3.2 rem;
$space-lg : 4.8 rem;

34. It is especially useful to put into variable values of z-index, with which you can otherwise get confused very well:

$zindex-default : 1;
$zindex-footer : 10;
$zindex-header : 30;
$zindex-overlay : 40;


35. CSS combines remarkably well with various HTML meaning attributes, which makes it possible to distinguish semantically meaningful elements.

36. For example, you can stylize elements with different default text language (the lang attribute can be used with any tag, not just with html).

.description[lang="en"] { color: red };
.description[lang="ru-ru"] { color: blue };

37. Or elements not available for interaction:

[disabled] { cursor: not-allowed; }

38. Do not forget that a class is also an attribute, which means that you can use the following selector:


39. CSS allows you to select classes (or any other attributes) whose value contains some combination of characters:


40. Or even one of several combinations, separated by spaces:

span[class~="icon arrow-right"]

41. You can select elements whose attribute value starts with a specific word, for example, icons:


42. Or secure links:


43. Using ARIA attributes and CSS attribute selectors, you can create great things, for example, here are the available tooltips:


44. Pseudo-classes and pseudo-elements of CSS offer tremendous possibilities for styling a document.

45. For example, you can hide empty elements:

div:empty { display: none; }

46. Very often there is the task of discarding some styles from the last element in the group, for example, frames or indents. Previously, this element had to add a special class:

<li class="last"></li>

  li { border: solid black 1px; }
  .last { border: 0; }

47. Pseudo-classes greatly simplify this task:

:last-child {  border: 0; }

48. And there is a better solution!

li:not(:last-child} { border: solid black 1px; }

49. Some interesting and useful examples of using the selector :not you can find in internet.

50. Pseudo-classes solve more nontrivial problems. They can, for example, gracefully select elements that are the last descendant of the parent, but not the only one:


51. The pseudo-elements :before and :after allow you to make as many as three of one HTML element: one source parent block and two of its pseudo-shots. This opens up a lot of possibilities for page styling.

52. Do not forget that these pseudo-elements do not work without the content property, even if it is empty.

:before { content: "Over?"; }
:after { content: "Not yet"; }
:after { content: ''; }

53. Please note that any contents :before and :after cannot have a semantic meaning and is not available for screen readers. Use them exclusively for decorative purposes.

54. By combining pseudo-elements and relative positioning, you can adjust the aspect ratio of the block, which is especially useful when working with images and media objects.

Selector combinations

55. In CSS, you can select elements based on their environment, for example, by selectors of the previous neighbor: + .btn { margin-left: 20px; }

56. Or parent: ~ .btn { margin-top: 20px; }

57. Feel free to combine selectors of different types:

input[type="checkbox"]:checked ~ p { color: red; }

58. You can create completely crazy combinations. For example, this one will select all headers with the class .title (except for the headers of the second level) that lie inside the .main block, which is in the markup after the .header block, which does not have the class .active. Dizzy!

.header:not(.active) + .main .title:not(h2)

59. Using the properties of radio buttons and checkboxes, you can make interactive elements that will appear and disappear when you click:

p { display: none; }
input[type="checkbox"]:checked ~ p { display: block; }

CSS organization

60. Carefully analyze your code for anything that can be reused, and make it components.

61. When developing your own extensible component system, follow the proven best practices of frontend development.

62. Avoid common mistakes in working with cascading style sheets.

63. Use common class naming conventions, such as BEM, to keep your CSS clean and tidy.

64. But remember that BEM is not a panacea, and in some cases it is better to do without it.

65. Use CSS Modules and CSS-in-JS to insulate the styles of different modules. These approaches allow you to no longer suffer with the names of classes. Instead of .header__title, you can write with a clear conscience just .title.

66. If you are not familiar with modular concepts, take a look here.

67. However, there are also drawbacks, the main one being the complication of the development process. So think carefully before introducing CSS modules into your project.

68. CSS-in-JS will be especially useful if you use component JavaScript tools like React or Vue.

69. If you work in a team, be sure to discuss with your colleagues (designers, frontend and backend developers) how to organize the CSS code and component base. This will make it easier for you to select and implement the appropriate tools for your project.

CSS optimization

70. Different selectors operate at different speeds. Consider this by optimizing your code.

71. The fastest – selectors by identifier (#header). Further – in descending order of effectiveness:

  • classes – .header
  • tags – header
  • neighboring elements – nav + header
  • immediate parent – main > h1
  • simple nesting – main header
  • universal selector – *
  • attributes – [type = "text"]
  • pseudo selectors – .header: before, .header: after

72. Avoid large nesting of elements:

body header ul li

73. It is better to mark the desired item using the class than to increase the number of search levels.

74. This article will help you understand the CSS optimization facts and myths.


75. With the advent of Flexbox and CSS Grid, you can stop using float to create layouts.

76. CSS Grid to some extent can replace ready-made grid systems, for example, Bootstrap.

77. No need to choose between CSS Grid and Flexbox, just use them together depending on the tasks.

78. Flexbox is ideally suited for organizing internal one-dimensional marking of containers, for example, aligning the logo on the left, and the menu on the right in the header of the site.

.header {
  align-items: center;
  display: flex;
  justify-content: space-between;
  height: 60px;

79. CSS Grid is a great choice for building complex multidimensional meshes.

Relative Units

80. Assess the advantage of relative units of measure and begin to actively use them in your frontend-development. For example, rem is based on the font size of the root element. If the html property is set to font-size: 10px, then 1rem will be equal to 10px, and 2rem20px.

81. By default, the size of the root element (html) is most often equal to 16px, that is, 1rem = 16px.

82. rem makes it easy to scale all sizes. To make changes, simply increase or decrease the font-size value of the root element.

media (max-width: 600px) {
  html {
    font-size: 10px;

83. Experiment with the viewport units and the calc function to set up a perfectly responsive font size:

html {
  font-size: calc(#{$minimum-size}px + (#{$maximum-size} — #{$minimum-size}) * ((100vw — #{$minimum-viewport}px) / (#{$maximum-viewport} — #{$minimum-viewport})));

Media queries

84. Adapting your website for different screens and devices, use the mobile first approach popular in frontend-development: start layout with a small resolution and gradually increase it.

85. Within a single media query, you can combine all the styles associated with it.

86. A lot of useful information about various media queries can be found in the documentation.


87. Check whether there is a value in the variable, you can use double negation:

const xis = 'x'
const hasXis = !!xis
console.log(hasXis) // true

88. To avoid mistakes, use a strict equality test with regard to the type:

console.log(1 === '1') // false

89. On the other hand, lax validation makes JavaScript programming more flexible:

console.log(1 == '1') // true

90. Variables declared with const are not so constant. You cannot change the variable itself, but its properties are easy:

const animals = ['cat', 'dog']
console.log(animals) // ['cat', 'dog', 'mouse']

91. To make a const variable completely immutable, use the Object.freeze method:

const d2k = Object.freeze(['javascript', 'ninja', 'react])
d2k.push('jquery') // Uncaught TypeError: Cannot add property 3, object is not extensible

92. Use patterned strings for convenient concatenation:

const f = (s = '❤️') => `I ${s} frontend`
// I ❤️ frontend

93. Spread-operator makes it easy to combine arrays:

const skills1 = [ 'css', 'html' ]
const skills2 = [ 'js', 'ts' ]
const newSkills = [ …skills1, …skills2, 'ux' ]
console.log(newSkills) // [ 'css', 'html', 'js', 'ts', 'ux' ]

94. And objects:

const obj1 = { a: 1, x: 'Hello' }
const obj2 = { b: 2, y: 'world' }
const mergedObj = { ...obj1, obj2 }
console.log(mergedObj) // { a: 1, b: 2, x: 'Hello', y: 'world' }

95. And turn a string into an array:

const s = 'HTML'
const c = [ …s ]
console.log(c) // [ 'H', 'T', 'M', 'L' ]

96. With the help of destructuring assignment, you can easily write object properties into variables:

const person = { name: 'Felipe', lastName: 'Fialho', age: 28 }
const { name, age } = person
console.log(name, age) // Felipe 28

97. The remaining properties are not lost anywhere, they can be turned into a new object using the rest-operator

const person = { name: 'Felipe', lastName: 'Fialho', age: 28 }
const { name, …restOfPerson } = person
console.log(restOfPerson) // { lastName: "Fialho", age: 28 }


Use the selected resources of the frontend developer:

98. MDN Web Docs – the best web documentation.

99. CanIUse – reliable verification of support for various features by browsers.

100. W3C standards – first-hand frontend standards.

Working with the HTML5 canvas in web projects

The HTML5 canvas is an interesting feature of this increasingly widespread web standard. With it you can draw dynamic content to any web page and add features like drawing tools, animation and graphic effects, and interactivity to your websites.

This article gives you an overview of the HTML5 canvas, along with a handful of examples to get you started. The animated banner sample in Figure 1 shows an application of the key concepts that I cover.

Figure 1. An animated banner built with EaselJS and the HTML5 canvas

Before you get started, download and install Adobe Dreamweaver CS6 from Adobe Creative Cloud if you haven’t already done so. Then download the supplied files to use as a reference.

What is the HTML5 canvas?

Figure 2. The coordinate space of the canvas starting at 0, 0 in the upper left corner

The HTML5 canvas is an invisible 2D grid that you can use to draw graphics and animations (see Figure 2). Any number of canvases can be added to an HTML page using the <canvas> tag.

The canvas tag itself is very simple. It defines an invisible resolution-dependent coordinate space at a given width and height. The coordinates run along two axes (x and y) starting at 0, 0 in the upper left corner.

The canvas has no drawing abilities of its own; you use JavaScript to reference a context within the canvas. Once you reference the canvas’ context, you can work with its commands to draw shapes, text, images, and video to the canvas. In most cases you’ll reference the context 2D object, although there are experimental implementations available for a context 3D object that is outside the scope of this article.

The following shows an HTML page that defines a canvas along with the JavaScript that retrieves the context and draws a rectangle:

<!DOCTYPE html>
<title>Canvas sample</title>
<canvas id="myCanvas" width="420" height="320"></canvas>
<script>var canvas = document.getElementById("myCanvas"); 
var context = canvas.getContext('2d'); 
context.fillStyle = "rgb(0,0,0)"; 
context.fillRect(10, 10, 400, 300); 

The fillStyle line sets the color to black. The fillRect line renders the rectangle at a size of 400×300 pixels placed at 10 x, 10 y in the coordinate space.

What can you do with the HTML5 canvas?

The canvas is all about drawing. You can use the context 2D application programming interface (API) to draw shapes, create image and video effects using drawImage, and transform and composite graphics for special effects. And that’s just the foundation. By combining the drawing abilities of the canvas with the power of JavaScript, you can create simple or complex animations, graphs and charts, and even highly interactive content like games and simulations.

The following is a quick summary of canvas features:

  • Draw shapes on the fly: lines, paths, and arcs; Bézier curves and quadratic curves; rectangles
  • Apply custom strokes and fills to your shapes: stroke color, stroke width, cap, join, miter limit; fill color, linear and radial gradients fills, pattern fills
  • Draw canvas text: font (CSS format), text align, and text baseline
  • Create special effects: images, video, and other canvases using drawImage
  • Add shadows to graphics: shadow color, offset, and blur
  • Composite overlapping images: composite modes and clipping paths
  • Transform graphics: translate (move), rotate, scale, and skew

Check out the Mozilla Developers Network Canvas Tutorial for a detailed review of HTML5 canvas features.

How does the HTML5 canvas relate to web standards?

The canvas tag is an element in the HTML document object model (DOM) and therefore can be treated like any other element. JavaScript can interact with it directly and CSS transformations can be applied to it for additional effects. And perhaps most importantly, you can view graphic effects and animations created on the canvas on any device supporting the HTML5 canvas standard. That means your content can be seen across all screens without the need for a plug-in.

The canvas also has the benefit of being supported by public JavaScript libraries (EaselJSKineticsJS, and Cake to name a few) that simplify many common production tasks. In the samples that follow, I focus on working with EaselJS since it was designed to make the canvas workflow similar to working in ActionScript 3.

The canvas tag is supported by Microsoft Internet Explorer 9, Mozilla Firefox, Opera, Google Chrome, and Apple Safari, iOS Safari, Android, and BlackBerry. Opera Mini partially supports the canvas.

Note: For the latest compatibility information, always check the CanIUse website.

Working with the HTML5 canvas in Dreamweaver

These examples can help you get started with the canvas and EaselJS. After you use Dreamweaver to create your web page, insert a canvas tag and add any amount of JavaScript to create simple or complex content.

Follow these steps to set up a canvas and initialize it with EaselJS:

  1. Open Dreamweaver and choose File > New to create a new file. In the New Document dialog box, select the HTML5 option from the DocType menu on the right (see Figure 3) and click the Create button.
    Figure 3. Creating an HTML5 document in Dreamweaver (click to enlarge)
  2. Switch to the Code view and add the link to the EaselJS library in the head tag. Your code should look like this:
    <!doctype html>
    <meta charset="utf-8">
    <title>HTML5 Canvas Sample</title>
    <script src=""></script>
  3. In the body tag, add a canvas tag with the following attributes:
    • id: myCanvas
    • width: 500
    • height: 45
    <canvas id="myCanvas" width="500" height="450"></canvas>
  4. Below the canvas tag, add a script tag with the following JavaScript:
    <canvas id="myCanvas" width="500" height="450"></canvas>
    // 1. Create a stage to draw on using the canvas 
    var stage = new createjs.Stage("myCanvas"); 
    // 2. Create a circle shape 
    var circle = new createjs.Shape();"blue").drawCircle(250,50,50); 
    // 3. Add the circle to the stage 
  5. Save the file and preview it in a browser. You should see a blue circle in the upper center of the canvas (see Figure 4). Check out example1.html in the supplied files to examine the working sample file too. While working in Dreamweaver, you can click the Live button to see the canvas rendered in the Design view.
    Figure 4. The circle rendered in the canvas coordinate space

Notice that in the first bit of code, you added the script block containing the JavaScript after the canvas tag. Placing your code at the bottom, just before the closing </body> tag, ensures that the canvas is loaded in the DOM before you try to manipulate it. It’s a good practice to wait for all the elements on the page to load before running your JavaScript routines, so placing your code here is an easy way to make sure you don’t run into any timing problems.

The JavaScript code you added is simple. It creates a stage object to draw on and then creates a new shape named “circle.” The code references the graphics property of the circle, sets the color fill to blue, and creates a circle that’s 50 pixels wide at 250 x, 50 y in the stage’s coordinate space. The last two lines add the circle to the stage and call the stage’s update method so you can view the shape.

Circles aren’t all that you could draw. You can draw different types of shapes by replacing the drawCircle method with the drawEllipsedrawPolyStardrawRect, or drawRoundedRectmethods. See the EaselJS Graphics Class documentation for more information.

Adding interactivity to the HTML5 canvas object

Follow these steps to make the circle interactive using an event:

  1. Return to the Code view in Dreamweaver.
  2. Add the following code in the script tag after the line that defines the circle:"blue").drawCircle(250,50,50); 
    circle.addEventListener("click", handleCircleClick); 
    // Respond to clicks on the circle function 
    handleCircleClick(e){ alert("You clicked on the circle..."); } 
  3. Save the file and preview it in a browser. Click the circle to see the alert dialog box pop up (click the circle in Figure 5 to see the result). Check out example2.html in the supplied files to examine the working sample file.
    Figure 5. Circle made interactive using an event

Interactivity is driven by events. All shapes support mouse and touch events, including hover, press, and release. Working with events requires two steps: creating a function that will be called when the event is triggered and then using the addEventListener method to assign the event handler function to watch for that specific event on a particular element.

In this case, the handleCircleClick function responds to click events on the circle. Note that you can enable greater support for touch events using the EaselJS Touch object as seen in the last line in the sample above. See the EaselJS MouseEvent and Touch Class documentation for more information.

Animating the HTML5 canvas object

Follow these steps to animate the circle:

  1. Return to the Code view in Dreamweaver.
  2. Add the following code as the last lines in the script tag:
    // 4. Animate the circle using the Ticker 
    createjs.Ticker.addEventListener("tick", handleInterval); 
    // Respond to the tick event function 
    handleInterval(){ circle.y += 5; if( circle.y >= 450 ){ circle.y = -50; } 
    stage.update(); }
  3. Save the file and preview it in a browser. Notice that the circle animates downward until it leaves the screen, then reappears at the top of the screen to continue the loop. Even though the circle is animated, it still responds to the click event (click the animated circle in Figure 6 to see the result). Also check out example3.html in the supplied files to examine the working sample file.

    Figure 6. The animated circle (top); animation shown paused during a click on the circle (bottom).

EaselJS provides an interval for animation called the Ticker. To use the Ticker, you add an event handler function that listens to the tick event, write your code inside the event handler, and call the stage’s update function to update the view. See the EaselJS Ticker documentation for more information.

Where to go from here

These examples cover the key concepts of setting up a canvas and EaselJS, drawing shapes, adding events to add interactivity, and using the Ticker to animate graphics on an interval. Take a look at the supplied files to deconstruct the working examples. And be sure to check out the animated banner sample (Figure 1 at the beginning of the article) that I included with the sample files as a more advanced scenario for you to review. The banner example takes these concepts a few steps further including adding and removing circles and animating with TweenJS.

Although working with the canvas is a really fun part of HTML5, be aware that you may encounter some pitfalls:

    • Include the standards mode document type declaration <!DOCTYPE html> at the top of your HTML page for support in Internet Explorer 9.
    • While the HTML5 standard does not require it, always include a closing canvas tag (</canvas>) for support across all browsers including Firefox and Internet Explorer.
    • Older browsers, most notably Internet Explorer 8, do not support the canvas tag. You can place an img tag, or other content, inside the nested canvas tags to provide fallback content for browsers without canvas support.
    • Performance during complex animations may become an issue. Consider using multiple canvases for complex compositions to ensure that you update as little of the drawing surface as possible.
    • You may run into timing issues while working with images and video along with the canvas. Make sure that your media is preloaded before you attempt to create effects with it.
    • The canvas is supported across most mobile platforms, but feature support is limited on iOS. Specifically, the drawImage API is not supported on iPad or iPhone.