├── css ├── syntax.md ├── selectors.md └── web-fonts.md ├── images └── css │ ├── selectors-focus.png │ ├── selectors-focus-links.png │ ├── selectors-focus-initial.png │ ├── selectors-focus-tooltip.png │ ├── selectors-focus-within.png │ ├── logical-properties-values.png │ ├── logical-properties-values-detailed.png │ ├── logical-properties-values-flipped.png │ └── logical-properties-values-flipped-detailed.png ├── index.md ├── LICENSE ├── readme.md └── javascript ├── hoisting.md └── classes.md /css/syntax.md: -------------------------------------------------------------------------------- 1 | # [TODO] CSS Syntax 2 | 3 | -------------------------------------------------------------------------------- /images/css/selectors-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/selectors-focus.png -------------------------------------------------------------------------------- /images/css/selectors-focus-links.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/selectors-focus-links.png -------------------------------------------------------------------------------- /images/css/selectors-focus-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/selectors-focus-initial.png -------------------------------------------------------------------------------- /images/css/selectors-focus-tooltip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/selectors-focus-tooltip.png -------------------------------------------------------------------------------- /images/css/selectors-focus-within.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/selectors-focus-within.png -------------------------------------------------------------------------------- /images/css/logical-properties-values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/logical-properties-values.png -------------------------------------------------------------------------------- /images/css/logical-properties-values-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/logical-properties-values-detailed.png -------------------------------------------------------------------------------- /images/css/logical-properties-values-flipped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/logical-properties-values-flipped.png -------------------------------------------------------------------------------- /images/css/logical-properties-values-flipped-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadalfy/frontend-notes/HEAD/images/css/logical-properties-values-flipped-detailed.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | # Available content 2 | 3 | 1. HTML 4 | 2. CSS 5 | 1. [[WIP] Selectors](./css/selectors.md) 6 | 2. [[WIP] Web fonts](./css/web-fonts.md) 7 | 3. JavaScript 8 | 1. [Hoisting](./javascript/hoisting.md) 9 | 2. [Classes](./javascript/classes.md) 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Frontend notes 2 | 3 | Frontend notes started as an attempt to create internal notes used by our team at [robusta](http://www.robustastudio.com) to facilitate and improve onboarding of the new frontend developers. After a while I thought I would better share it for the benefits of everyone. 4 | 5 | There are tons of useful resources out there covering everything you might want to know. Videos, blogs, magazines, tutorials, discussions on platforms so I am not attempting to reinvent the wheel. My goal is to provide a story telling experience from a prespective of someone who has been working in this field for more than 15 years. 6 | 7 | This is a work in progress and I don't think it will ever finish. I will continue to add topics, examples and references for as long as I can. If there is any topic that might be interesting to you please open a GitHub issue and I will add it to the list. You're welcomed to contribute, point to mistakes or request changes to anything you want and I will be glad to discuss. 8 | 9 | Thank you. 10 | 11 | ## Content 12 | 13 | The index of the available contents can be found [here](./index.md). 14 | 15 | ## Flow 16 | 17 | Right now I have many drafts with titles and todos that I am willing to continue working on. I will push the parts that I feel they are mature enough to be shared. As I mentioned earlier anyone can suggest a topic and I will put it on my list as long as it falls in the same domain of my work. 18 | 19 | Right now I am far away from having a clear structure of this work in my head. I will put the articles in a high-level categories and organize it later as the content grow. 20 | 21 | This work is licensed under [the Unlicense license](./LICENSE) -------------------------------------------------------------------------------- /javascript/hoisting.md: -------------------------------------------------------------------------------- 1 | # Hoisting 2 | 3 | ## What is hoisting 4 | 5 | Hoisting mean that **variable** and **function declarations** are physically moved to the top of our code, but this is not in fact what happens. Instead, the variable and function declarations are put into memory during the *compile* phase, but stay exactly where we typed them. 6 | 7 | Example: 8 | 9 | ```javascript 10 | console.log(hoistedFunction('10')); 11 | 12 | function hoistedFunction(x) { 13 | return x; 14 | } 15 | 16 | // The result will be "10" 17 | ``` 18 | 19 | ## Only declarations are hoisted 20 | 21 | JavaScript only hoists declarations, not initializations. If a variable is declared and initialized after using it, the value will be undefined. For example: 22 | 23 | ```javascript 24 | console.log(variable); // Returns undefined 25 | 26 | var variable; 27 | 28 | variable = 10; 29 | ``` 30 | 31 | If we tried the prervious example using `let` or `const` it will through a `ReferenceError` but that doesn't mean that variables declared with them are not hoisted. The main difference between them is in the **initialization**. Variables declared using `var` and function exprerssions are initalized with `undefined` at the top of the scope. `let` and `const` however stay **uninitialised**. This means that a `ReferenceError` exception is thrown if we try to access it. It will only get initialised when the `let`/`const` statement is evaluated [¹][1]. Same applies for **class declarations**. 32 | 33 | ```javascript 34 | var p = new Rectangle(); // ReferenceError 35 | 36 | class Rectangle {} 37 | ``` 38 | 39 | [1]: https://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations "ES6 Let and Const Declarations" 40 | 41 | -------------------------------------------------------------------------------- /javascript/classes.md: -------------------------------------------------------------------------------- 1 | # Classes in ES6 2 | 3 | JavaScript is a prototype-based language, and every object in JavaScript has a hidden internal property called `[[Prototype]]` that can be used to extend object properties and methods. 4 | 5 | Until recently, developers used constructor functions to mimic an object-oriented design pattern in JavaScript. The language specification ECMAScript 2015 introduced classes to the JavaScript language. Classes in JavaScript do not actually offer additional functionality, and are often described as providing "[syntactical sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)" over prototypes and inheritance in that they offer a cleaner and more elegant syntax. Because other programming languages use classes, the class syntax in JavaScript makes it more straightforward for developers to move between languages. 6 | 7 | Both classes and constructors imitate an object-oriented inheritance model to JavaScript, which is a prototype-based inheritance language. Being familiar with classes is extremely helpful, as popular JavaScript libraries make frequent use of the `class` syntax. 8 | 9 | ```javascript 10 | // Initializing a function with a function expression 11 | const x = function() {} 12 | 13 | // Initializing a class with a class expression 14 | const y = class {} 15 | ``` 16 | 17 | ## Defining a class 18 | 19 | Classes are not hoisted like function declaration. The reason for this limitation is because of the ability to extend the class into a new object. It must be evaluated in the proper “location”. 20 | 21 | Also, all code inside the class construct is automatically in strict mode. 22 | 23 | ### Constructors 24 | 25 | The `constructor` method is a special method for creating and initializing an object created using classes. This shouldn't confuse you with the constructor pattern that developers used to follow before the introduction of classes. 26 | 27 | ```javascript 28 | // Initializing a constructor function 29 | function Person(name, age) { 30 | this.name = name; 31 | this.age = age; 32 | } 33 | 34 | // Initializing a class definition 35 | class Person { 36 | constructor(name, age) { 37 | this.name = name; 38 | this.age = age; 39 | } 40 | } 41 | ``` 42 | 43 | Developers used to follow the convention of capitailzing the first character in the constructor function. Now the class function does exactly the same as the constructor pattern except it uses the `constructor` function. 44 | 45 | A `constructor` can use the function `super` to call the constructor of the super class. More details about that in the *Extending class* section. 46 | 47 | Note that classes have a default `constructor() {}`. If there’s no `constructor` in the `class` construct, then an empty function is generated, same as if we had written `constructor() {}`. Not just that, it will also call the `super` by default. ESLint have a rule to [disallow unnecessary contstructor](https://eslint.org/docs/rules/no-useless-constructor) `no-useless-constructor` which commonly confuses beginners to React: 48 | 49 | ```javascript 50 | import React, { Component } from 'react'; 51 | 52 | class SomeComponent extends Component { 53 | constructor(props) { 54 | super(props); 55 | } 56 | } 57 | ``` 58 | 59 | ### Prototype Methods 60 | 61 | Method are added directly to the class body like the following 62 | 63 | ```javascript 64 | // Initializing a constructor definition 65 | function Person(name, age) { 66 | this.name = name; 67 | this.age = age; 68 | } 69 | // Adding a method to the constructor 70 | Person.prototype.greet = function() { 71 | return `${this.name} says hello.`; 72 | } 73 | 74 | // Initializing a class definition 75 | class Person { 76 | constructor(name, age) { 77 | this.name = name; 78 | this.age = age; 79 | } 80 | // Adding a method to the constructor 81 | greet() { 82 | return `${this.name} says hello.`; 83 | } 84 | } 85 | ``` 86 | 87 | Class methods are non-enumerable. A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`. That’s good, because if we `for..in` over an object, we usually don’t want its class methods. 88 | 89 | ### Static methods 90 | 91 | Static methods are methods that are called without instantiating their class and cannot be called through a class instance. They are meant to provide class-specific methods for object-oriented programming in Javascript. 92 | 93 | One difference between static methods and class methods is that the static method doesn't go in the prototype chain. Also another difference is the reference of `this` keyword. In the static method, `this` keyword will refer to the class itself. 94 | 95 | Static methods arre used to create functions that belongs to the class and not the instance. For example, in our `Person` class we can create a static method `getOldest` that can take an array of instances and return the oldest person in the list. 96 | 97 | ```javascript 98 | class Person { 99 | constructor(name, age) { 100 | this.name = name; 101 | this.age = age; 102 | } 103 | static getOldest(people) { 104 | return people.reduce((previous, current) => { 105 | return (current.age > previous.age) ? current : previous; 106 | }); 107 | } 108 | } 109 | const people = [ 110 | new Person("John", 24), 111 | new Person("Peter", 31), 112 | new Person("Will", 25), 113 | ]; 114 | Person.getOldest(people); // Person {name: "Peter", age: 31} 115 | ``` 116 | 117 | ### Getters and Setters 118 | 119 | Classes may include getters/setters. Here’s an example with `user.name` implemented using them: 120 | 121 | ```javascript 122 | // Initializing a class definition 123 | class Person { 124 | constructor(name, age) { 125 | // invokes the setter 126 | this.name = name; 127 | this.age = age; 128 | } 129 | get name() { 130 | return this._name; 131 | } 132 | set name(value) { 133 | if (value.length < 4) { 134 | alert("Name is too short."); 135 | return; 136 | } 137 | this._name = value; 138 | } 139 | } 140 | 141 | const john = new Person("", 24); // Name too short. 142 | ``` 143 | 144 | Getters can call anything we define not just the properties we use. For example we can define a getter method called `yearOfBirth` that calculate the year of birth of the person and return the date. We saw how to use setters in the example above to validate the paramteres and ensure that the function works as expected. 145 | 146 | ## Extending class 147 | 148 | An advantageous feature of constructor functions and classes is that they can be extended into new object blueprints based off of the parent. This prevents repetition of code for objects that are similar but need some additional or more specific features. 149 | 150 | New constructor functions can be created from the parent using the [`call()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) method. 151 | 152 | ```javascript 153 | // Creating a new constructor from the parent 154 | function Student(name, age, grade) { 155 | // Chain constructor with call 156 | Person.call(this, name, age); 157 | this.grade = grade; 158 | } 159 | 160 | const john = new Student('John', 14, '8th grade'); 161 | ``` 162 | 163 | With ES6 classes, the [`super`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super) keyword is used in place of `call` to access the parent functions. We will use `extends` to refer to the parent class. 164 | 165 | ```javascript 166 | // Creating a new class from the parent 167 | class Student extends Person { 168 | constructor(name, age, grade) { 169 | // Chain constructor with super 170 | super(name, age); 171 | // Add a new property 172 | this.grade = grade; 173 | } 174 | } 175 | const john = new Student('John', 14, '8th grade'); 176 | ``` 177 | 178 | The output is nearly exactly the same, except that in the class construction the `[[Prototype]]` is linked to the parent, in this case `Person` unlike the using the constructor which will be linked to `Student`. -------------------------------------------------------------------------------- /css/selectors.md: -------------------------------------------------------------------------------- 1 | # [WORK IN PROGRESS] Selectors 2 | 3 | CSS selectors are the means that we utilize to target elements in our DOM tree and apply certain styles to these DOM nodes. The same DOM node can be selected by different types of selectors. It might look intimidating at the beginning but it gets easier to understand when you start working with them. Understanding how selectors work is a corner stone for writing elegant CSS. 4 | 5 | ## Types of selectors 6 | 7 | ### The universal selector 8 | 9 | The universal selector matches against every element in the DOM tree. It's written using the asterisk `*` like the following: 10 | 11 | ```css 12 | * { 13 | /* style that will be applied to the whole document */ 14 | } 15 | 16 | header * { 17 | /* style that will be applied to all the elements inside the header tag */ 18 | } 19 | ``` 20 | 21 | The universal selector was commonly used for resetting CSS properties on all the elements. It's worth mentioning that it is always feared of being bad for performance. These claims were disproved according to the [tests ran by Steve Souders](http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/) and it was proven that their impact on performance is negligible in real world scenarios. 22 | 23 | The most common use of the universal selector nowadays is setting the `box-sizing` like the following: 24 | 25 | ```css 26 | * { 27 | box-sizing: border-box; 28 | } 29 | ``` 30 | 31 | Perhaps the fear of the universal selector roots to our old friend IE6 where developers used to target this browser by prefixing the `*` to the properties and not the selector itself. This hack doesn't have anything to do with the universal selector. 32 | 33 | ```css 34 | li { 35 | display: inline-block; 36 | *display: inline; /* will affect IE6 only because IE6 doesn't understand inline-block */ 37 | *zoom: 1; 38 | } 39 | ``` 40 | 41 | ### Type / Element selector 42 | 43 | Type selector target specific elements according to their matching tag. It simply consists of the name of the tag used different in the HTML. For instance if you want to change the `font-family` for all the `h1` elements in the page that can be done using something like: 44 | 45 | ```css 46 | h1 { 47 | font-family: Impact, sans-serif; 48 | } 49 | ``` 50 | 51 | Type selectors -on their own- are very generic and should be used with caution. I commonly see novice developers using it to reset common and useful style that for sure would be needed like removing all the bullets from an unordered list: 52 | 53 | ```css 54 | ul { 55 | list-style: none; 56 | } 57 | ``` 58 | 59 | Before you do something like that you should ask yourself, am I 100% sure that I won't the display of a list on any of the pages I am working on? Once you do that, if you ever needed to insert a bulleted list you starts to target that list using different methods to set the bullets back (using class selectors or combined selectors). That could be perfectly fine for you but for someone working with you on the same codebase that can be very confusing. 60 | 61 | Another mistake I see as well is using the same example to apply very specific styles to elements that can break other elements. Consider the following: 62 | 63 | ```css 64 | input { 65 | width: 300px; 66 | height: 40px; 67 | padding: 0 10px; 68 | font-family: inherit; 69 | } 70 | ``` 71 | 72 | This will make all input elements look the same regardless of their type. The only problem that we are applying the same style to some elements and will break their look like the following: 73 | 74 | ```css 75 | 76 | 77 | 78 | ``` 79 | 80 | I don't think anyone ever saw a checkbox 300px wide. This end by either setting different style to these elements by other means (class selectors, attribute selectors) or using a more appropriate selector for the elements we are targeting. 81 | 82 | It's worth mentioning that element selectors are case-insensitive but it is always discouraged to utilize uppercase when you write CSS in general. 83 | 84 | ### Class selector 85 | 86 | An HTML class is an attribute used to landmark an element in order to select it. It's like a label we give to the elements to facilitate the way of *selecting* them in the future. 87 | 88 | Classes are case-sensitive and are writing by prefixing the class name with a dot: 89 | 90 | ```html 91 | 97 | 98 |

This paragraph's color will be red and its font-size is 20px

99 | 100 |

This paragraph will not be affected by properties in the .intro class

101 | ``` 102 | 103 | Most of the time we target elements using class selectors. Even most of CSS writing methodologies are based on strategies about picking an accurate and a self-explanatory class name (see CSS writing methodologies). An element can have multiple classes and these classes can interfere with each other. We will discuss that when talking about the cascade and the specificity. 104 | 105 | ### Pseudoclass selectors 106 | 107 | The word pseudo means something something that appear like something else that confuse the observer on the first sight. Pseudo-classes are combined to other selectors to modify their style when they are on a certain *state*. This is why I like to call them **state selectors**. 108 | 109 | #### `:hover` selector 110 | 111 | Perhaps the most commonly known selector of this type is the `:hover` selector. The `:hover` targets an element when the user move the pointer's cursor over it. Consider the following example: 112 | 113 | ```html 114 | 119 | 120 |

Please check the information posted on our privacy policy before continueing to use this service.

121 | ``` 122 | 123 | When the user move the pointer over the `` tag, the underlying text below the link will disappear. Note how these types of selectors are written; it starts with a column then the keyword is attacked to it directly. 124 | 125 | > 📜 **A little bit of history ** 126 | > 127 | > The `:hover` selector is supported on every type of elements but that wasn't always the case. On IE6, the `:hover` selector used to work on anchor tags only. Also, IE7 and IE8 used to ignore the `:hover` selector if a strict doctype is not used. Developers used to mimic the hover effect by using JavaScript to add and remove classes like `.hover` on `mouseEnter` / `mouseLeave` events on elements. This was a commonly used technique when creating drop down menus as the the submenu was being displayed when the user hover the `li` and not the `a` inside. This technique was first described on [a list a part](http://alistapart.com/article/dropdowns) and was called Suckerfish Dropdown back in 2003! 128 | 129 | Be careful of using the hover to change the dimensions of an element or the size of its text. It will reposition the surrounding elements and text and will also trigger what we call the *reflow* or *layout thrashing* which is a performance bottle neck (see reflow, repainting). Instead, use CSS transition to achieve a similar effect. Consider the following: 130 | 131 | ```css 132 | a { 133 | font-size: 12px; 134 | } 135 | 136 | /* This is horrible and you don't want to do that */ 137 | a:hover { 138 | font-size: 16px; 139 | } 140 | 141 | /* This won't trigger reflow and will perform better */ 142 | a:hover { 143 | transform: scale(1.34); 144 | } 145 | ``` 146 | 147 | #### `:focus` selector 148 | 149 | The focus selector target elements that are focusable either by using keyboard or mouse. Some elements are focusable by default like anchors and inputs. Other non-focusable elements can be made focusable as well by setting their `tabindex` attribute to a non-negative integers (see `tabindex` in HTML). 150 | 151 | The focus selector plays a great role on making your document more accessible. Everyone benefits from it not just users who uses keyboard for navigation. When used in forms, it brings the user attention to the field he's focusing on. You probably are requested constantly to remove these blue lines from the text input when the user focus them on Chrome: 152 | 153 | ![](../images/css/selectors-focus-initial.png) 154 | 155 | While they seem annoying for anyone from a design perspective, this outlines helps bringing the user attention to the field being focused. It's common to see novice developers getting rid of these lines by using: 156 | 157 | ```css 158 | input:focus { 159 | outline: none; 160 | } 161 | ``` 162 | 163 | This is bad for everyone. A more appropriate approach will be removing the lines and providing something else that looks good. Consider the following example from Yahoo's registration page: 164 | 165 | ![](../images/css/selectors-focus.png) 166 | 167 | The First name field has a thick blue border at the bottom unlike the rest. See there is no harm on removing the outline, you should however provide something else to give a hint about the focus. 168 | 169 | Another common issue reported to developers is to remove the dotted outline around the links that look like the following on Firefox 170 | 171 | ![](../images/css/selectors-focus-links.png) 172 | 173 | This outline is the style that Firefox applies to the links that receive focus. OK let's get something off the road first ... If someone is to discover something like that then that user must've used the tabs to navigate the page. Anyone who would use something like that will fall in love quickly with the landmark that says where you are now exactly ... Why would anyone want to remove that? 174 | 175 | The answer is, some people discover this without using the tab for navigation. For instance, if you clicked a link that open in a new browser window then you close that window you will find that the link has received focus. The user knows nothing about the focus state nor using the keyboard for navigation. S/he think it's odd and report it. 176 | 177 | Another common use for the focus state is to mimic the behaviors shown on hover. Below is a screenshot taken from [the documentation](https://getbootstrap.com/docs/4.1/components/tooltips/) of the popular UI toolkit Bootstrap featuring the tooltip component. 178 | 179 | ![](../images/css/selectors-focus-tooltip.png) 180 | 181 | Tooltips are displayed on hover. To improve accessibility, the tooltip is displayed for those who focus the element as well. Can you figure out which one received the focus and which one received the hover? Correct; the tooltip at the top was triggered using the focus (can you see the focus outline on the link?) and the one at the bottom received the hover (notice the underline added to to this particular link). Bootstrap uses JavaScript to display these information but the same can be applied with CSS using focus state and a different type of selectors we will discuss later on. 182 | 183 | The last think about focus is that it can be used to **bring user attention to an element that looks inert by default** although it can be interactive. Consider the following HTML of an accordion component on a web page: 184 | 185 | ```html 186 |

How can I sign up?

187 |

Information about sign up

188 | 189 |

What's the available payment options?

190 |

Inforrmation about payment options

191 | ``` 192 | 193 | Accordions are common on the web, they help us save space on the page and help the user to check the topics faster. A common pattern is to make the title *clickable* using JavaScript and collapse/expand the content below it accordingly. Making the element focusable only require adding the attribute `tabindex` then we can add style to indicate to the user that this title has been focused and it can be opened if you pressed Enter on your keyboard: 194 | 195 | ```html 196 | 202 | 203 |

How can I sign up?

204 |

Information about sign up

205 | 206 |

What's the available payment options?

207 |

Inforrmation about payment options

208 | ``` 209 | 210 | #### `:focus-within` selector 211 | 212 | `:focus-within` is a relatively new pseudo-class selector. It matches an element that have a child element within its tree that received focus. This selector has been a dream for many developers who cared about making their content accessible because it enables us to achieve effects and behaviors that weren't available without the use of JavaScript. 213 | 214 | A common problem it solves is the navigation of dropdown menus using keyboard. The submenu only displays using `:hover` on the parent `li` and can be made visible if its title receive a focus. Once the focus move on to the submenu, the menu disappear because it is no longer receiving the focus nor the hover. To get a better understanding of the behavior you can check [this pen](https://codepen.io/ahmadalfy/pen/ppJGBJ) and try to navigate it using the `tab` key. 215 | 216 | Another common pattern this selector helps to solve is the customization of the `select` element. This technique was described by [filament group](https://github.com/filamentgroup/select-css) with a single flaw; you cannot change the caret's orientation when the `select` is opened. Using `:focus-within` can help you overcome that because when the select is opened, it will be focused and the wrapper can be selected using that selector to apply any style we want to the caret. 217 | 218 | #### `:active` selector 219 | 220 | This selector can be used to target an element being clicked. For instance, a button being clicked without releasing the mouse button. Once the button is released, it is no longer active. A common use for this selector is to mimic the effect of a button being pushed downward like the following: 221 | 222 | ```html 223 | 238 | 239 | 240 | ``` 241 | 242 | You can try it to see the effect [here](https://jsfiddle.net/f5rwk9ed/3/). 243 | 244 | ⚠️ It's worth mentioning that new comers commonly misunderstand this selector of being used to apply specific style to the menu item that indicate the *active* page. 245 | 246 | ------ 247 | 248 | Remaining: 249 | 250 | * Pseudo-classes 251 | 252 | * `:target` 253 | * Form pseudo-classes `:invalid`, `:required`, `:checked` 254 | * Links pseudo-classes `:link`, `:visited` 255 | 256 | * Attribute selectors 257 | 258 | * Element position selectors `:first-child`, `:nth-child` ... etc 259 | 260 | * Negation selector: `:not` 261 | 262 | * Language selector `:lang` 263 | 264 | * Matching selector `:matches` 265 | 266 | * Direction selector `:dir` 267 | 268 | * Pseudo elements `::before`, `::after` 269 | 270 | * ID selectors 271 | 272 | * Combining selectors: 273 | 274 | * Regular nesting 275 | * Direct descendent `>` 276 | * Direct sibling `+` 277 | * All siblings `~` 278 | -------------------------------------------------------------------------------- /css/web-fonts.md: -------------------------------------------------------------------------------- 1 | # [WORK IN PROGRESS] Web Fonts 2 | 3 | Web fonts play a great role on web design today. Thanks to the `@font-face` rule, we are able to use any custom font we want. It took us so long to get there. For a long time we were limited to a set of fonts that we used to call *web safe* fonts. Surprisingly the reason wasn't a technical one. 4 | 5 | The problem with the fonts is that they are really expensive. It takes a designer a lot of practice and patience to produce a typeface. Back in 1998 the CSS Working Group proposed the `@font-face` rule to allow the usage of custom fonts on the web. IE4 implemented that feature but it didn't succeed. By the end, who would risk and put a font that costs hundreds or thousands of dollars on the web so that others can download it and use it for free? 6 | 7 | In 2008 `@font-face` was implemented by Safari and Firefox and the road was being paved for custom fonts to come to the browsers. In 2009, [Typekit](https://typekit.com/) was founded (acquired by Adobe later on) and started offering high quality fonts with appropriate licenses for the usage on the web. Typekit published a post on their blog called [Serving and Protecting Fonts on the Web](https://blog.typekit.com/2009/07/21/serving-and-protecting-fonts-on-the-web/) explaining how they protect their fonts from being downloaded using different techniques. The growth of Typekit opened the door for other services to come to the surface and people started to get used to custom fonts on the internet. Time after time, the fear of piracy started to shrink. In 2010 Google launched [Google Fonts](https://fonts.google.com/) which now hosts more than 800 high quality font for anyone to use. 8 | 9 | These services were great as they offered new elegant and shiny fonts for everyone to use but they didn't let you use your own custom fonts on your website. Using a custom font on the web isn't as easy as installing a font on your machine, you will have to convert it first to an appropriate format that the browser can understand. In 2010 a popular service for hosting fonts called [FontSquirrel](http://fontsquirrel.com) (originally founded in 2009) started offering a free service that allows anyone to upload a custom font and it convert it to what was commonly became known as a *font-face kit*. 10 | 11 | ## `@font-face` 12 | 13 | We mentioned in the earlier section that the tools we use to generate the font-face kits generate different font formats. Typically, the output of the generated kit should be something similar to: 14 | 15 | ```css 16 | @font-face { 17 | font-family: 'Custom Font'; 18 | font-style: normal; 19 | font-weight: 400; 20 | src: local('Custom Font'), 21 | url('/fonts/file.woff2') format('woff2'), 22 | url('/fonts/file.woff') format('woff'), 23 | url('/fonts/file.ttf') format('truetype'), 24 | url('/fonts/file.eot') format('embedded-opentype'); 25 | } 26 | ``` 27 | 28 | The declaration consists of the following descriptors: 29 | 30 | * `font-family` describes the font name. This is the name that we will eventually use it when we want to apply that custom font. It's common to wrap custom font names in quotes. According to the [W3C](https://www.w3.org/TR/css-fonts-3/#family-name-value) punctuation characters, digits at the start of the name should be escaped. To avoid escaping errors, it's always recommended to quote custom font names. 31 | * `font-style` tells the style of the font. This can either be normal or italic. 32 | * `font-weight` tells the weight of the font. The range from `thin` towards `black`. 33 | * `src` defines the path to the custom font files. It optionally starts with the local variant of the font then followed by the urls and formats of the provided font files. Why do we need to load all these formats? This is what we are going to discuss on the following section. 34 | * `font-display` determines how a font face is displayed based on whether and when it is downloaded and ready to use. More information about this descriptor on the fonts loading section below. 35 | 36 | Sometimes we use a descriptor called `unicode-range` to restrict rendering a range of characters to a specific font. This technique is commonly used in Arabic websites when the font that is used in the design doesn't have a Hindi glyphs for the numbers. Most Arab countries and users uses Hindi glyphs (١٢٣٤٥٦٧٨٩٠) and not Arabic numbers (1234567890). To fix that, we use a custom font that contain the glyphs we want to use (like [GE SS Two](https://fonts2u.com/ge-ss-two-bold.font)) and restrict it to only render the numbers like the following: 37 | 38 | ```css 39 | /* The font used for the Aarbic text */ 40 | @font-face { 41 | font-family: 'Custom Arabic Font'; 42 | font-style: normal; 43 | font-weight: 400; 44 | src: local('Custom Arabic Font'), 45 | url('/fonts/file.woff2') format('woff2'), 46 | url('/fonts/file.woff') format('woff'); 47 | } 48 | 49 | /* The font used for the Hindi numbers. Note that we use the same family name as the font we used above */ 50 | @font-face { 51 | font-family:"Custom Arabic Font"; 52 | unicode-range: U+0030-0039; 53 | src: url('/fonts/GE-SS-TWO.woff2') format('woff2'), 54 | url('/fonts/GE-SS-TWO.woff') format('woff'); 55 | } 56 | ``` 57 | 58 | As you have noticed, we used the same `font-family` value for both fonts with the addition off the `unicode-range` for the font that will be used to render the numbers. This way we ensure that the numbers will always be rendered as we want. 59 | 60 | Note that the `U` character written at the beginning of the value should be in uppercase otherwise it will be an invalid values in some browsers. 61 | 62 | > We used the term descriptor instead of properties within the @font-face rule. Refer to [CSS Syntax](syntax.md) to understand the difference between both. 63 | 64 | ## Formats 65 | 66 | Different browsers support different formats of font files. This is why we are declaring a list of different formats for the browsers to pick the one it can use. Browsers didn't agree to support a common format because of several reasons like licensing and other stuff. The timeline for the formats usage was like the following: 67 | 68 | * Older versions of IE started to support Embedded OpenType (EOT) format. EOT was proprietary to Microsoft then it was submitted to W3C to make it an open Web Standard. 69 | * Until Safari 4 on iOS, SVG fonts was the only supported format. Its file size was the biggest (but compressed very well with gzip) and lacked [font-hinting](https://en.wikipedia.org/wiki/Font_hinting). It had a few bugs related to text selecting but it was the only way to display custom fonts on iPhone and iPad on this time. 70 | * Newer versions of IE (9 and above), Firefox, Chrome and Safari on Mac was supporting OTF and TTF. 71 | * Mozilla, Microsoft and Opera worked on a new standard together and proposed the Web Open Font Format (WOFF) which is OTF/TTF with metadata and compression. This format was created to be used on the web and it has an advantage over the other formats of being smaller in size. This format is widely supported on all modern browsers. 72 | * WOFF2 is the next generation of WOFF and it is 30% smaller in size. It is less widely supported than its predecessor. 73 | 74 | We don't use some formats like the EOT and SVG because it's unlikely to find users who still use old browsers that require these formats. You are most likely to encounter these formats in old code base. It's mostly limited now to WOFF2, WOFF and TTF/OTF. 75 | 76 | ## Generating custom font kits for the web 77 | 78 | We mentioned earlier the service named [FontSquirrel](http://fontsquirrel.com) where you can go and upload your custom font (TTF/OTF) and generate the different formats in addition to the CSS you will need to use. It will check the font against a list of known or previously reported commercial fonts and if it isn't in that list it will generate the kit. 79 | 80 | I personally use another service called [onlinefontconverter.com](https://onlinefontconverter.com/) because it works very well with fonts for non-latin languages (like Arabic) unlike FontSquirrel. 81 | 82 | There is also a free desktop application called [FontPlop](https://www.fontplop.com/) but it works on Mac only. 83 | 84 | ## Fonts loading 85 | 86 | The browser doesn't download the font files unless it tries to render text that require that font. In other words, if your CSS file reference the bold weight of the font `Roboto` but the current page the user is visiting doesn't have any bold text, the font will not be downloaded. This is actually good because it saves the bandwidth and ensure that only the needed font weights/families are downloaded. 87 | 88 | Because fonts aren't downloaded until required, this sometimes leads to what we call **Flash of Invisible Text (FOIT)** and **Flash of Unstyled Text (FOUT)**. In other words, text space being preserved but the text itself is invisible then uses another font. This happens because browsers follow different policies for rendering text while the font is being downloaded. Let's take a look at the font display timeline. 89 | 90 | ### Font display timeline 91 | 92 | The moment the browser tries to use a font for the first time on a page, the font files download timer is started. This timer advances through three periods of time associated with the font: 93 | 94 | * **Font block-period**. During this period if the font file is not loaded, The text trying to use that font will use be invisible. If the font is successfully downloaded during the block-period, the font will be used normally. 95 | * **Font swap-period**. During this period, if the font file is not downloaded, the text will be rendered using the fallback font. If the font file is downloaded successfully during, the font will be used normally. 96 | * **Font failure-period**. If the font file is not downloaded the font is marked as a failed load and the fallback font will be used. 97 | 98 | Each period varies according to the browsers. Some browsers like IE will render the fallback font first and render the custom font once it is ready. Chrome and Firefox will have a block-period of 3 seconds then either use the fallback font or the custom font. Safari on iOS have a relatively long block-period of 30 seconds before using the fallback font. Because of these variation, a standard was developed (currently a working draft) to control this behavior using the `font-display` descriptor. 99 | 100 | ### `font-display` descriptor 101 | 102 | The `font-display` descriptor is used to control the behavior of the browsers when downloading custom fonts and rendering text. The `font-display` descriptor is used inside the `@font-face` rule and accept one of the following values: 103 | 104 | * `auto` is the default value. This will leave the display to the policy defined by browsers. Most of the browsers have a default policy similar to `block`. 105 | * `block` will give a short block-period (3 seconds) and an infinite swap-period. That means that the browser will render invisible text at first if the font is not downloaded for 3 seconds. During this period if the font is downloaded, it will use the font once it is downloaded. If it couldn't download the files, it will use the fallback font. 106 | * `swap` will gives a very short block-period (100ms) and an infinite swap period. That means that the browser will render the text immediately with the fallback if the font files aren't downloaded and will render the text again using the custom font if it is downloaded. 107 | * `fallback` will give a very short block-period (100ms) and a short swap-period (3 seconds). That means that if the text will be rendered with the fallback font at first if the font is not loaded. It will be swapped with the custom font if it is downloaded within 3 seconds. After that, the font will not be used to render the text again and it will keep using the fallback font. 108 | * `optional` will give a very short block-period (100ms) and a zero second swap period. That means that the custom font will only be used if it has been downloaded and cached. Otherwise, the fallback font will be used. The browser can decide to abort downloading the font if the connectivity is low or the browser is operating under the [Data Saving](https://support.google.com/chrome/answer/2392284?hl=en&co=GENIE.Platform%3DDesktop&oco=0) mode. With this option, the custom text will be only used on subsequent visits to the website pages after the font is downloaded and cached. 109 | 110 | To see the effect of this descriptor in action, you can check this [YouTube video](https://www.youtube.com/watch?v=PuGmlOe5wRk) using Chrome DevTools and the [network throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) options. Perhaps now the question to answer, which one should I use? 111 | 112 | * `block` usage should be **limited to a few cases where using the custom font is crucial**. Consider an icon font that uses regular character or unicode characters to render icons. While the font is being downloaded and the `font-display` is set to `swap`; unrelated characters or squares will show up. `block` will be perfect and cause less confusion to the reader. 113 | * `swap` usage should be **limited for short text** (like titles, logos). If we used `swap` on long chunks of text it will be very confusing for the reader to follow the text after the re-render happens. The size of the characters varies across the different font. If the difference in size between the two fonts is noticeable, the text will be rearranged in the page and the reader might lose track of where he stopped before the re-rendering happens. 114 | * `fallback` should be **used for large pieces of text**. Ideally the focus on the body text shouldn't be how the font's *look*. The user shouldn't be disturbed by the text rearrangement when the new font is swapped. The only problem with this technique is to explain to non-techie customers you are building a platform for "why is the body text sometimes looks different". 115 | * `optional` is the best if accessibility is your top priority. It's similar to `fallback` but stresses more on getting the text rendered with the least bandwidth usage. 116 | 117 | > The numbers mentioned above (3s and 100ms for blocking) aren't defined by the specs, they are just a recommendation. Google Chrome change this time adaptively to improve performance on slow connections if `font-display` is set to `auto`. This manifest as a console warning/error. You can read more about it [here](https://www.chromestatus.com/feature/5636954674692096). 118 | 119 | ## TODO 120 | 121 | - Different syntax used for loading custom fonts along with its corresponding weights and the local reference 122 | - Fonts and CORS 123 | - Add note about `@font-feature-values` rule 124 | - Identifying rendered font in Chrome 125 | - Optimizing font loading with link preloading 126 | - Font Loading API 127 | - A little bit about what we used to use before custom fonts (cufón, sIFR, image replacement techniques ...) 128 | 129 | ## Notes 130 | 131 | ### Tools 132 | 133 | * [FontSquirrel](http://fontsquirrel.com) Free fonts library and online web fonts generator. 134 | * [Online font converter](https://onlinefontconverter.com/) A free and reliable online tool to generate web fonts. Very useful if you need to convert a non-latin typeface (like Arabic) 135 | * [FontPlop](https://www.fontplop.com/) Open source web font converter for Mac 136 | 137 | ### Great resources 138 | 139 | * [Web Fonts are Rocket Science](https://vimeo.com/254727749) - SmashingConf London 2018 — Zach Leatherman 140 | * [Zach Leatherman blog](https://www.zachleat.com/web/fonts/) about web fonts, web font loading and typography. One of the best advocates on the topic. 141 | 142 | ### References 143 | 144 | * [Fonts on the web](https://www.w3.org/Fonts/) - W3C 145 | * [Serving and Protecting Fonts on the Web](https://blog.typekit.com/2009/07/21/serving-and-protecting-fonts-on-the-web/) by Typekit 146 | * [Fighting the @font-face FOUT](https://www.paulirish.com/2009/fighting-the-font-face-fout/) by Paul Irish --------------------------------------------------------------------------------