How to create a custom image uploader with preview
Tags: javascript, tutorial, css, html
Published: 2022-07-28 21:14:00

## Introduction

Creating a custom image uploader has nearly become a must as the default **HTML** `input type file` looks plain.
You will agree that modern web design demands more, and there seems to be no direct way to style it. However, the use of `::file-selector-button` CSS pseudo-element can be used but still has its limitations. In this article, I will show you how I created a **fully customized image uploader with preview** as shown below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhi9j2zm2cyksd25szri.gif)

### Creating an HTML `input` type File 
Create an HTML `input type file` with attribute `accept = “image/x-png, image/jpeg”`

```HTML
<input type="file"
   id="image-file"
   accept="image/x-png, image/jpeg"
/>
```
By adding the attribute `accepts` to the input type file, you specify the type of file you want the input to accept. In our case, we want it to accept image type `png` and image type `jpeg`.

Click on the input to open the file explorer. You will see that you can select images with _.png_ extension and images with _.jpeg_ extension only.

### Creating an HTML `label` Tag
Add a `label` tag and point the `label for` attribute to the `id` of the created input file.

```HTML
<input type="file"
  id="image-file"
  accept="image/x-png, image/jpeg"
 />
 <label for="image-file">Upload image</label>

```
By adding the `for` attribute of the `label` to the `id` of the `input`, clicking the `label` element behaves as if we clicked the `input` directly.

The outcome of the above is as shown below. We can click the Upload image text and see that it toggles the window file explorer, just as what the `input file` is doing.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrd23pewsfuw66u71485.gif)

### Hiding The Default `input`
Next is to hide the default `input` and `style` the `label` as you want.
Since we have a `label` that behaves exactly as our `input`, the next is to hide the default `input`. To hide the default `input`, we need to add a CSS `style` and set `display = none` to the `input` file tag.

```HTML
<input type="file"
  id="image-file"
  accept="image/x-png, image/jpeg"
  style="display : none"
/>
```

At this point, you now have a `label` you can `style` as you like. To `style` our `label`, add an `id` attribute to the `label` tag, then add the below `CSS` to give it a beautiful card-like custom `image` uploader.

```HTML
<label id="image-label" for="image-file">Upload image</label>
```

```CSS
   body{
      display: flex;
      justify-content: center;
   }
   #image-label{
      position: relative;
      width: 200px;
      height: 200px;
      background: #fff;
      background-position: center;
      background-repeat: no-repeat;
      background-size: contain;
      display:flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0px 1px 7px rgba(105, 110, 232, 0.54);
      border-radius: 10px;
      flex-direction: column;
      gap: 15px;
      user-select: none;
      cursor: pointer;
      color: #207ed1;
      transition: all 1s;
   }
   #image-label:hover{
      color: #18ac1c;
   }
```

Now that you have a completely customized image uploader, now is time to preview the selected image.

### Using Javascript to Get a Selected File From an `input` Type File
Next is getting the selected image and previewing it for the user
Now what I did is, in my JavaScript file, I listen to the change event on the `input` file, whereby whenever a change is made, it returns an array of one element which contains the information of the uploaded file(such as file name, file type, etc.).

```javascript
const input_file = document.getElementById('image-file');
input_file.addEventListener('change', async function(){
   const file = document.querySelector('#image-file').files;
   console.log("file", file)
   })
```

### Using Javascript to Convert File to BASE64 Encoded File.
Now that we can get the file, we need to convert the file to a base64 encoded file for our browser to understand the image

```javascript
const input_file = document.getElementById('image-file');
 
const convert_to_base64 = file => new Promise((response) => {
   const file_reader = new FileReader();
   file_reader.readAsDataURL(file);
   file_reader.onload = () => response(file_reader.result);
});
 
input_file.addEventListener('change', async function(){
   const file = document.querySelector('#image-file').files;
   const my_image = await convert_to_base64(file[0]);
   console.log(my_image, "my_image")
   })
```

### Using Javascript to Style an Element
Now we are done, all we need to do is set the base64 image as the background image of our label.

```javascript
const input_file = document.getElementById('image-file');
const input_label = document.getElementById('image-label')
 
const convert_to_base64 = file => new Promise((response) => {
   const file_reader = new FileReader();
   file_reader.readAsDataURL(file);
   file_reader.onload = () => response(file_reader.result);
});
 
input_file.addEventListener('change', async function(){
   const file = document.querySelector('#image-file').files;
   const my_image = await convert_to_base64(file[0]);
   input_label.style.backgroundImage =`url(${my_image})`
   })
```

And that is all. You have a super cool custom image uploader with an image preview in a few simple steps.

## Conclusion
As a developer, you will agree that modern web design demands more than just a plain image uploader. The above articles show you how to create a custom image uploader with image preview in four easy steps with your **HTML, CSS, and JavaScript**

Thanks for Reading 🌟🎉

I'd love to connect with you on [Twitter](https://twitter.com/Abdulrasaq_Jay)

Happy coding...