Giter Site home page Giter Site logo

phuocng / frontend-tips Goto Github PK

View Code? Open in Web Editor NEW
611.0 9.0 53.0 15.57 MB

Super tiny, quick tips, tricks and best practices of front-end development

Home Page: https://phuoc.ng/collection/tips

License: MIT License

MDX 100.00%
front-end front-end-development html css javascript developer-tools tips-and-tricks best-practices eleventy

frontend-tips's Introduction

Hey, I'm Phuoc Nguyen! ๐Ÿ‘‹

I'm a software engineer from Vietnam ๐Ÿ‡ป๐Ÿ‡ณ.

In my free time, I enjoy playing football โšฝ with my co-workers and Nintendo games ๐ŸŽฎ with my kids.

I also take care of my Border Collie ๐Ÿ•. Here's a little secret: my zodiac sign is the dog.

I hope you find useful things in this digital space ๐Ÿš€.

Collections ๐Ÿš€

Check out this list of series that cover various topics in front-end development. They're incredibly useful for both learning and your day-to-day work, just like they are for me.

Best of all, they're all free and open to contributions. If you find them helpful, please consider giving them a GitHub star ๐Ÿ˜. Your support is greatly appreciated!

My top JavaScript utilities, in just One Line of Code!

Common ways to solve cross-browser compatibility problems

Awesome CSS animations: examples of stunning animations without external libraries

A collection of popular CSS layouts and patterns that you can use right away

Front-End development mastery: simple tips, tricks, and best practices

Mastering DOM manipulation with vanilla JavaScript

Understanding the difference between หหห and หหห in front-end development

In-depth series ๐Ÿงช

Are you a front-end engineer looking to take your skills to the next level? Then you're in luck! I'm excited to present to you our in-depth series covering advanced techniques and patterns in front-end development.

Our series is designed to provide you with real-life examples that you can use for your applications. We understand that learning can be a daunting task, which is why we've curated our content to be both engaging and informative. You won't find any boring material here!

In this series, we'll cover a range of topics, including advanced CSS, JavaScript, as well as popular front-end libraries. Our goal is to help you become a more well-rounded and skilled front-end developer.

It's important to follow the posts in the correct order, starting from the first one and working your way to the last. There are some important techniques introduced in between that you won't want to miss.

Enhancing user experience through text area mirroring

Your complete guide to mastering the use of "ref" in React

Master the art of drag and drop in React

Questions? ๐Ÿ™‹

Do you have any questions about front-end development that you'd like to learn more about? Shoot me a message on Twitter or assign me a new issue.

I've got a long list of upcoming posts, but I want to make sure I'm covering the topics that you're most interested in. Let's learn together! Sharing knowledge is the best way to grow in this field ๐Ÿฅท.

Contact

frontend-tips's People

Contributors

akulsr0 avatar andrew-walker91 avatar apollorisky avatar dnrm avatar dylankenneally avatar kittygiraudel avatar masteryi101 avatar phuocng avatar pixelt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frontend-tips's Issues

[Fun] Why does 'hello'.charAt(true) return e?

The charAt(index) method will try to convert the index to the number first. Since Number(true) === 1, charAt(true) will returns the character at the one index position, i.e, the second character.

Get characters of a string

[first, ...rest] = 'Hello'
first = 'H'
rest = ['e', 'l', 'l', 'o'] 

We can use it to capitalize a string

capitalize = ([first, ...rest]) => `${first.toUpperCase()}${rest.join('')}`
decapitalize = ([first, ...rest]) => `${first.toLowerCase()}${rest.join('')}`

[Good practice] Don't add custom methods to primitive objects

It is not recommended to add a custom method to primitive objects such as Array, Boolean, Number, String, etc. Since for ... in statement loops over the enumerable properties, it will include new methods which are added to the prototype.

Array.prototype.isEmpty = function() { 
    return this.length = 0;
}

const a = ['cat', 'dog', 'mouse'];
for (let i in a) {
    console.log(i);     // '0', '1', '2', 'isEmpty'
}

[Good practice] Use string literals for the enum values

If you don't set the values for enum, they will be set to incremental numbers by default.
Let's say that we have the following enum:

enum Theme {
    DEFAULT,
    LIGHT,
    DARK,
}

So Theme.DEFAULT, Theme.LIGHT and Theme.DARK will take the value of 0, 1, 2, respectively. It is more hard to debug:

console.log(Theme.DARK);    // 2

Even if we set the number for enum values, it's still possible for us to set an invalid value for a variable whose type is the enum:

enum Theme {
    DEFAULT = 0,
    LIGHT = 1,
    DARK = 2,
}

// TypeScript doesn't throw errors
const theme: Theme.DEFAULT = 3;

Due to these reasons, it's advised to use string literals for the enum values. The Theme enum should look like as follow:

enum Theme {
    DEFAULT = 'Default',
    LIGHT = 'Light',
    DARK = 'Dark',
}

console.log(Theme.DARK);                // 'Dark'
let theme: Theme.DEFAULT = 'Default';   // ERROR

[Tip] Override the behavior of instanceof

instanceof doesn't work for primitive types.
If you want to use instanceof all the time, then you can override the behavior of instanceof by implementing a static method with the key of Symbol.hasInstance.
In the following code, we create a class called PrimitiveNumber that checks if a value is a number:

class PrimitiveNumber {
    static [Symbol.hasInstance](value) {
        return typeof value === 'number';
    }
}

12345 instanceof PrimitiveNumber;           // true
'helloworld' instanceof PrimitiveNumber;    // false

Track the focused element with Chrome DevTools

Assume that you want to test the keyboard accessibility in your website.

There's a case that the pressing the Tab key jumps to a particular element which is invisible in the viewport.

Chrome DevTools provides the ability of tracking the focused element.
* Open the Console
* Click the eye icon which is located at the right of the Filter box to create a live expression
* Type `document.activeElement`
This live expression will represent the active element which has the focus currently. You can right click on the expression's
result and then choose Reveal in Elements panel to inspect the focused element.

image

Visualize elements on page with outline

The outline property is useful when you want to visualize elements on the page. In the following sample code, we iterate over all the elements and set the outline property with a random hex color:

[].forEach.call(
    document.querySelectorAll('*'),
    ele => {
        const color = `#${Math.random().toString(16).slice(2, 8).padEnd(6, '0')}`;
        ele.style.outline = `1px solid ${color}`;
    }
);

Of course, you will need an opposite command to reset the outline property:

[].forEach.call(
    document.querySelectorAll('*'),
    ele => ele.style.removeProperty('outline')
);

You can change the selector from * to whatever you want to match the set of particular elements, for example:

// Set the outline for links only
[].forEach.call(
    document.querySelectorAll('a'),
    ...
);

Indicate img elements that don't have alt attribute

Give a red outline to any img having a missing or blank alt attribute:

img:not([alt]),
img[alt=""] {
    outline: 8px solid red;
}

If you are using Visual Studio Code, you can install the webhint extension. It will automatically detect the issue and show the details when you hover on the element.

image

Avoid to use colons (:) and periods (.) in id attribute

According to the HTML specifications,
a valid id can consist of almost characters except ASCII whitespace.
Assume that we have an element representing an user's email address:
~~~ html


~~~
In order to access the element, the `getElementById()` method accepts all of three ways passing the `id`:
~~~ javascript
// They return the same element
document.getElementById('user.email')
document.getElementById('user\.email')
document.getElementById('user\\.email')
~~~
But these methods return different results if you are using jQuery library:
~~~ javascript
// Function // Returned element
$('#user.email') //

$('#user\.email') //

$('#user\\.email') //

~~~
As you see, the first two methods will find an element with `id` of `user` and has `email` class.
In order to get the correct element, we have to escape the `id` using double backslashes (`\`).
It also happens if we use the same value in CSS:
~~~ css
#user.email {
...
}
~~~
All the styles declared within `#user.email { ... }` has effect on the element with `id` of `user` and has the `email` class.
The styles aren't applied to element with `id` of `user.email`. To define the styles for our element, we have to escape the selector.
But this time, it requires a single backslash only:
~~~ css
#user\.email {
...
}
~~~
Avoid using the special characters in the `id` and `class` attributes will help us get rid of the confusion and errors above.
If it's not possible to get rid of colons and periods (for example, the `id` attribute is generated by the server side),
then you can use the single backslash as above, or use the attribute selector.
Note that it has a lower specificity than the `id` selector:
~~~ css
[id="user.email"] {
...
}
~~~

[Good practice] Always pass the radix to parseInt

The parseInt method takes two parameters:

parseInt(value, radix);

The second parameter specifies the current numeral system. In the case it's not specified, then it will be set automatically based on the value.
If the value starts with 0x or 0X, then the radix is 16 (hexadecimal)
In other cases, the radix is 10 (decimal).
In the older versions of JavaScript, if the string starts with 0 then the radix is set as 8 (octal).

parseInt('0xF');        // 15
parseInt('0XF');        // 15
parseInt('0xF', 16);    // 15

parseInt('0xF', 10);    // 0

Since the method could be implemented differently in different versions of JavaScript and browsers, it's recommended to pass the radix number.

Wrap function body in parentheses

If the inline arrow function consists of the <, <=, > or >= operator, it is advised to wrap the function body in parentheses.
Looking at the two versions below, it is easy for the first variant to cause a misleading.

// Bad
const compareToZero = a => a <= 0 ? 0 : a;

// Good
const compareToZero = a => (a <= 0 ? 0 : a);

Merge different arrays

You can use ES6 spread operator to merge different arrays into one:

const a = [1, 2, 3];
const b = [4, 5, 6];
const c = [7, 8, 9];

const final = [...a, ...b, ...c];   // [1, 2, 3, 4, 5, 6, 7, 8, 9]

The spread operator is handy if we use the push method as well:

const a = [1, 2, 3];
const b = [4, 5, 6];

a.push(...b);
a;              // [1, 2, 3, 4, 5, 6]

Use the template literal syntax in ES6

You can use the template literal syntax in ES6 to get rid of escaping quote. For example:

// Instead of
const message = 'It\'s a message';

// We can do this which is more convenient
const message = `It's a message`;

[Good practice] Trim the spaces before parsing the number

Both Number() and parseInt accept the spaces in input. But be aware that you could get different result when passing a value with spaces as following:

parseInt('   5   ');    // 5
parseInt('12 345');     // 12, not 12345

To avoid the similar situations, you should remove all spaces before parsing:

parseInt(value.replace(/s+/g, ''), 10);

[Tip] wbr element

A browser might break a long text at unexpected places. For example, the specific path (`/this/is/.../folder`) in the following text
is placed at the second line:
~~~
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
| Copy file to the folder: |
| /this/is/a/very/long/path/to/the/destination/folder |
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
~~~
To prevent this behavior, HTML5 provides the `` element. It stands for Word Break Opportunity, and is used to specify the
positions that a line break would be created.
Getting back to the example above. If we use `` elements right before each path separator (`/`) as follow:
~~~ html
Copy your file to the folder:
/this
/is
/a
...
/destination
/folder
~~~
The browser will break the paths in between the directory names:
~~~
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
| Copy your file to the folder: /this/is/a/very/long |
| /path/to/the/destination/folder |
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
~~~
Note that `` element is not supported in IE 11 and earlier versions.

[Tip] Convert string to number

Instead of using the Number() constructor to convert a string to number, you can use the + operator:

+'010';     // 10
+'2e1';     // 20
+'0xF';     // 15

Use an underscore to name unused argument

You can use an underscore to name the argument which is not used in an arrow function. It makes the code more readable.

// No arguments
const noop = _ => {};

const range = (min, max) => Array(max - min + 1).fill(0).map((_, i) => min + i);

Remove a property from an object with spread operator

We can use the ES6 spread operator to remove a property from an object:

const { name, ...rest } = { name: 'Foo', age: 20 };

console.log(name);      // 'Foo'
console.log(rest);      // { age: '20' }

It's also possible to remove a dynamic property:

const property = 'name';
const { [property]: value, ...rest } = { name: 'Foo', age: 20 };

console.log(value);     // 'Foo'
console.log(rest);      // { age: '20' }

A note on preventing default handler with jQuery

If you're using jQuery to manage the events, then you're able to use return false within the event handler:

$(element).on('click', function(e) {
    return false;
});

Before returning the value of false, the handler would do something else. The problem is that if there's any runtime error occurring in the handler, we will not reach the return false statement at the end.

In that case, the default behavior will be taken:

$(element).on('click', function(e) {
    // Do something here, but if there's error at runtime
    // ...
    return false;
});

We can avoid this situation by using the preventDefault method before performing any custom handler:

$(element).on('click', function(e) {
    e.preventDefault();

    // Do something here
    // The default behavior is prevented regardless errors at runtime
    // ...
});

Prefix class name with `js-`

Have you ever seen a class name starting with js-?
If the answer is not, then you can visit Github and see the source of generated HTML. There are bunch of elements whose class are prefixed with js- such as:

<meta class="js-ga-set" name="userId" content="...">
<meta class="js-ga-set" name="dimension1" content="...">

They are often used to manage the list of elements that we don't want to set id for (dynamic elements, for example). In these cases, we use the document.querySelectorAll('js-xxx') method to retrieve the elements list.

In the other words, the js- classes don't define the styles, but for managing the elements in JavaScript instead. That's why they are prefixed with js-. Follow this naming convention is helpful if you're working in a team. Other engineers will be aware of the class name, and don't remove them when refactoring the page.

[Tip] Put + at the beginning of function

Usually, we can invoke a function by using the form of Immediately Invoked Function Expression (IIFE).

(function(a, b) {
    return a + b;
})(4, 2);

// 6

Do you know that we get the same result if we omit the parentheses and put + at the beginning as follow:

+function(a, b) {
    return a + b;
}(4, 2)

// 6

It works because putting + at the beginning of function declaration will turn it to an expression, and passing the parameters with () at the end will invoke the expression.
It is rare to see that code in development, but it is used in the minifications to save the file size.
In addition to +, you can use other operators such as -, !, ~ and void in the similar way to invoke a function:

-function() { ... }();
!function() { ... }();
~function() { ... }();
void function() { ... }();

Note that the return value could be different from the original function, for example:

!function() { return false; }();     // true

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.