Nested CSS without preprocessors

I don’t know when I’ve started using Sass but. My first blog post on that topic dates back to 2012. There are many features I love Sass for, and one of them is nesting.

What is nesting in Sass

A typical example for when nesting is really helpful is when dealing with CSS selectors of elements, that are usually children of other elements. Unordered lists used for navigation menus are a great example here:

nav {
	ul {
		list-style: none;

		ul {
			display: block;
		}
	}

	li {
		display: inline-block;
	}

	a {
		display: block;
		padding: 5px 10px;
	}
}

In this code, we have some child (or grandchild) nodes of a <nav> tag. By nesting them, and using a preprocessor like Sass, we get the following result in the compiled CSS:

nav ul {
  list-style: none;
}
nav ul ul {
  display: block;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 5px 10px;
}

Many of you will probably agree, that the Sass code is easier to write and change, as you don’t have to write the full CSS selector. Rearranging the nesting becomes really easy, compared to replacing the middle parts of long CSS selectors. The selectors I’ve chosen above are rather short. This is on purpose, as you should not nest too much, just because you can, or even worse, because it replicated your HTML. We probably don’t need a CSS selector like “nav ul li a“, since if we just want to style every link in the navigation, just having “nav a” is all we need.

How to use nesting without a preprocessor?

If you try to use that nicely nested code in a .css file, it might just work. No more need to use a preprocessor. But you might have to support a browser, that does not implement this new specification, and which doesn’t understand this syntax. For those browsers, all you have to do is adding an & before each nested selector. The code above changes to this:

nav {
	& ul {
		list-style: none;

		& ul {
			display: block;
		}
	}

	& li {
		display: inline-block;
	}

	& a {
		display: block;
		padding: 5px 10px;
	}
}

Fortunately, all major browsers have implemented this new specification, where you don’t have to add the & before the nested selectors. But they also support the old syntax. So if you want to be safe, you could still use this old syntax for some time. I can also highly recommend reading a bit more on CSS nesting in the documentation.

Conclusion

That’s it! Just use nesting as in Sass, Less and other preprocessors and modern browsers will understand your code. If you still use a preprocessor for other things like variables, they will still convert this syntax into the normal “long CSS selectors”.

With CSS custom properties (variables) and nesting, there are two of three features now native to CSS, I use a lot in Sass. The last one is “templating” using multiple files for different part/components. The rest like mixins are more “nice to have” for me, but not really essential.

Dynamic parameters in JavaScript

Many programming languages have this. Instead of defining all parameters for a function, you can pass any number of parameters into a function and then work with them.

Functions with static parameters

Before we get into dynamic parameters, let us introduce a function we can then work on. How about one adding two numbers?

function sum( a, b ) {
	return a + b;
}

console.log( sum( 4, 5 ) ); // 9

Nothing special here, right? But what would happen if we just add more parameters to the function call?

console.log( sum( 4, 5, 6 ) ); // 9

Nothing would happen, since the function is only using the first two parameters. But you not get an error. JavaScript is simply not using the third parameter.

The arguments object

Even if we don’t use the third parameter, it is still available. But how can we use it, when we don’t have a parameter name for it? We can use the arguments object to get all the parameters, even if we haven’t even defined any parameter for the function:

function sum() {
  let total = 0;
  for (const number of arguments) {
    total += number;
  }
  return total;
}

console.log( sum( 4, 5 ) ); // 9
console.log( sum( 4, 5, 6 ) ); // 15

The arguments object works very much like an array. You can access the first parameter with arguments[0], etc. In our sum() function, we don’t even have any arguments at all, as mentioned before. But you can also combine defined and additional ones:

function someFunction( a, b ) {
	console.log( a ); // 4
	console.log( b ); // 5 
	console.log( arguments ); // [4, 5, 'a string', Array(2), ...]
}

someFunction( 4, 5, 'a string', [ 'an', 'array' ] );

The arguments object always contains all parameters passed to the function, even those with a name. The object has some other properties, you can read more about in the documentation.

The rest parameter

A more modern way to use dynamic parameters in JavaScript is the rest parameter. Let’s start with a simple example again. We implement our sum() function and use the rest parameter this time:

function sum( ...numbers ) {
	let total = 0;
	for ( const number of numbers ) {
		total += number;
	}
	return total;
}

console.log( sum( 4, 5 ) ); // 9
console.log( sum( 4, 5, 6 ) ); // 15

The only parameter here is “...numbers“, and this is the “rest parameter”. Another good example is this one:

function calc( operation, ...numbers ) {
	switch ( operation ) {
		case "sum":
			return numbers.reduce( ( total, num ) => total + num, 0 );
		case "multiply":
			return numbers.reduce( ( product, num ) => product * num, 1 );
		case "subtract":
			return numbers.reduce( ( difference, num ) => difference - num );
		case "divide":
			return numbers.reduce( ( quotient, num ) => quotient / num );
		default:
			console.error(`Invalid operation "${operation}"`);
			return;
	}
}

console.log( calc( "sum", 4, 5, 6 ) ); // 15
console.log( calc( "multiply", 4, 5, 6  ) ); // 120

Now the “rest” makes sense, right? We have some normal parameters, followed by the rest parameter, which contains all other parameter, or simply, the rest of the parameters. You can always only have one rest parameter, and it must be the last parameter. This example also shows a good use case for the console.error() function from our previous blog post.

Bonus: the arguments object used as the rest parameter

In our first example on the rest parameter, you wouldn’t even need to have the ...numbers parameter, since it’s the only parameter. You could just have used argument object in combination with the spread operator like this:

function sum() {
  let total = 0;
  const numbers = [...arguments]; // Convert arguments object to a real array
  for (const number of numbers) {
    total += number;
  }
  return total;
}

This conversion in line 3 is not really necessary, since the arguments object behaves very similar to an array, but nonetheless you can do it and might have a use case for this. But as soon as you have more (named) parameters, that probably wouldn’t work anymore.

Conclusion

A function with a fixed number of arguments might be too inflexible, especially, when you deal with arrays or lists. In these cases, the rest parameter or the arguments object can help to write some nice and short functions.

Advanced JavaScript debugging

In the very first advent calendar blog post this year, I’ve shown you how to “Getting started with JavaScript debugging“. Today, I want to show some more advanced techniques you can use to debug your code.

Different logging types

In the first blog post, we have only used console.log(), but there are more functions from the console object you can use:

console.debug('debug message');
console.info('info message');
console.log('log message');
console.error('error message');
console.warn('warn message');

And this is how they would look like in the Chrome Console:

The Chrome Console with the output of the four debugging methods info, log, error and warning.

The info and log method produce a similar output. The error and warning however are styled more prominent. Some of you might have noticed, that we only see 4 lines here. Where is the debug logging? This one might not be shown (by default) in your browser. In Chrome, you would click on the “Default levels” dropdown. Here, you can also activate “Verbose” to see the debug messages:

The Chrome Console with the output of debug method as well, after activating the "Verbose" debug level.

Since the debug output is also similar (in Chrome), you might not really need it. I would probably mainly use log, warning and error.

Using format strings and styling in messages

The debugging function accepts more than one parameter. If you just ass multiple strings, numbers, objects, etc., it would print each of them in one line separated by a space (for scalar types) or in multiple lines (for objects). But you can also use additional parameters for format strings and even styling.

Let’s begin with a format string. An example with a single %s placeholder for a string might look like this:

const code = 'Code';
console.log('%s is Poetry.', code);

And the output would be Code is poetry, as we would expect. But apart from the usual format string placeholder, you can use the %c placeholder. The very next parameter would be a CSS string, the following text would be styles with. Just like this:

console.log(
	'This is %csome green text, followed by %csome red and italic text.',
	'color: green;',
	'color: red; font-style: italic;',
);

If you have multiple %c placeholders, the styles our change to the next parameter and style any following text with these new styles. The output from the code above looks like this:

You can also combine the %c placeholders with any other usual placeholder. Why don’t you give it a try in your current browser console? But you can’t go too crazy. There are also a few CSS properties and values you can use in Firefox and Chrome.

More useful console debugging function

If you log a lot of messages, you can group them. You would start a new group by calling the console.group() function (with an optional label) and close the group with console.groupEnd(). You can even nest groups in groups, creating something like a “tree structure”.

There are some other instance methods you mind find useful in your debugging task, but one of them is really cool!

Measuring times in the console

The console object has some timing functions you can use for some easy performance checks. Here is an example using the console.time() function:

console.time("a timer label");
slowFunction(1000);
console.timeEnd("a timer label");

function slowFunction(milliseconds) {
	const start = Date.now();
	while (Date.now() - start < milliseconds) {
		// Simulating a long-running function
	}
}

The function “waits for one second” inside the while loop. The output in Chrome looks like this:

a timer label: 999.2578125 ms

Using the optional “label” as the first parameter, you can have multiple timers running. If you want to measure times in between, you can use console.timeLog() (with your label) to get “split times”.

Conclusion

While developing or analyzing some code, it can really help to log things to the browser console. If you have only used console.log() so far, make yourself familiar with the other useful methods.

But when it comes to finalizing your code, always make sure to remove those debugging methods. Some JavaScript compilers might even do that automatically, when you “build for production”.

The native HTML range input

Many of us have seen and used them. In the WordPress Block Editor, they are available for things like the font size of several blocks. This is how it looks for the core/paragraph block:

The "Typography" settings for the font size of a paragraph block, showing a number input on the left, and a range input on the right, with the numeric value in a tooltip below it.

When you use the range selector, it will show the current value under the “range thumb” and also updates it in the number input field left of it.

Options for the range input

The two most important attributes to the range input are probably the min and max attributes. So this is a basic example:

<input type="range" id="font-size" name="font-size" min="16" max="96" />
<label for="font-size">font size</label>

As always, don’t forget to have a <label> for your inputs. If you don’t set min, its default value will be 0 and for max it will be 100.

Another attribute you might want to use it step. This can be a decimal or floating-point value, like in this example:

<input type="range" id="font-size" name="font-size" min="16" max="96" step="4" />
<label for="font-size">font size</label>
<input type="range" id=">line-height" name="line-height" min="0" max="10" step="0.1" />
<label for="line-height">line height</label>

For some reason, WordPress is not using a range input, but only a number field. But it is also using a step width of “0.1” here.

On the documentation page, you will also find a rather crazy example for the step attribute, and it looks like this:

<input id="pi_input" type="range" min="0" max="3.14" step="any" />

If you use the value “any“, the input will really take “any floating-point” value in between min and max. Interestingly, if you use your keyboard to navigate to the range input, and then use the left/right cursor keys to move the thumb, you will get 100 discrete values. But if you use your mouse, you will get some random wild numbers in between.

Using the list attribute

In the last blog post on the HTML topic, we have already learned about the list attribute, and the range input also supports it. You can find some normal and creative examples in the documentation. In Chrome, using a list attribute lets the thumb “snap” to <option> values of the <datalist>, but you can still also have a value in between. In my opinion, you can best combine the list attribute with steps, as in this case, you only allow the selection of options in your <datalist>:

<label for="temp">Choose a comfortable temperature:</label><br />
<input type="range" id="temp" name="temp" list="markers" step="25" />

<datalist id="markers">
  <option value="0"></option>
  <option value="25"></option>
  <option value="50"></option>
  <option value="75"></option>
  <option value="100"></option>
</datalist>

This code shows an input without min/max values, but with an additional step="25" attribute. Also take a look at the example using labels.

Styling of the range input

The styling would look very different, depending on your browser or operating system. Even though WordPress is using a range input, what you see is not the input itself. It is made “transparent” and lays above some custom HTML using multiple spans to create a UI element, that looks the same in all browsers. If you want to use that exact element, you can use the RangeControl component in your JavaScript code.

But even if you can’t style the range input exactly the same, there are some options to styles it, like changing the color of the bar and thumb:

input[type='range'] {
  height: 30px;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
  height: 10px;
  background: red;
}
input[type='range']::-webkit-slider-thumb {
  position: relative;
  height: 30px;
  width: 30px;
  margin-top: -10px;
  background: green;
  border-radius: 50%;
}

This is only one example for Chrome/Webkit. It’s important to set many things to appearance: none, as otherwise the other styling changes would have no effect. These styles would result in a range input like this:

A label "Choose a comfortable temperature" with a range input below it. The input has a red background color (the range bar) and a green "thumb" (a circle to change the value).

You all know I’m not a designer, but I hope this illustrates the styling a bit. If you want to go really creative, take a look at the blog posts from CSS-Tricks, Smashing Magazine or W3Schools.

Conclusion

Range inputs can really make the UX of an online application better, since number inputs are not “as responsive” in some cases. And if you are not in the WordPress JavaScript ecosystem, using the native range input might be all you need.

Smooth scrolling using CSS

More than 9 years ago, I wrote a (German only) blog post about how to “improve JavaScript with scroll event handlers”. Back in the days, people would use a plugin like “WP-Smooth-Scroll” (it’s still around, but hasn’t been updated in 11 years). Smooth scrolling was often used in combination with a “scroll to top button”. The scroll effect was done with the scrollTop() function from jQuery. Nowadays, jQuery is not used as much. But scrolling with JavaScript is still around.

Scrolling a page with JavaScript

Beside “scroll to top buttons”, a website can also use “smooth scrolling” for anchors. If you want to see it in action, look no further than on the file wp-includes/js/admin-bar.js in WordPress core, where you will find this function:

/**
 * Scrolls to the top of the page.
 *
 * @since 3.4.0
 *
 * @param {Event} event The Click event.
 *
 * @return {void}
 */
function scrollToTop( event ) {
	// Only scroll when clicking on the wpadminbar, not on menus or submenus.
	if (
		event.target &&
		event.target.id !== 'wpadminbar' &&
		event.target.id !== 'wp-admin-bar-top-secondary'
	) {
		return;
	}

	try {
		window.scrollTo( {
			top: -32,
			left: 0,
			behavior: 'smooth'
		} );
	} catch ( er ) {
		window.scrollTo( 0, -32 );
	}
}

As you can see from the comment, this function has been around since WordPress 3.4, which was released in June 2012! The behavior: 'smooth' was added only later, since Firefox added it in 2015 and Chrome in 2017. But still today, you can click on the “Admin Bar” (on anything but a link) and the website will scroll up smoothly.

The issue with method

As we can see in the code above, the scrollTo() function takes an object with the exact scroll position in the viewport. For the WordPress “Admin Bar”, this is easy, since it sticks to the top of the page. But if we want to scroll to another element on the page using an anchor link, we need to calculate the position. And do you remember our last blog post on the CSS topic, “How to fix sticky headers“? If we want to make sure the scroll position is correct, we also need to take the scroll-margin-top offset into account.

An alternative JavaScript approach

There is another scrolling function, that is also around for many years: the scrollIntoView() function. With this one, we don’t have to calculate the position. We just select the element we want to scroll to and use this function on it:

const element = document.getElementById("some-anchor");
element.scrollIntoView();

The great thing about this one, is that you can even tell the function where to place the element. And it takes the scroll-margin-top or similar properties into account. There are some more examples on the documentation page. One of these other CSS properties is the one, I want to write about in this blog post.

The CSS scroll-behavior

Even without JavaScript, you can get a smooth scrolling by only using CSS. Just add the following to your page:

html {
	scroll-behavior: smooth;
}

Now, when you click on any anchor link, the site will “scroll smoothly” to that element. And since the browser knows exactly how to do that, we always get the perfect scroll position for that element.

Conclusion

Sure, you can use a function with 20 lines like in WordPress Core for a smooth scrolling effect. But you could also just use one CSS property and regular anchor links to get the same result. And I haven’t even told you about all the issues with JavaScript scrolling, like scrolling manual scrolling while the smooth scrolling is still animating, wrong position calculation due to lazy loading, etc. I hope this is enough to convince you for now. 😉

Labeled statement in JavaScript

You might now ask yourself: What?! That was also my first reaction, when I’ve heard about labeled statements. So what are they, and when can they be used?

Are they goto statements?

Many programming languages have goto statements. Some programming languages even only added them in later version, like PHP did with version 5.3, and this is how it would look like in PHP:

$array = [
	'one' => [ 1, 2, 3 ],
	'two' => [ 4, 5, 6 ],
];

foreach ( $array as $key => $numbers ) {
	foreach ( $numbers as $number ) {
		if ( $number === 4 ) {
			goto fourFound;
		}
	}
}

echo "There is no 4 in the array";
goto end;

fourFound:
printf( "There is a 4 in array '%s'", $key );

end:

In this example, we have two foreach loops. The code tries to and find a 4 in a two-dimensional array. As soon as a 4 is found, we can stop the loops and print the result. To leave the loop(s), this code is using a goto statement to “go to” line 17 to the label fourFound, where we print out the result. There is also a second goto at line 15, which would move to the end label. In any case, only one echo/printf function would be called.

Many experienced developers would see multiple ways to improve that code, but I hope it can demonstrate, how a goto in PHP (and many other languages work) works. But what are labeled statements in JavaScript? They are similar to the labels in PHP shown here, but there is no goto statement and those labels can only be used in combination with either the break or the continue keyword.

How to use continue and break in your code?

If you have a loop, you can break out of the loop, by using the break statement like this:

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

for (let i = 0; i < numbers.length; i++) {
	if (numbers[i] === 4) {
		console.log(`Found 4 at index ${i}`);
		break;
	}
}

This code would iterate through the numbers array, but as soon as it found the 4, it would “break out” of the array and not look at the other values.

The continue statement can be used to stop the current iteration and start with the next one. Like in this modified example:

for ( let i = 0; i < numbers.length; i++ ) {
	if ( numbers[i] % 2 !== 0 ) {
		continue;
	}
	if ( numbers[i] === 4 ) {
		console.log( `Found 4 at index ${i}` );
		break;
	}
}

In line 2, we check, if the current number is odd. If that’s the case, it can’t be the number 4 we are searching for. We then use the continue statement, to start with the next iteration, so the condition in line 5 would not be executed.

How to skip an “inner loop”?

Let’s take the first code example from PHP again and use the break statement instead of a goto statement:

$array = [
	'one' => [ 1, 2, 3 ],
	'two' => [ 4, 5, 6 ],
];

foreach ( $array as $key => $numbers ) {
	foreach ( $numbers as $number ) {
		if ( $number === 4 ) {
			break 2;
		}
	}
}

if ( $number === 4 ) {
	printf( "There is a 4 in array '%s'", $key );
} else {
	echo "There is no 4 in the array";
}

In PHP, you can use break 2 to not only exit the “inner loop”, but also the “outer loop”. So the number after break indicates how many “control structures” you want to break out from. Something similar is possible with continue 2, where the program would continue with the next iteration of the “outer loop”.

In JavaScript however, this is not possible. You cannot add any number after a break or continue statement. And that’s where labeled statements come into play.

Breaking out an inner loop in JavaScript

If we try to create the same code as above in JavaScript, we can use a labeled statement like in this code:

var array = {
	one: [1, 2, 3],
	two: [4, 5, 6],
};

outerLoop:
for ( var key in array ) {
	var numbers = array[key];
	for ( var i = 0; i < numbers.length; i++ ) {
		if ( numbers[i] === 4 ) {
			break outerLoop;
		}
	}
}

if ( numbers[i] === 4 ) {
	console.log( `there is a 4 in array ${key}'` );
} else {
	console.log( "There is no 4 in the array" );
}

The label does not need to be on its own line, it can also be in one line for the for loop. For better readability, I just formatted it like this.

If you prepend each loop with a label, you could also have use break statement to jump to any loop. The same is true for continue.

What should I use this for?

So should you use labeled statements? My advice would be similar to the one given by the xkcd comic on goto: Don’t use it!

If you end up writing some code that would profit from something like break 2, continue 2, or the JavaScript equivalent using a labeled statement, this would be a clear sign for me, that this piece of code should be refactored.

Instead of using a goto to jump out of a loop, put that loop inside a function and use return. And for nested loops, you can also use nested functions in loops.

There are plenty of things to optimize in the code above, not only the nested loops. With some modern JavaScript functions, it could look like this:

const array = {
	one: [1, 2, 3],
	two: [4, 5, 6],
};

function findTheFour(obj) {
	for (const property in obj) {
		if (obj[property].includes(4)) {
			return property;
		}
	}
	return null;
}

const found = findTheFour(array);
if ( found ) {
	console.log( `there is a 4 in array ${found}'` );
} else {
	console.log( "There is no 4 in the array" );
}

Isn’t that a lot easier to read? Using the includes() function for arrays, we can even safe the “inner loop”. And we do not need any labeled statement.

Conclusion

You may ask yourself why I’ve shown you this feature of JavaScript, and then advise against the usage of it. Well, there is code out there using it which you might not understand, if you have never seen labeled statements or goto in other programming languages. And I haven’t even shown you all the things you can do with it. So feel free to read the documentation on it, and maybe you do find a use case, where it can really benefit your code base, what ever case that might be.

Debugging arrays and objects in JavaScript with the console.table() function

In the first debugging blog post, we’ve learned about the console.log() method and how it works to debug scalar types or arrays. But there is a nicer way to log arrays or objects in the browser.

The console.table() function

As mentioned in the first blog post, the console object has some more useful functions, and today we want to take a look at the table() function.

Simple arrays

The function can be used to log arrays like this:

const colors = ["red", "green", "blue"];

console.table(colors);

This is the most basic example. We just use a one-dimensional (numerical) array. This is the result in the browser console:

Browser console, showing a table with "(index)" as the first column header and values ranging from 0-2, and "Value" as the second column header, with the color strings.

As you can see here, you get a table with two columns. The first one is the numerical “(index)” for the array, and the second one has the “Value” for each entry of the array. You will still always have the variable below the table, just as with console.log() and you can “expand” it here, to investigate it further.

Multidimensional arrays

The function can not only be used with simple one dimensional array, but you can also use it for multidimensional ones:

const names = [
	["Leia", "Organa"],
	["Luke", "Skywalker"],
	["Han", "Solo"],
];

console.table(names);

Now we have an array of (numerical) arrays and this is how it looks like in the console:

(index)01
0'Leia''Organa'
1'Luke''Skywalker'
2'Han''Solo'

We now have three columns. Since the “inner arrays” are numerical as well, we have column name “0” and “1” for them.

Logging objects

The function cannot only be used for arrays, but also for objects. The output depends on the structure of the objects.

Simple objects

Let’s create an object for one of the previous example:

function Person(firstName, lastName) {
	this.firstName = firstName;
	this.lastName = lastName;
}

const luke = new Person("Luke", "Skywalker");

console.table(luke);

And this is how that object would be logged into the browser console:

(index)Value
firstName'Luke'
lastName'Skywalker'

Logging arrays of objects

How about logging an array with multiple objects of the same type? Again, an example like before:

const leia = new Person("Leia", "Organa");
const luke = new Person("Luke", "Skywalker");
const han = new Person("Han", "Solo");

console.table([leia, luke, han]);

This is the resulting table for this array of objects:

(index)firstNamelastName
0'Leia''Organa'
1'Luke''Skywalker'
2'Han''Solo'

As many of you might have expected, the column names are now the property names of the objects.

Logging multidimensional objects

The previous example was using a numerical array. But how about an object of objects? Here is an example:

const family = {};

family.mother = new Person("Padmé", "Amidala");
family.father = new Person("Anakin", "Skywalker");
family.daughter = new Person("Leia", "Organa");
family.son = new Person("Luke", "Skywalker");

console.table(family);

And the result of this will look like this:

(index)firstNamelastName
mother'Padmé''Amidala'
father'Anakin''Skywalker'
daughter'Leia''Organa'
son'Luke''Skywalker'

That looks nice, right? Except for “(index)”, we have some good columns names and our index values also are not numerical anymore.

Logging only specific columns

The console.table() function has a second parameter columns, which is an array as well. It expects an array with the names of the columns/indices. So for our previous code, we could do this:

console.table(family, ["firstName"]);

And sure enough, this would be the logged results:

(index)firstName
mother'Padmé'
father'Anakin'
daughter'Leia'
son'Luke'

Pretty neat, isn’t it? This can be really useful when debugging some larger objects with multiple properties.

Conclusion

Even though you can use the generic console.log() function to debug and log arrays and objects, seeing them in a logged table, can make reading them a lot easier. You also don’t have to “expand” the tables.

Implement a color picker with native HTML

In the first advent calendar blog post with the topic HTML, I want to introduce an HTML element, some of you might not know. It’s not really its own element, but the <input> element of type color. With this element, you can add a very simple color picker to your web application.

Adding a color picker to your site

Inserting the color picker is straightforward. It’s an <input> element, and you can add a value attribute, if you want:

<input type="color" id="background" value="#000000" />
<label for="background">Background</label>

Yes, you always want to have a <label> with any form input field. If you don’t set a value, it would use #000000 as the default. You can also only set a hexadecimal RGB value, without an alpha value (transparency) so nothing like #00000066.

The color picker in different browsers

As with many other input-types, the color picker has a very different UI, depending on the operating system you are on and the browser you are using. There are some examples:

Chrome color picker in Linux
Chrome (Linux)
Chrome color picker in Windows
Chrome (Windows)
Firefox color picker in Linux
Firefox (Linux)
Firefox color picker in Windows
Firefox (Windows)

Chrome brings its own color picker, and it looks similar in Linux and Windows. Firefox on the other hand would use the native color picker from your OS.

Advanced usage with a color list

A bit hidden in the documentation of the element, you can see that the element can use a list attribute. That attribute alone would probably worth its own blog post. When you use that attribute, you can reference a <datalist> with some values. This is how it would be used:

<input type="color" id="text" list="text-colors"/>
<label for="text">Text</label>
<datalist id="text-colors">
	<option>#ff0000</option>
	<option>#00ff00</option>
	<option>#0000ff</option>
	<option>#ffffff</option>
	<option>#000000</option>
</datalist>

For the <option> values, you can also only use hexadecimal RGB values. This is how the color picker with the list looks like in Chrome:

Color list in Chrome (Windows)
Color list in Chrome (Windows)

If you have more than 5 values, it will show them in up to three rows with 5 colors each If you have even more values, it will show a scrollbar. In Firefox on Windows however, it would use the same color picker as before, and list the options below the “Custom colors” in the modal.

Bonus: Using WordPress color picker components

If you are developing a WordPress project, you can use the color picker components that are available in the WordPress components library.

The ColorPicker component

In @wordpress/components you will find the ColorPicker component, that would render the color picker:

import { useState } from 'react';
import { ColorPicker } from '@wordpress/components';

function MyColorPicker() {
    const [color, setColor] = useState();
    return (
        <ColorPicker
            color={color}
            onChange={setColor}
            enableAlpha
            defaultValue="#000"
        />
    );
}

When you use the components it would render “inline”, so not open on a click on a button:

ColorPicker component with a color picker, a select for "Hex", a "copy value" button and an input with "#000000" as its value.

If you want to have a button to open the color picker, you would have to implement that yourself. If you add the enableAlpha attribute, you can also use an RGB value with alpha (e.g. #00000066) in the input, or you switch from “Hex” to “RGB” or “HSL”, where you would have an alpha channel range setting.

The PanelColorSettings

There is currently no documentation for the PanelColorSettings component, but this is how you would use it:

import { useState } from 'react';
import { PanelColorSettings } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';

export const MyPanelColorSettings = () => {
	const [ textColor, setTextColor ] = useState( { color: '#000' } );
	const [ backgroundColor, setBackgroundColor ] = useState( { color: '#fff' } );

	return (
		<PanelColorSettings
			__experimentalIsRenderedInSidebar
			title={ __( 'Color' ) }
			colorSettings={ [
				{
					value: textColor.color,
					onChange: setTextColor,
					label: __( 'Text' ),
				},
				{
					value: backgroundColor.color,
					onChange: setBackgroundColor,
					label: __( 'Background' ),
				},
			] }
		/>
	);
};

In the colorSettings object, you can set multiple colors. In this example, we have one for a text and background color. This is how it would render:

PanelColorSettings showing the modal to select a color, with the colors from the theme and core default colors listed on the left, and the "Text" and "Background" color settings on the right.

As you can see here, the PanelColorSettings will not show a generic color picker, like the ColorPicker would do. Instead, it will present you with the color presets from the theme and from Core, depending on how these color settings are defined in the theme.json file.

Conclusion

Implementing a color picker was never easier, than with the native HTML input type. No more need to add a heavy jQuery/JavaScript library. Unless you want to use a color picker inside a WordPress project and also use the color palette from the theme. Then you can use the components from the block editor. They also have the benefit, that they render in the same way in any browser and any OS.

If you need a quick color picker for some random use case, you could also just google for “color picker”. 😉

How to fix sticky headers

You all know these websites with a sticky header, right? They have a horizontal navigation at the top, often with the site logo on the left – which is also often way too big, so not too many navigation items fit beside them. And then you scroll down these pages with this large header … and the header does not scroll off the page. Many people want that for their own website, but many people using this page don’t like it as much. I’m one of them.

Issues with sticky headers

There are multiple issues with such a sticky header. While there are valid reasons to have them, most of the time they are used for the wrong reasons – like website owners always want to see their logos or important navigation items. In my opinion: if people need to use your main navigation to find things, you are doing content wrong on your site. But what are the actual issues?

Issue 1: Elements appear behind or before the sticky header

Sure, when your website is designed with a sticky header, it probably pushed the content down. But since the sticky header needs to above the content when scrolling down, it might also cover some content that you can’t interact with anymore, like a popup that has the close button in the top right and that is now behind the header. And since often with popups, you can’t scroll the page while they are open, you can’t hit that closing button.

But you could also have issues with content that appears before the header, when you scroll down the page. That happens quite often with embedded elements, like a video, PDF or map embed.

Issue 2: Anchor links don’t work anymore

When you use an anchor link to navigate to parts of your site – which is really popular on “one pager websites”. Such an anchor element scrolls the website down (or up) so that the element is at the top of the page. And then it is behind your header.

Issue 3: Too little vertical space

When those headers are really high, you end up having not too much vertical space left on the page to view the content.

Let’s take an 11″ laptop with 720px height. Not as uncommon as you might think. Then we calculate the available vertical height:

  • Total: 720px
  • Windows taskbar: 66px
  • Chrome tabbar: 40px
  • Chrome address bar: 48px
  • Chrome bookmark bar: 34px

That leaves us with just 532px remaining vertical space. And now reduce this by another 60px only – that is about the current height of the header on my blog, which is really not high. This leaves you with only 472px of available space. And have we talked about those sticky cookie banners at the bottom already? That’s about the space that many of us have in landscape mode on our phones, and who really enjoys browsing a website in landscape mode?

Solutions

There are multiple solutions for the issues mentioned. Here are some that might work in your cases.

Issue 1

If a single (type of) embedded element is overlapping your header, you have to find a good z-index value for this element and overwrite it. Or you increase the z-index value of your header. But this can the lead to the issue with elements behind your header. You probably end up trying around with many manual z-index changes for multiple elements and still you find some elements that don’t appear as you want them to.

Issue 2

Most websites use some CSS like this to make a header sticky and move the content down:

.fixed-header {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 999;
}
html {
    margin-top: 60px;
}

Something like this would work for my header. It’s also what WordPress does, when it shows the “adminbar”. But it’s not the best solution to create a sticky header.

There is a relatively new value sticky for the position CSS property, and this is how the CSS code for a sticky header would look like with this new value:

.fixed-header {
    position: sticky;
    top: 0;
}

The great thing about it: the header does not need to be the first/top element on the page. You could have a logo, followed by the sticky header, and once that header reached the top of your browser viewport when scrolling down, it “sticks” to the top. In the past, this was only possible by toggling the position to fixed with JavaScript, and adding the margin-top at the same time. But now, modern browsers can do this kind of effect automatically.

No matter how we make our header sticky, we still have the issue with anchor links not working. The margin of 60px will not push any element down by that value, but only the beginning of the body.

To solve this, you could use an additional CSS property, to add an offset for the scrolling to the anchor like this:

html {
    scroll-padding-top: 60px;
}

This additional scroll-padding-top should get a value of at least the height of the header. And here you see another issue with this solution: if the header height changes, e.g. when the items don’t fit into one line anymore and break into two lines, then those static values don’t work anymore. You could now add some JavaScript to dynamically update these two values, but that’s not a great solution.

Issue 3

My favorite solution for this issue: just don’t use a sticky header. It also solves all the other issues. No, seriously. Does your header really need to be sticky? Does it make your website more usable? Can people read your content better or even find their way around? Please think twice before making a header sticky, and not just “because you like it that way”.

So in case you really need to make it sticky, there are some ways to make you website more usable:

  • Reduce the height of the header, once your site scrolls down – this is what many themes do, and they often also shrink the logo
  • Hide the sticky header after some scrolling, and show it again, once you scroll up – many apps do that for sticky header and footer bars
  • Make the header “not sticky”, if you detect a too low viewport height or if a device is in portrait mode

Conclusion

Some people love sticky headers, other hate them. You have to decide for yourself, if you want to have them. But please do one thing: don’t only test your website on your large desktop/laptop screen. Grab your smartphone and browse your website in landscape mode. Do you still think a sticky header is a good idea? Then use the techniques mentioned above to solve the usual issues with them.

Fun with numbers in JavaScript

No, I’m not going to start a video channel on this topic. But I want to show you some things about numbers, you might not have known before. The answer, however, as we all know, is 42.

Types of numbers

Let start with the very basics. You probably all know that in JavaScript, just like in many other programming languages, there are decimal number and floating-point numbers. But internally, they are all of the type Number. They are 64-bit, which should usually be enough for most code. But if you need really large numbers, you can also use BigInt to store them.

Some lesser known number types

Now that we know, that all (small) numbers are of type Number, we only know parts of the truth. We can have more than just two types. Here are the two typical ones, and some more, you might not have heard of or used in JavaScript:

42 // decimal
42.0 // float
042 // octal => 34 decimal - as digits after leading zero(s) are <= 8
099 // not octal, decimal 99, as digits after leading zero(s) are > 8
0o42 // explicit octal number - either lower- or uppercase latin "o"
0x42 // hexadecimal => 66 decimal - either lower- or uppercase latin "x"
0b101010 // binary 42, nice sequence ;) - either lower- or uppercase lat. "b"
0.042e3 // exponential number 42 - either lower- or uppercase latin "e"
42n // BigInt 42 - decimal followed by latin lower- "n" even for small number

Comparing numbers

As we have discussed earlier, except for BigInt, all numbers are the same type. Therefore, comparing the following numbers, these are the results:

42 === 42.0 // true
042 === 42 // false
0o42 === 34 // true
042 === 34 // true
099 === 99 // true
0x42 === 66 // true
42 === 0b101010 // true
42 === 0.042e3 // true
42n === 42 // false
42n == 42 // true

That last one might be (a bit) unexpected. So when comparing a BigInt to any other number, you cannot use the “strict equality operator”, since the numbers are of a different type.

If you want to find out, if a number is an integer, you can use a function from the Number object:

Number.isInteger(42) // true
Number.isInteger(42.001) // false
Number.isInteger(42.0) // true
Number.isInteger(42.000000000000001) // true

As you can see, this function will return true, if the number is an integer, or a floating-point number with a zero fraction – or a really small fraction. Unfortunately, there are no similar functions to check for other number types.

Now some fun part

Do you need some very long numbers in your code? Then you probably end up with something really hard to read. But there is a neat little trick to make them more readable:

// That's a huge number!
let rubiksCubeConfigurations = 43252003274489856000;
// As a string, it's easier to read, but this is bad code!
let sameNumberAsString = parseInt("43252003274489856000");
// How about this?
let easierToRead = 43_252_003_274_489_856_000;

That’s more readable, right? The funny thing is, that you can use an underscore at any place, just not at the beginning or end of the number, not after a leading zero, and not two underscores in a row. But many of us will probably use them like shown above.

Bonus: Formatting numbers

Now that we have seen how to make numbers more readable in code, here is a tip to make them easier to read for people from different countries. In the US, you would write a number like this: “123,456.789”. But in Germany, you would write “123.456,789”. If we look at the Number object again, we will find the toLocaleString() function, and this is how you can use it:

const number = 1234567.89;
// German
console.log(number.toLocaleString("de")); // 1,234,567.89
// English (United States)
console.log(number.toLocaleString("en-US")); // 1,234,567.89
// Englisch (India)
console.log(number.toLocaleString("en-IN")); // 12,34,567.89
// Ukrainian
console.log(number.toLocaleString("uk")); // 1 234 567,89
// Dzongkha
console.log(number.toLocaleString("dz")); // ༡༢,༣༤,༥༦༧.༨༩

Would you have known, how numbers are formatted in different languages? And in some languages, JavaScript will even output them with non latin letters. The same function can also be used to format currencies:

const costs = 123.4567;
// German with EUR
console.log(
    costs.toLocaleString("de-DE", { style: "currency", currency: "EUR" }),
); // 123,46 €

Conclusion

There are many really useful trick then dealing with numbers in JavaScript. I hope there was something for you, that will help you in a future project. I can also recommend to look at documentation of the other functions and features of the Number object.