@home

November 23, 2022 Reading time: ~1 minute

Welcome

You reached a self-hosted website with no ambition except being some kind of a notepad as well as a personal sandbox. But feel free to take away anything you may find useful.

I'm considering publishing here short articles about what I'm learning. I'll avoid hosting images because I don't have much storage available.

Stay tuned!


Qwixx project - v1 released

December 13, 2024 Reading time: 2 minutes

I'm happy to announce that the first version is available since May! You can play Qwixx here: https://qwixx.jboisseur.xyz

Long story short

I've been working on this project for a long time. It started when I took a few Python lessons a few years ago but I abandonned because I had no clue about how to get an UI. Going back to HTML/CSS and then starting learning JavaScript put me back on tracks.

What I learned

So many things! Particularly in JavaScript where I worked with arrays, listened for events, ran a huge amount of loops, created functions, toggled CSS classes, saved data in the user's browser etc. I also learned about debugging and using the web developer tools on the browser. I had to use some PHP as well, for saving best scores.

This said, I think the biggest take away was to divide the work into achievable challenges and push the harder ones at the end. Keeping this goal in mind: at the end of each step, the full game should be playable. This way, the path was most of the time enjoyable, and having something to share along the way is very rewarding.

What I plan

I already started working on version 2, which is about allowing two persons to play on a same device. I'm experimenting working on cold and old code. It's very time-consuming but I try to refrain from starting all over on a blank project. I try to improve what's already there and implement what's missing to achieve this 2-players goal. One small step at a time.


cosmetic CSS properties

September 8, 2024 Reading time: 4 minutes

The less the better BUT just in case, these CSS properties could be handy for some cosmetic touches (examples available on an ugly CodePen):

Shadowing

Use box-shadow and / or text-shadow property. Values: offsetX offsetY (blurRadius) (spreadRadius) color.

For instance

<p class="shadow">Lorem ipsum</p>

.shadow {
box-shadow: 2px 5px 2px 5px rgba(100, 100, 100, .25);
text-shadow: 2px 5px 2px green;
}

Aligning

last line of text

Use text-align-last property (right or center)

an element vertically

Use vertical-align property (text-top / super ; text-bottom / sub)

Fun with fonts

Decorate

text-decoration shorthand property for: text-decoration-line, text-decoration-color, text-decoration-style, text-decoration-thickness

For instance :

text-decoration: underline overline dotted red 5px;

Vary

font-variant property to display text in a small-caps font for instance

Default size

Good to now: 1em corresponds to the current font size (browser default is 16px.

The solution that works in all browsers:

body { font-size: 100%; } 
h1 { font-size: 2.5em; }
h2 { font-size: 1.875em; }
p { font-size: 0.875em; }

a: pseudo classes

/* unvisited link */ 
a:link { color: red; }

/* visited link */ a:visited { color: green; }

/* mouse over link */
a:hover { color: hotpink; }

/* selected link */
a:active { color: blue; }

!important:

  • a:hover MUST come after a:link and a:visited
  • a:active MUST come after a:hover

Tables

Also use :hover pseuo-class with a background-color property on <tr>!

Zebra-strip table with tr:nth-child(even) { background-color: #f2f2f2; }

That's all... for now.

Prevent textarea resizing

overflow: hidden;
resize: none;

For loop: are you of or in?

July 13, 2024 Reading time: 2 minutes

Aren't you? I'm always struggling to know where to use the for... of loop or the for... in loop.

Let's have here a quick note for reference:

for... of loop

Iterates over an iterable object (object, array, string, map...) and temporarily assign to a variable

const chars = ["Jack", "Daniel", "Sam", "Teal'c"];

for (const char of chars) {
console.log(char); }

Note that you can use const if the variable is not reassigned within the loop.

for... in loop

Loops for properties of an array or object. Not to be used if the order is important.

// array
const chars = ["Jack", "Daniel", "Sam", "Teal'c"];

for (let char in chars) {
console.log(char); // prints the indexes as strings
console.log(chars[char]); // prints the value }

// object
const soldier = {firstname: "Jack", lastname: "O'Neill", team: "SG1"};

for (let key in soldier) {
console.log(key); // prints the key (firstname, lastname, team)
console.log(soldier[key]); // prints the value (Jack, O'Neill, SG1) }

forEach() method

The same result can be obtained using forEach() method (on an array).

const chars = ["Jack", "Daniel", "Sam", "Teal'c"];

chars.forEach(function (char, index) {
console.log(index); // prints the indexes as numbers
console.log(char); // prints the names
});


grid overview

February 19, 2024 Reading time: 4 minutes

Two steps are required when it comes to building grid designs:

  1. slice a container into... a grid
  2. fill the cells or area of cells with elements

Imagine we work with following code:

<div id="container">
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
</div>

The corresponding CodePen is of course available.

Slicing

First, we need our container to display its content as a grid : #container { display: grid; }. After that we need to slice down the container. There's two ways to do that:

Classic way

#container {
display: grid;
grid-gap: 1em;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}

Here we'll have a grid of 2 columns and 2 rows.

By name

#container {
display: grid;
grid-gap: 1em;
grid-template-areas:
"div1 div2"

"div3 div4"
}

Same here but we use names. In both cases we set up a gap, which is the space between the child element of the container.

Filling

Classic way

#div1 {
grid-column: 1;
grid-row: 1;

}

div1 will go in first column and first row.

By name

#div1 {
grid-area: div1;
}

Here we declare the element's name. As div1 was the first name on the first line, #div1 element will go on first column and first row.

Units and functions

For the slicing part, we can use different units, exclusively or in a combination, such as:

  • fraction (fr) - the browser divides the screen with the all fractions that were specified
  • relative units: %, vw, vh, auto...
  • fixed units: px
  • keywords: min or max-content, auto

We can also use functions, exclusively or in combination, such as:

  • repeat(nbOfTimes, unit)
  • minmax(minSize, maxSize)

Coordinates

For the filling part, we can set up precise coordinates which will be a line or a column line number with the syntax from / to

For instance, if our first div was supposed to fill the entire first line, we could write:

#div1 {
grid-column: 1 / 3;
grid-row: 1;

}

Where we are telling the brower to extend #div1 on column 1 and 2 (column 1 is between number 1 and 2 and column 2 between number 2 and 3).


CSS selectors

February 11, 2024 Reading time: 4 minutes

Target the right element is a must-know. Here's a recap of the available options. Examples are for the following structure:

<h2>Some title</h2>
<p>A paragraph</p>
<div>
<p>I am child of div</p>
<p>The guy up there is my bro.</p>
<section>
<p>Lonely paragraph</p>
</section>
<p>Third brother.</p>
</div>
<p>Out of div</p>
<p>Same</p>

As always, a demo is available on CodePen.

Combinators

Target a list of elements

Separate the elements with a ,.

h2, section {
font-weight: bolder;
color: navy;
}

Target all descendants of an element

Separate the parent element from the descendant element with a space.

div p {
text-decoration: underline;
}

Target all children of an element

Separate the parent element from the child element with a >.

body > p {
font-family: monospace;
}

Target the next sibling

Separate the first bro element from the second with a +.

div + p {
text-align: center;
}

Target all next siblings

Separate the first bro element from the other ones ~.

div ~ p {
width: 20%;
padding: 0.5em;
border: 0.25em solid indianred;
}

Pseudo-class selectors

A full list can be found on MDN Web Docs.

Target all first child from a parent element

Use a pseudo class after the element's name you want to target:

p:first-child {
letter-spacing: 0.25em;
}

Target every x element of a type from a parent

p:nth-of-type(3n) {
color: blue;
}

Pseudo-elements

Locate a starting point then create inline elements or specific decoration. For instance:

h2::before {
content: "♥ ";
}

h2::selection {
background-color: gold;
}

Attribute selectors

There's no attribute in the demo page. See attribute selectors


xHTML vs HTML5

January 26, 2024 Reading time: ~1 minute

I may have been stuck in xml model or several years ago but in the Uni course I learned that a HTML5 document doesn't validate if you close self-closing elements. You should write <img src="" alt="">, <br>, <hr> etc. and not <br/> and so on.

Here's the W3C HTML5 validator: https://validator.w3.org/nu/#textarea. You can also add an extension to your code editor.

Also, the closing tag may be omitted if a block element follows, for instance:

<p>Some text added
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>

is valid.

Confusing, eh!