Checkout my Getting Started with React video course on Skillshare. It is 100% free.

Making CSS responsive with the clamp, min and max functions

The clamp, min, max functions are a trio of CSS functions that can make our life easier when working with a responsive design. They make sure the increase or decrease in size never goes beyond some limits.

Let's start with the clamp function. It takes three parameters:
-> the minimal value
-> the preferred size
-> the maximum size

So, for example, if we say:

.my-element {
    width: clamp(300px, 50%, 800px)

Then .my-element will try to be always 50% of its parent's width, but will never go under 300px or more that 800px.

It can be very useful when working with font sizes. In a responsive context, it's great to be able to use the viewport units with font sizes. This will mean that when our screen is getting smaller also our font size will decrease. But the font can become too small to read on small screens.

So the clamp function to the rescue! We use a statement like the one below to make sure our font size will always be readable and also responsive.

.my-resposive-readable-text {
    font-size: clamp(12px, 3vw, 24px);

Alongside with clamp, we have two other complementary functions.

The CSS 'min()' function will take two parameters are will return the smaller one to be used as a size.

So, if we have:

.widget {
    width: min(20rem, 80%)

Then the .widget component will be the smallest of the two values from 80% of its parent or 20rem.

The max() function will behave the same, just that it will select the biggest value.

One nice thing about all of these functions is that you don’t need a calc() function to do math inside.

We can just write max(20vw - 1rem, 10% + 40px) and it will work. Just be sure to leave an empty space before and after the operator sign.

Of course, all the time when we use the min() or max() functions we will need to use different units types. Writing something like min(10%, 25%) it's nonsense as 10% will always be the smaller value.

Kevin Powel has a nice video explaining more about these functions:

Replacing console logs with debugger; and using conditional breakpoints

If you are like me and still slipping back to the nasty habit of using too much the console.log(); statements for debugging in Javascript this video was of real help.

Something did not feel natural for me to go in the devtools, find the troublesome block of code and add there a breakpoint.

Being in the code editor all the time, was much more easy just to drop a few console.log() statements in there. More easy yes, but for sure not more productive.

But it turns out that if you drop a debugger; statement (min 1.20 in the video) it triggers the breakpoint with full access to the debugging tools.

javascript debuger statement

Another cool trick in the video is are the usage of the conditional breakpoints (min 3.00) from the dev tools.

But you can use this that also with the debugger; as well:

for (let counter = 1; counter < 10; counter++) {
    // more complex code here
    if (foo === 5) {
        // activate the brekpoint only  when foo is 5

So, welcome debugger and bye-bye console.log().

Using the new two-value syntax of the display property in CSS

Changes are coming to one of the core properties in CSS: the display property. We will be able to define how our elements are behaving when relating to their children and how they relate to their siblings.

The new syntax of the display property will accept two parameters <display-outside> and <display-inside>.

For example, when we are saying display: grid we are basically saying two things:

  • this element is a grid for its children
  • and this element is a block for its siblings

So the full declaration can be display: block grid.

The same with display inline-grid. It is a grid for its children and an inline for its siblings. So with the new syntax, it will become display: inline grid.

In this Web docs Mozilla article we have the following table describing the correspondence between the old and new syntax.

Current value New value
block block flow
flow-root block flow-root
inline inline flow
inline-block inline flow-root
flex block flex
inline-flex inline flex
grid block grid
inline-grid inline grid

As a general rule if a <display-outside> value is specified but <display-inside> is omitted, the element’s inner display type defaults to flow.

So far only Firefox fully implements this new syntax but I am looking forward to more support as I think it provides a clearer description of how an element behaves.

If you want to read more and you can take a look at this great article or Rachel Andrew or the below video:

CSS Logical Properties

Create spacing that works regardless of the direction of your content or the environment of your users.

Say you want to put some space between two inline items: what do you do? Probably something like this:

.my-element {
    margin-left: 1em;

This approach is fine and has been for a long time with CSS, but what happens when the content direction changes? That left margin suddenly becomes problematic because it no longer matches and makes the content look awkward.

Western languages read left to right, but other languages such as Arabic, read right to left. Some languages even read top to bottom, like traditional Chinese.

Our CSS should be as flexible as possible, so instead of explicitly setting a left, right, top or bottom value to margins, we should instead be using a logical property.

Here’s that same example from the start, but with a logical property:

.my-element {
    margin-inline-start: 1em;

What this now does is instead of saying “add margin to the left”, it says “regardless of direction, put margin on the starting side”. If the language of the document was right to left, like Arabic, that margin would be on the right hand side.

Why is this important?

The web is global and open, so making presumptions about the users of your website is pretty dangerous.

A variety of factors come into play when someone visits your site, such as connection speed, device power and spoken language. They could also be using a translation extension. It’s our job as web developers to make our content as flexible as possible to meet user needs, regardless of what those needs are, using the powerful, flexible tools that are given to us by the web platform.

Logical properties are a perfect example of this and they have a huge browser support, so you should absolutely use them today.

Resources and further learning permalink

This is only a quick intro to logical properties, but luckily, some other fine folks from around the web have written about them in detail:

CSS Logical Properties - CSS-Tricks
CSS Logical Properties and Values - MDN
Understanding Logical Properties And Values
CSS Logical Properties - Adrian Roselli

Tagged template literals in Javascript

In ES6 the templated literals were added in Javascript. They are used to interpolate values in a string.

const name = 'Tom'
const age = 20;
const myString = `The name is ${name} and the age is ${age}.`;
myString is now "The name is Tom and the age is 20."
before  ES6 the templated literals we had to write:
myString = "The name is " + name + " and the age is " + age "."

So, this made things a bit more elegant when concatenating strings.

But we can do more than this. We can define tagged template literals. Basically, they are a combination of a tag function and a string template literal. What's returned from the tag function will determine the final format of the string.

Let's say we want to show a string like this one in the below picture.

The basic string literal will just alow use to write this:

const text = `${} is ${p.age} years old.`;

However, with the tagged template literals we can say:

const text = setHighlightTags `${} is ${p.age} years old.`;

We can name the tag function however we want. In our example the setHighlightTags is defined as:

function setHighlightTags(strings, ...values) {
   let str = '';
   strings.forEach((string, i) => {
       str += string;
          str += `<span class='hl'>${values[i]} </span>`;
   return str;

And the .hl CSS class has just some simple rules:

.hl {
    background-color: yellow;
    padding: 2px 10px;

And that's pretty much all we need. We can get more creative when we need it. There are libraries, like styled-components (React) or chalk (for colorful logs) that take this feature to the next level.

If you want you can read more about it here. Also, check out below the full codepen for this example:

See the Pen
by JS Craft (@js-craft)
on CodePen.

[Js-Craft #17] CSS Grid Screencasts, a new newsletter layout, CSS margin collapsing and more

Hello everybody,
I skipped sending the last newsletter because an unplanned vacation happened. Therefore I salute you from Greece 🇬🇷 🎉.

Also, I've decided to split this newsletter into three categories. The newly published screencasts, the new articles added on js-craft, and a new section with interesting links and resources I've found around the web. Let’s go!

# Two new screencasts to watch

I am happy to announce that I've started a new video series about CSS Grid. Through about 6 or so episodes we will build a fully responsive CSS grid layout. The first two new episodes are below:

# Six new articles to read

The new articles published on js-craft are:

# Three interesting links from around the web

That's all folks! I would be very happy to hear from you. So, if you have any feedback about this newsletter, the new CSS Grid video series or anything else please drop me an email at daniel [at]


6 things I didn’t know you can do in Javascript

The fact that JavaScript is such a flexible language makes it maybe the easiest language to start with and the hardest to master. I’ve been working with JavaScript for more than 10 years now and I still stumble upon some hidden syntax or tricks that I never knew existed.

So let's see some JS mysteries that I've recently discovered.

1. There is a function constructor. You will give it the parameters and the body of the function and it will return back the actual function :

const diff = new Function('a', 'b', 'return a - b');
diff(20,13) // 7

2. We have a with statement in Javascript. It takes as a parameter an object and binds the properties of that object to the scope of the contained code block.

const book = {
    author: 'Ernest Hemingway',
    title: 'The Sun Also Rises'
with(book) {
    console.log(author); // Ernest Hemingway
    console.log(title); // The Sun Also Rises

3. we can use the + operator to convert a string to a number. No more the need to use functions like parseInt() or parseFloat(), unless you want to parse to that specific numerical type.

const nr = +'1.5';
nr + 1; // 2.5

4. we can assign properties to functions. We can make configurable functions by assigning specific properties to that function.

function sayHello() {
    if ( = 'US') {
        return alert('Hi there!');
    if ( = 'FR') {
        return alert('Bonjour !');
    if ( = 'GR') {
            return alert('Guten Tag !');
    return alert('Hi');
} =  'FR';
sayHello(); // alert('Bonjour !');

Also, we can use these function properties as counters or "static variables".

5. we can use the arguments.callee.caller to see what function invoked the current function. The arguments var is a default of any js function. But we have the arguments.callee.caller that will tell us who called that function. Something like a console.trace() but just one level deep.

function sayHello() {
    alert(arguments.callee.caller); //start

function start() {

Also the arguments.callee refers to the currently running function.

6. we have a void operator. You give it anything and it returns back undefined.

void(1); // undefined
void(true); // undefined
void(false); // undefined
void({}); // undefined

You may ask yourself why you would want an operator like this one? Well because before ES5 you could actually assign a new value to the original undefined:

undefined = "abc";
x = undefined;
alert(x); // "abc"
// this will not work anymore
// but it explains why we have the void operator 

So ... Javascript the language where surprises never end!

CSS margin collapsing – what it is and why should I care

In CSS margin-collapsing refers to the fact that the margins that are next to each other are colliding… but only vertically.

Yeah, it's one of those brainfuck moments in CSS.

Let's first take two divs that are one next to each other on the horizontal axis. If we have a margin: 25px for both divs, and the width: 100px then, as expected, the required width will be 300px.

However, if we try to do the same with the divs are arranged vertically then the total needed space will be 275px, instead of the expected 300px.

And this is because the vertical margins of the elements are collapsing.

But, what if the margins are of different sizes? What if one div has margin: 25px and the other has a margin: 40px? Well, in this case just the largest of the two margins will be applied (40px in our case).

And what about negative margins? The rule will be applied when both margins are negative (vertically), but not when one margin is negative and the other is positive.

If you want to learn more take you can a look at:

Frontend links of the past few days

One of the most motivating reads of the past few days is Joel Hooks article My blog is a digital garden, not a blog. One of those pieces of content that makes you love your sleeves and get to work.

Also Lately, I've been spending quite some time browsing thought the CSS examples on codepen. There are a lot of interesting ones, but the following ones caught my attention in particular:

Using CSS Grid to make a Newspaper Layout

Maybe one of the most beautiful and complete examples of using CSS grid to build the full layout of a page. Great work Olivia. By the way, follow her on codepen. She has some wonderful CSS examples.

Airplanes - the beginners guide

Another fantastic showcase on how CSS cand be used for visual narratives. A real piece of art in my opinion.

Super Mario - CSS only

When I first saw this, I recoiled and thought: “there’s no way this is just CSS”. Even I should know by now, how powerful CSS has become, I am still amazed when finding examples like this one.