A closer look at CSS functions
Tags: html, css
Published: 2020-11-23 17:06:07

---
title: A closer look at CSS functions
published: true
description: CSS functions are cool, but what can you do with them?
tags: html, css
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/y3nr2tp8mdp2lri6atod.jpg
---

## __Introduction__

CSS functions are used as properties for various CSS properties. In this article you'll learn about these functions, how they are used, when to use them,  if necessary, their "backup" approach (if the specific function is not supported by the browser). You'll also get links to other writings from around the web for further study. In the end, you'll have added to your CSS skills.

## __CSS function definition__

In most modern programming languages, a function is defined by writing the `function` keyword and specifying the name of the function followed by a pair of brackets (which can contain the function parameters), and curly that will contain the function definition.

An example of a function in JavaScript:

```js
function helloWorld() {
    console.log("Hello world, I am a function");
}

// Call the function
helloWorld(); // Hello world, I am a function
```

Unlike JavaScript (or other languages) where you can define _some_ function(s) (as shown above) before you can call them, CSS functions definition are written by browser vendors, you just need to call the function with the appropriate property and then pass the necessary arguments.

The syntax is given below:

```
property-name: <function name>(arguments)
```

Now, let's go into proper details and explanation. We will start by listing the functions followed by detailed explanation and code examples.

## __CSS functions__

The functions are listed below, they are arranged based on the likelihood of their usage in your projects. Click on the function name to jump to its explanation and browser support:

* [`url()`](#url)
* [`rgb()`](#rgb)
* [`rgba()`](#rgba)
* [`hsl()`](#hsl)
* [`hsla()`](#hsla)
* [`attr()`](#attr)
* [`linear-gradient()`](#linear-gradient)
* [`repeating-linear-gradient()`](#repeating-linear-gradient)
* [`radial-gradient()`](#radial-gradient)
* [`repeating-radial-gradient()`](#repeating-radial-gradient)
* [`calc()`](#calc)
* [`cubic-bezier()`](#cubic-bezier)
* [`var()`](#var)
* [`min()`](#min)
* [`max()`](#max)
* [`clamp()`](#clamp)

You'll also find [backup approach for RGB and HSL color functions](#rgbhsl-backup) and [backup approach for CSS gradients](#gradients-backup).

In addition, __the browser version under each browser support table is the first version of that browser to support that said property__.

### __`url()`<a name="url"></a>__

The `url()` function name is short for Uniform Resource Locator. It is used with CSS properties that loads an external resource (like an image or font file) that is used on the web page. Examples of such properties are:

* `src`
* `background-image`

The location of the file(s) is either on your local machine, another server on the same network, or the internet. Then you will have to specify the URL in any of the following format:

* Relative URL
* Absolute URL
* data-URI

#### __Relative URL__

A relative URL is used to reference file(s) that are in the same directory as the current working directory or in another directory on the same server. It is specified __without__ the server address.

When the Relative URL is used with the `url()` function, it takes the following form if the file is in the same directory as the CSS file:

```
url('file-location');
```

In the example below, CSS `background-image` property as indicated by the property name, is used to add a background image to a page. Here, the `url()` is using a Relative URL:

```css
.hero-section {
    background-image: url('image.jpg');
}
```

When the file is in a higher directory than the CSS file, you use `..`, which means _go up one directory_.

```
url('../file-location');
```

In the example below, `@font-face` has a `url()` using a Relative URL that goes up one level to get the font file:

```css
@font-face {
    font-family: "Catamaran-Bold";
    /**
     * Go up one level to the fonts folder and find the Catamaran
     * font inside the Catamaran folder.
     */
    src: url('../fonts/Catamaran/Catamaran-Bold.ttf') format('truetype');
}

/**
 * Now, the font can be used with the font-family property
 */
h1 {
    font-family: "Catamaran-Bold", Verdana, sans-serif;
}
```

If it's two directory up, you'll write `..`  twice separated by `/`, which means _go up one directory_, _and then another directory_:

```
url('../../file-location');
```

CSS code example for this format is given below, this time the URL goes up twice to fetch the image:

```css
.hero-image {
    background-image: url(../../image.jpg);
}
```

You should know that the double `..`  can be folder names

```
url('../my-assets/images/file-location')
```

Therefore, you can have a code example like the following:

```css
.hero-image {
    background-image: url(../my-assets/images/image.jpg);
}
```

#### __Absolute URL__

An absolute URL is _mostly_ used when referencing files on another server, but you can use it to reference files on your server. It takes the following form:

```
url('protocol://domain/path')
```

The protocol can be any of the following:

* `http://`
* `https://`
* `ftp://`
* `file://`

When used with the `url()` function, it takes the following form:

```
url('https://server-address/path-to-file');
```

In the following example, `url()` is using an Absolute URL to load the required resource for the `.hero-section`:

```css
.hero-section {
    background-image: url('https://server-address/images/image.jpg')
}
```

#### __data-URI__

A data-URI is used to specify a resource in `base-64` format or Scalable Vector Graphics.

```
url('data:resource-format');
```

The following example taken from MDN, is using a data-URI to fetch an SVG:

```css
.background {
    background: yellow;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='45'%3E%3Cpath d='M10 10h60' stroke='%2300F' stroke-width='5'/%3E%3Cpath d='M10 20h60' stroke='%230F0' stroke-width='5'/%3E%3Cpath d='M10 30h60' stroke='red' stroke-width='5'/%3E%3C/svg%3E");
}
```

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 1      | 1       | 12   | 3.5   | 1      | 3                 |


### __`rgb()`<a name="rgb"></a>__

This function name is taken from RGB which stands for Red, Green, and Blue. Therefore, this function defines a color using the RGB model.

It accepts three comma-separated values either as _integer_ values between `0` and `255` or percentage values between `0` and `100%`. These values specify the intensity of the color.

With the previous information, it's evident that `rgb()` only works with CSS properties that is used to apply color to a web page element. Examples of such properties are:

* `background-color`
* `box-shadow`

Its syntax is:

```
rgb(<red value>, <green value>, <blue value>);
```

The color of `box-shadow` is specified using  `rgb()`:

```css
.media-card {
	box-shadow: 0 2px 4px rgb(0, 0, 0); /* Black */
}
```

You can rewrite the previous examples to use percentage values:

```css
/**
 * Note the percentage values.
 */
.media-card {
    box-shadow: 0 2px 4px rgb(0%, 0%, 0%); /* Black */
}
```

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 1      | 1       | 4.0  | 3.5   | 1      | 11.0              |

### __`rgba()`<a name="rgba"></a>__

On a normal day, the background color of the next selector should be Black, but due to the alpha transparency value of `0`, it turns out White.

```css
/**
 * Note the alpha transparency value
 */
body {
  background-color: rgba(0, 0, 0, 0);
}
```

Similar to `rgb()`, it works with CSS properties that applies colors to a web page element. An example is the `background-color` demonstrated above.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 1      | 3.0     | 9.0  | 10.0  | 3.1    | 11                |

### __`hsl()`<a name="hsl"></a>__

HSL stands for _Hue Saturation Lightness_ which is another model for defining a color. The function `hsl()` defines colors using this model.

Its syntax is:

```
hsl(hue, saturation, lightness);
```

Where:

* `hue` &mdash; The degree of the color on a color wheel. The color wheel is a circle measured in `360deg`. On the circle `0` (or `360`) is Red, `120` is Green, `240` is Blue.
* `saturation` &mdash; The intensity of the color where `0%` represents shade of gray and `100%` is the full color.
* `lightness` &mdash; The value or tone of the color. `0%` represents Black, `50%` is normal, and `100%` is White.

Let's create a variant of green color with a bit of lightness:

```css
body {
    background-color: hsl(120, 20%, 70%);
}
```

I'll advise that you should experiment with other values for better understanding and fun.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 1.0    | 1.0     | 9.0  | 9.5   | 3.1    | 9.0               |

### __`hsla()`<a name="hsla"></a>__

Same as `hsl()` with the addition of the _alpha transparency_. As a reminder, the _alpha transparency_ specifies the opacity of the color.

```css
body {
    background-color: hsla(120, 20%, 50%, 0.3); /* Super light green */
}
```

#### __Backup approach for RGB and HSL color  functions <a name="rgbhsl-backup"></a>__

For browsers that do not support the RGB and HSL color functions, you can use _hexadecimal_ notation or the _direct_ color name in-place of these functions for properties that use them as part of the values:

```css
.media-card {
    box-shadow: 0 2px 4px #000000; /* Black */
}
```

But if you use any of the function to specify a color as such:

```css
body {
    background-color: rgb(120%, 79%, 21%);
}
```

You should provide the same color (or another) in a _hexadecimal_ notation or its _direct_ name as a value (or part of the value) of the property, afterwards, you declare the same property again using the RGB or HSL color functions, therefore, for browsers that do not support the RGB or HSL color functions, the _cascade_ will kick in and the browser will use the latter declaration.

```css
body {
    background-color: #ffc936;
    background-color: rgb(120%, 79%, 21%);
}
```

### __`attr()`<a name="attr"></a>__

The HTML attribute of an element are returned by the `attr()` function. Furthermore, you can attach or place this attribute on a selected element.

This function is mostly used with CSS `content` property.

```css
/**
 * Insert the Image alt attribute after the
 * image itself.
 */
.media-card__image::after {
    content: attr(alt);
}
```

The following example taken from W3Schools will insert the value of the `href` attribute after each link:

```css
a:after {
  content: " (" attr(href) ")";
}
```

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 2      | 1.0     | 8.0  | 9.0   | 3.1    | 8.0               |


### __`linear-gradient()`<a name="linear-gradient"></a>__

Gradients in CSS gives you the opportunity to display smooth transitions between two or more specified colors. There are two types:

* Linear Gradients &mdash; Goes down/up/left/right/diagonally and represented by the `linear-gradient()` function (discussed next).
* Radial Gradients &mdash; They are defined by their center and represented by `radial-gradient()` function.

This `linear-gradient()` function sets a linear gradient as the background image of the selected element. Its syntax is:

```
background-image: linear-gradient(direction, color-stop1, color-stop2, ...);
```

The `direction` value can be any of the following:

#### __Top to bottom (default) <a name="top-to-bottom"></a>__

The following example starts at the top and ends at the bottom. It starts Black, transitioning to White:

```css
body {
    background-image: linear-gradient(black, white);
}
```

#### __Left to right <a name="let-to-right"></a>__

As the name indicates, the gradient starts goes from left to right using the following keywords:

* `to`
* `right`

The following gradient starts Blue, transitioning to Red.

```css
body {
    background-image: linear-gradient(to right blue, red);
}
```

#### __Diagonal <a name="diagonal"></a>__

You can create a gradient by stating the horizontal and vertical starting positions. In pseudo-code,  some examples are:

* _to bottom right_
* _to bottom left_

The following gradients start at top left and ends at the bottom right.

```css
body {
    background-image: linear-gradient(to bottom right blue, red);
}
```

You can also use _angles_ to specify the direction of the gradient, this gives you more control over the direction of the gradient:

* `0deg` is equivalent to `to top`
* `90deg` is equivalent to `to right`
* `180deg` is equivalent to `to bottom`

__Code examples on how to do this is left as an exercise to the reader__.

Note that you are __not limited to just two colors__, you can use multiple color stops as shown in the example below:

```css
body {
    background-image: linear-gradient(to bottom right, blue, red, aqua);
}
```

In addition, you can also specify the color using the `rgba()` function, then you can use the _alpha transparency_ to create a fading effect. As stated earlier:

> The _transparency value_ is a number between `0.0` (fully transparent) and `1.0` (fully opaque).

```css
body {
    background-image: linear-gradient(to bottom right, rgba(124,65,89,0), #1560bd, rgba(255,0,0,1));
}
```

The `#1560bd` above is a hexadecimal color notation which is another way to specify the color. How will it look like in a browser? Well, if the webpage is blank (why would you have a blank page?), it might not look good:

![A web page with linear gradient](https://dev-to-uploads.s3.amazonaws.com/i/e1n4qohb9at42v4v9isp.png)

If the web page contains enough content the effect might look compelling:

![A data table with linear gradients](https://dev-to-uploads.s3.amazonaws.com/i/o1gk8k2qmt5egj5r0y6b.png)

#### __Browser Support__

| Chrome              | Firefox         | Edge | Opera          | Safari            | Internet Explorer |
| ------------------- | --------------- | ---- | -------------- | ----------------- | ----------------- |
| 26.0, 10.0 -webkit- | 16.0, 3.6 -moz- | 12.0 | 12.1, 11.1 -o- | 6.1, 5.1 -webkit- | 10.0              |

### __`repeating-linear-gradient()`<a name="repeating-linear-gradient"></a>__

As the name implies, this function is used to repeat linear gradients.

Its syntax is as follows:

```
 background-image: repeating-linear-gradient(angle | to side-or-corner, color-stop1, color-stop2, ...);
```

Where:

* `angle` &mdash; Direction of the gradient from `0deg` to `360deg`, default is `180deg`.
* `side-or-corner` &mdash; Two keywords (both optional) that defines the starting-point of the gradient line. The first indicates the horizontal side (left or right) and the second indicates the vertical side (top or bottom).
* `color-stop1`, `color-stop2`, `...` &mdash; The colors you want to render smooth transitions among followed by an optional stop position which is a percentage value between `0%` and `100%` or a length along the gradient axis.

An example is given below:

```css
/**
 * The gradient starts at 75deg and uses 3 color stops.
 * The second color covers just 7% along the gradient.
*/
body {
    background-image: repeating-linear-gradient(75deg, rgba(124,65,89,0), #1560bd 7%, rgba(255,0,0,1) 10%);
}
```

#### __Browser Support__

| Chrome              | Firefox         | Edge | Opera          | Safari           | Internet Explorer |
| ------------------- | --------------- | ---- | -------------- | ---------------- | ----------------- |
| 26.0, 10.0 -webkit- | 16.0, 3.6 -moz- | 12   | 12.1, 11.1 -o- | 6.1, 5.1 -webkit | 10.0              |

### __`radial-gradient()`<a name="radial-gradient"></a>__

This function sets a radial gradient as the background image of a web page element. A radial gradient starts at the center of the selected element and you __must__ define at least two color stops.

The syntax is:

```
 background-image: radial-gradient(shape size at position, start-color, ..., last-color);
```

Where:

* `shape` &mdash; The shape of the gradient. _ellipse_ is the default, the other being a _circle._
* `size` &mdash; Size of the gradient with _farthest-corner_, _closest-side_, _closest-corner_, and _farthest-side_ as possible values.
* `position` &mdash; Position of the gradient. Default is `center`.
* `start-color`, `...`, `last-color` &mdash; The colors that you want to render smooth transitions along which is a color value followed by an optional stop position (a percentage value between `0%` and `100%` or a length along the gradient axis).

A basic example of a radial gradient with three color stops is given below:

```css
body { 
    background-image: radial-gradient(#1560bd, #cccccc, #1a1a1a);
}
```

In the code snippet above, the gradient starts with `#1560bd` (blue) at the center, followed by `#cccccc` (gray) around it, then `#1a1a1a`  (black) completes the gradient. The result is an _ellipse_ (which is the default) with three _rings_ of colors as defined by the color stops.

You can change the _ellipse_ if you want to. The code snippet below will result in a _circle_ because we changed the shape of the gradient before defining the color stops:

```css
body {
    background-image: radial-gradient(circle, #1560bd, #cccccc, #1a1a1a);
}
```

Furthermore, you can also define the size of the gradient. The size determines how _big_ or _small_ the gradient will be from its center. When you use the value `closest-side` the gradient appear small at the center of the selected element.

```css
body {
    background-image: radial-gradient(circle closest-side, #1560bd, #cccccc, #1a1a1a);
}
```

__You should experiment with other values__, i.e. _farthest-side_, _closest-corner_ e.t.c.

Currently, the gradient is at the center, you can move it to the left or right if you wish. If you'd like to move it to the left, you'll have to ensure the `position` value is __less than__ `50%`. In the snippet below, the gradient will appear to the left of the selected element because `position` is reduced to `26%`:

```css
body {
    background-image: radial-gradient(circle closest-side at 26%, #1560bd, #cccccc, #1a1a1a);
}
```

If you'd like to move the gradient further to the right, increase the `position` value above `50%`. Try `86%`.

Mind you, the `position` value can be specified as two values, the first value represents the _x-axis_ (horizontal) and the second value is the `y-axis` (vertical). 

In the code snippet below, the gradient is moved `40%` from the left of the selected element and `30%` from the top:

```css
body {
    background-image: radial-gradient(circle closest-side at 40% 30%, #1560bd, #cccccc, #1a1a1a);
}
```

#### __Browser Support__

| Chrome              | Firefox         | Edge | Opera          | Safari            | Internet Explorer |
| ------------------- | --------------- | ---- | -------------- | ----------------- | ----------------- |
| 26.0, 10.0 -webkit- | 16.0, 3.6 -moz- | 12   | 12.1, 11.6 -o- | 6.1, 5.1 -webkit- | 10.0              |

### __`repeating-radial-gradient()`<a name="repeating-radial-gradient"></a>__

This function behaves similarly to `radial-gradient()`repeats the radial gradient with one exception &mdash; it repeats the radial gradient.

You can convert the last code example to use a `repeating-radial-gradient()`:

```css
body {
    background-image: repeating-radial-gradient(circle closest-side at 40% 30%, #1560bd, #cccccc, #1a1a1a);
}
```

The gradient is now repeated until it fills the entire area of the selected element.

#### __Browser Support__

| Chrome              | Firefox         | Edge | Opera          | Safari           | Internet Explorer |
| ------------------- | --------------- | ---- | -------------- | ---------------- | ----------------- |
| 26.0, 10.0 -webkit- | 16.0, 3.6 -moz- | 12   | 12.1, 11.1 -o- | 6.1, 5.1 -webkit | 10.0              |

#### __Backup approach for CSS Gradients <a name="gradients-backup"</a>__

Use `background-color` has a backup for browsers that might not support CSS gradients.

```css
body {
    background-color: black;
    
    /* Specify CSS gradients here */
}
```

### __`cubic-bezier()`<a name="cubic-bezier"></a>__

As the name implies, this function defines a Cubic Bézier curve. Wikipedia defines a Bézier curve as:

> a parametric curve used in computer graphics and related fields.

A Bézier curve is defined by four points `P0`, `P1`, `P2`, `P3` where `P0` and `P3` are the start and end points.

In CSS, these points are fixed coordinates where:

* `P0` is `(0, 0)` &mdash; initial time and initial state
* `P3` is `(1, 1)` &mdash; final time and final state

The `cubic-bezier()` function is used with animation related properties in CSS for defining the speed of the animation. Some of these properties are `animation-timing-function` and `transition-timing-function`. Its syntax is:

```
cubic-bezier(x1,y1,x2,y2);
```

Where:

* `x1, y1, x2, y2` are required numerical values. `x1` and `x2` must be a number from `0` to `1`.

The example below is a modified version of an example on W3schools, the animation will start slow and will speed up towards the end.

```css
div {
    width: 100px;
    height: 100px;
    background: red;
    transition: width 2s;
    transition-timing-function: cubic-bezier(.32,.3,.9,.21)
}

div:hover {
    width: 300px;
}
```

Here is the HTML (without the metadata):

```html
<p>Hover over the div element below, to see the transition effect.</p>
<div></div>
```

There is an online tool by Lea Verou used for creating the Bézier curve values. Visit it at [cubic-bezier.com](https://cubic-bezier.com/).

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 4.0    | 4.0     | 12   | 10.5  | 3.1    | 10.0              |

### __`calc()`<a name="calc"></a>__

The `calc()` function performs mathematical calculation using the expression it receives as an argument. This expression can be simple or complex if need be, as long as it's a valid expression, the function will compute it and the result will be used as the property value.

The syntax is:

```
calc(expression)
```

In the example below, the font size is calculated using `calc()`:

```css
/**
 * 1rem is 16px,
 * 0.2em is (16px * 2) which is 3.2px
 * Finally, 16px + 3.2px gives 19.2px
 */
p {
    font-size: calc(1rem + 0.2em); 
}
```

The calculation in the code snippet above assumes the browser default font size is `16px` (this is easily changeable by the user).

#### __Browser Support__

| Chrome              | Firefox         | Edge | Opera | Safari           | Internet Explorer |
| ------------------- | --------------- | ---- | ----- | ---------------- | ----------------- |
| 26.0, 19.0 -webkit- | 16.0, 4.0 -moz- | 12   | 15    | 7.0, 6.0 -webkit | 9.0               |

### __`var()`<a name="var"></a>__

When you declare a CSS variable in your stylesheet, the `var()` function is used to insert the value of the variable later in the stylesheet.

Its syntax is:

```
var(name, value)
```

Where:

* `name`  &mdash; Required.  The name of the variable that must start with two dashes `--`.
* `value` &mdash; Optional fallback value that is used when the variable is not found.

First declare the variable as _global_ variable:

```css
:root {
    --border-color: #1560bd;
    --background-color: #cccccc;
}
```

Then you can use the variable value via the `var()` function:

```css
main {
    border: 2px solid var(--border-color);
    background-color: var(--background-color);
}
```

You can provide fallback values if the variable is not found:

```css
main {
    border: 2px solid var(--border-color, #1560bd);
    background-color: var(--background-color, #cccccc);
}
```

To make things easy, the fallback values are the variable values declared in the `:root` element. You can use other values depending on the theme of your website.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 49     | 31      | 15.0 | 36.0  | 9.1    | No Support        |

### __`min()`<a name="min"></a>__

The `min()` function is part of CSS logical operators (others being [`max()`](#max) and [`clamp()`](#clamp)) that allows you to provide a list of values as arguments and the browser will determine which one is the smallest and it will use this as the actual value at any given time.

It allows you to specify multiple values as arguments but two values is easiest to understand. Take a look at the following code snippet:

```css
main {
    width: min(1000px, 500px);
}
```

Here, we have `main` width set to `min(1000px, 500px)`, at any given time the browser will set the width of `main`  as `500px` because it's always smaller than `1000px`.

Now, let's tweak the values:

```css
main {
    width: min(1000px, 70%);
}
```

Here, at a larger viewport that is more than `1000px`, the browser will set the width of `main` as `1000px` because at that point the width has exceeded what the browser will compute as `70%` of the viewport and automatically `1000px` becomes the minimum value and the browser will use it as the actual width of `main`.

Have a look at the following GIF and take note of the computed width:

![Browser developer tools opened](https://dev-to-uploads.s3.amazonaws.com/i/5vtkfapwsd6mjypm3ahk.gif)

I had to increase and decrease the zoom level so that you can notice when the browser sets the `main` width to `1000px`.

At a smaller viewport, where `1000px` is more than `70%`, the browser will set the width as `70%` because at that point `70%` is the minimum value compared to `1000px`.

With that out of the way, you should know that you can write `min(1000px, 70%)` as:

```css
main {
    width: 70%;
    max-width: 1000px;
}
```

Effectively this means `max-width` use `min()` behind the scenes. But which one should you go for? 2 lines of code with `width` and `max-width` or 1 line of code with `min()`? I'll leave that you.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 79     | 75      | 79   | 66    | 11.1   | No Support        |

### __`max()`<a name="max"></a>__

This is the opposite of `min()`. As it selects the maximum value from the list of supplied arguments which the browser will use as the actual value.

Using our previous example, let's switch the function name to `max()`:

```css
main {
    width: max(1000px, 70%);
}
```

Here, the width of `main` will be a minimum of `1000px`, but as the computed value of `70%` increases beyond `1000px` the browser will always use that computed value as the actual width of `main`.

In the GIF below, `1000px` is the minimum value therefore, the browser will use it at that viewport size, but when the zoom level is increased (thus imitating an increase in viewport size) the actual width of `main` starts to grow:

![Browser developer tools opened](https://dev-to-uploads.s3.amazonaws.com/i/eigcgjy9aqmy9xrbz9i0.gif)

You should note that `max(1000px, 70%)` is almost the same as:

```css
main {
    width: 1000px;
    min-width: 70%;
}
```

This also means that `min-width` use `max()`.

Please, note the following for `min()` and `max()`:

* The order in which you write the arguments does not matter, the functions will select either the smallest or largest value as the actual value of the property.
* You can supply more than 2 values as the arguments for both functions.
* `min()` allows you to impose a maximum value since it selects the smallest of values and the browser won't allow the value to exceed this value hence that is the _maximum_ it will go.
* `max()` allows you to impose a minimum value since it selects the biggest of values and the browser will use the smallest value first and if condition permits it will keep growing more than this _minimum_ value.
* You can perform mathematical calculation inside `min()` and `max()` without using `calc()`. e.g. `min(1000px + 10px, 70%)`.

Now, the question is: What if you want a value in-between a maximum and minimum value? You'll have to resolve to `clamp()`.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 79     | 75      | 79   | 66    | 11.1   | No Support        |

### __`clamp()`<a name="clamp"></a>__

With the `clamp` function, you can set a minimum and maximum values and in-between those values, an _ideal_ value. The browser will use the computed ideal value when it's larger than the minimum value but smaller than the maximum value.

This is effectively setting a `width`, `min-width`, and `max-width` property on an element all at once.

In the code example below, the browser will use `500px` because its computed value is larger than `5em` which is the minimum value but smaller than the maximum value of `50em`:

```css
main {
  width: clamp(5em, 500px, 50em);
}
```

When you tweak the values as follows:

```css
main {
  width: clamp(600px, 500px, 50em);
}
```

Here, `600px`  is larger than the ideal value of `500px` therefore, the browser will use it as the actual value of the `width` property.

You can write the previous code is:

```css
main {
    width: 500px;
    min-width: 600px;
    max-width: 50em;
}
```

Kindly note that the `clamp()` function accepts 3 values, anything less or more is __invalid__.

#### __Browser Support__

| Chrome | Firefox | Edge | Opera | Safari | Internet Explorer |
| ------ | ------- | ---- | ----- | ------ | ----------------- |
| 79     | 75      | 79   | 66    | 13.1   | No Support        |

## __Conclusion__

In this article you've learned about CSS functions in great detail. I'll encourage you to experiment further to deepen your CSS skills. In a future article we'll look at some practical applications of some of these functions. Thanks for reading.

## __References__

* 📚 [Firefox 75: Ambitions for April](https://hacks.mozilla.org/2020/04/firefox-75-ambitions-for-april/)
* 📹 [min(), max(), and clamp() are CSS magic!](https://www.youtube.com/watch?v=U9VF-4euyRo)
* 📚 [CSS values and Units Module Level 4: Comparison Functions: min(), max(), and clamp()](https://drafts.csswg.org/css-values-4/#comp-func)
* 📚 [What is the difference between an absolute and relative URL](https://kb.iu.edu/d/abwp)

## __Further reading__

* 📚 [min(), max(), and clamp(): three logical CSS functions to use today](https://web.dev/min-max-clamp/)
* 📚 [Everything I Learned About min(), max(), clamp() In CSS](https://ishadeed.com/article/css-min-max-clamp/)
* 📚 [A guide to the `min()`, `max()`, and `clamp()` CSS functions](https://blog.logrocket.com/min-max-clamp-css-functions/)

## __Credits__

All browser support table is courtesy of [W3Schools](https://w3schools.com) and [MDN](https://developer.mozilla.org/en-US/docs/Web).

Cover photo is by [Maik Jonietz](https://unsplash.com/@der_maik_) on [Unsplash](https://unsplash.com/).