I am very happy to help beginners and advanced web developers. I've been thinking about what beginners struggle with most often and what might help them move forward. I certainly don't aim to cover all the problems in this article, but I have focused on the following 7 issues that I see as essential in my experience and also occur a lot.
Many beginners like a variety of libraries, some of the most well-known being Bootstrap or Bluma. These popular libraries are used everywhere, with no hesitation about whether they fit the project. One such example would be using the entire Bootstrap library just for the sake of Grid System (rows and columns).
Another example would be using the jQuery library just for selecting elements in html
, when this can be done easily in pure JS
.
Solution: It is necessary to think at the beginning of the project what libraries I want to use and whether I will use all of them, or import only parts of them. For example, Bootstrap is already written in Sass
since version 4 and allows you to import only those components that you use.
It happens to newcomers that when they create a new interactive element they forget to have enough area for interaction, whether clicking or tapping with a finger. A prime example is the production of "a chevron", which is made of two lines turned opposite each other by a few degrees. This arrow can be made using only html
and css
. When interaction is then added directly to the arrow itself, the click area is very small and the visitor may have trouble hitting the element.
Solution: It is necessary to think about how the user will work with the site, in case of small clickable areas it is good to wrap these areas in a wrapper element (for example a button), which is set some internal indentation padding
and set the interaction to this element.
This problem happens when web developer doesn't have the hover (hover is the state of the element after mouseover) designed by the graphic designer and has to improvise. The developer creates element by element, each of the elements can be created for different lengths of time, and so sometimes a newbie can lose the whole picture of the result of the work, or some feeling of the user using the web page. It often happens that developer assigns elements a hover that he likes, but in the overall picture it can be very disjointed and inconsistent. A prime example might be two buttons, while one of them changes the background color, the other responds with scale.
Solution: First of all, it's good if the developer doesn't have to improvise so much and has everything prepared by the graphic designer and not only :hover
states but also for example :focus
or :active
states of buttons/inputs if they are important for the web application. But if the frontend developer has freedom in this direction, it is good to test the result a few times during the work to see how it works together and whether everything reacts consistently, then prepare a preview of the project and consult interactions with team members.
The <img>
image tag is one of the first things one encounters if one decides to learn HTML
. The image tag contains attributes such as the path to the image src=""
, a description of the image when hovered over title=""
, an alternate description if the image cannot be displayed alt=""
, width width=""
, height height=""
and a few others...
But only one of the image attributes is required by the specification, would you know which one?
It is an alt
attribute, an alternative description, a piece of text that is displayed as an alternative if the image cannot be displayed in the browser (e.g. wrong path, unsupported format, etc...).
Solution: Describe images in alt
attributes. If the image is only decorative, for example to complete the web design, I recommend to use alt anyway and leave it empty alt=""
.
Although this may seem trivial from a more experienced developer's perspective, novice developers may have trouble perceiving context by referencing the directory structure. First, let's see what an absolute reference looks like and what a relative reference looks like:
<a href="/index.html">Absolute link starts with a slash</a>
<a href="index.html">A relative reference does not begin with a slash</a>
Absolute link - links directly from the root of the domain, wherever it is used on the site, it will link to the same place. For example, if I use the link on example.com/contact/
<a href="/products.html">Products</a>
It will link to https://example.com/products.html, it simply replaces everything after the domain with my link (/products.html)
Relative link - refers relatively to the place where I am. So if I modify the previous example slightly and use a link on example.com/contact/ */
<a href="products.html">Products (bad link)</a>
It will link to https://example.com/contact/products.html which I didn't want, the products are located at https://example.com/products.html. So relative links work by taking the path (folder) where I'm located - in our case /contact/ */ and putting our relative path at the end of the path, that is products.html and I saw the result above.
We need to be aware of this behavior and write the links correctly. A bitter discovery often occurs when we write links relatively and then put the content in some sub-folder where the relative links stop working because the context has changed, all the resources have a folder above.
The solution may be to write links absolutely.
The problem of unnamed constants, can be found in almost every programming language, even in CSS. We can recognize it by encountering a number that has no obvious reason why it is the way it is. They degrade our code readability, are hard to maintain, and can lead to future application errors.
An example of such code can be the following condition in javascript:
function isSmallScreen() {
if (window.innerWidth > 640) {
// What does the number 640 mean? Where did it come from?
return true
} else {
return false
}
}
In the example we see the number 640 used, which is written hard, it is not based on any constant or configuration. Code written this way is usually a sign of small time saving at the expense of very poor clarity.
Solution: How should it be done? We should use constants, ideally defined in some configuration file or otherwise reasonably defined.
// File config.js
export {
Screen: {
// …
sm: 640,
// …
}
// File script.js
function isSmallScreen() {
if (window.innerWidth > Screen.sm) {
return true
} else {
return false
}
}
Similarly, we shouldn't use magic numbers in CSS**. Let's demonstrate this with the following example:
.cta-box {
width: 100%;
background: #424242;
margin-top: 273px;
margin-bottom: 266px;
padding: 12px;
}
Colors should ideally be defined when we start coding the project and then use colors from the palette, so the color must go into a variable. The margin-top
and margin-bottom
are problematic, because they are probably somehow generalized numbers and it would be good to at least round them off, ideally to define some spacing variables for each block of the project.
Let's see what the corrected code could look like to make it more readable and systematic:
:root {
/* Colour definition */
--bg-secondary: #424242;
/* ... */
/* Section indentation */
--section-spacing-lg: 17rem; /* 272 pixels */
/* Global indentation */
--gutter: 12px;
}
/* ... */
.cta-box {
width: 100%;
background:var(--bg-secondary);
margin-top: var(--section-spacing-lg);
margin-bottom: var(--section-spacing-lg);
padding:var(--gutter);
}
As you can notice, we have defined variables for color, section indentation and global indentation. All of these values are now defined in one place and we can easily change them.
The code written this way is descriptive, easy to understand and maintain.
There is a !important
rule in css that gives more priority to the css styles to which it is applied. However, beginners tend to solve some of their problems this way. Overusing the !important
rule then results in very poor orientation, and furthermore the !important
rule can only be overridden by the !important
rule, so when we need to overload/override such rules the !important
rules keep replicating.
Let's illustrate this with an example:
<section>
<a href="#" class="button">Button</a>
</section>
/* We have defined the background colour of the button */
section .button {
background: red;
}
/* ... */
/* Somewhere down the line we want to change the color of the button */
/* But we can't because the rule above is more specific */
/* So we use !important */
.button {
background: blue !important;
}
Let's consider the situation - the developer first defined the button and then in CSS wanted to change the button in the section. However, the top entry has higher element specificity and thus has higher priority, so the developer decided to solve the problem with !important
, to say that the bottom rule has higher priority. This way, however, he set himself up for a future problem, because now the background color of the button will not change without using another !important.
Note: This is a model situation, in reality you will want to change the color of the button in its initial definition and ideally through a configured variable, the example serves as a representative of the issue.
We need to either reduce the specificity of the rewritten rule or increase the specificity of the newly created rule, for example like this:
/* We have defined the background colour of the button */
/* in the same way as in the first example */
section .button {
background: red;
}
/* ... */
/* But here we increase the specificity */
/* so we don't have to use !important */
section .button {
background: blue;
}
The advice for this issue is avoid the `!important' rule, but there are rare cases where this is unavoidable. (For example, in some cases when working with third-party libraries that we can't touch)
I'm sure there are many other things to watch out for, the ones I mentioned in the article I consider basic and every frontend user should know them. It's great that you've read this far and I'll be very happy if you share this article among your frontmen** either in your company or friends, maybe some of the above will be interesting for them too :)