{"id":16740,"date":"2022-09-12T10:42:15","date_gmt":"2022-09-12T17:42:15","guid":{"rendered":"https:\/\/coderpad.io\/?p=16740"},"modified":"2023-06-05T14:10:02","modified_gmt":"2023-06-05T21:10:02","slug":"react-photo-editor-with-css-filters","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/react-photo-editor-with-css-filters\/","title":{"rendered":"How to Build a Photo Editor With React and CSS Filters"},"content":{"rendered":"\n<p>CSS is the language used to control the style of a web document in a simple and easy way. It helps makes a web application look more presentable and visually appealing.&nbsp;<\/p>\n\n\n\n<p>In a world of constant development and evolution, especially in the software engineering world, CSS isn\u2019t left behind; it now includes new features that allow developers to apply effects that previously would only seem possible with graphics applications such as Adobe. These new features are &#8220;CSS Filters,&#8221;<a href=\"https:\/\/coderpad.io\/blog\/development\/everything-you-need-to-know-about-all-11-css-filters\/\" target=\"_blank\" rel=\"noreferrer noopener\">which we recently covered in-depth on our blog.<\/a><\/p>\n\n\n\n<p>Text, photos, and other aspects on a webpage can have visual effects applied to them using CSS filters. We can access effects like color, blur, and shifting on an element&#8217;s rendering before the element is displayed, thanks to the CSS filter property.<\/p>\n\n\n\n<p>In this article, we will build a photo editor using React and some CSS filters.<\/p>\n\n\n\n<p>&nbsp;Specifically, in this article we&#8217;ll learn how to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Understand the CSS filter properties with a quick recap<\/li>\n\n\n\n<li>Set up our React project and start building out our application<\/li>\n\n\n\n<li>Set up the JSX structure for our project.<\/li>\n\n\n\n<li>Style our project using standard CSS. This includes our project sidebar.<\/li>\n\n\n\n<li>Make our sidebar, containing our CSS filters, responsive using JavaScript.<\/li>\n\n\n\n<li>Add some functionality to our slider using JavaScript<\/li>\n\n\n\n<li>See the final app in action<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>A quick recap of 11 CSS filter properties<\/strong><\/h2>\n\n\n\n<p>Let\u2019s look at some of the CSS Filter properties and what they do:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>blur(): <\/strong><code>blur()<\/code> applies the blur effect to an element. If the blur value is not specified then it takes in <code>0<\/code> as the default value.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>70%<\/code> blur:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f77992f3.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f77992f3.png\" alt=\"The CoderPad logo with a blurring effect applied \" title=\"The CoderPad logo with a blurring effect applied \"\/><\/a><figcaption class=\"wp-element-caption\">The CoderPad logo is blurred by the CSS filter<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>brightness(): <\/strong><code>brightness()<\/code> controls how bright the element is. It is completely black at <code>0%<\/code> brightness, and it is identical to the original at 100% brightness. Elements are brighter when the values are higher than <code>100%<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>99%<\/code> brightness:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f79b5c10.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f79b5c10.png\" alt=\"The CoderPad logo with the brightness increased to the extent that the word &quot;Pad&quot; is no longer visible\" title=\"The CoderPad logo with the brightness increased to the extent that the word &quot;Pad&quot; is no longer visible\"\/><\/a><figcaption class=\"wp-element-caption\">The CoderPad logo with the brightness increased to the extent that the word &#8220;Pad&#8221; is no longer visible<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>contrast(): <\/strong><code>contrast<\/code> aids in adjusting an element&#8217;s contrast. When the contrast is <code>0%<\/code>, an element is completely black; when it is&nbsp; <code>100%<\/code>, it shows the original element.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>70%<\/code> contrast:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7ac2897.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7ac2897.png\" alt=\"The CoderPad logo with a 70% contrast effect applied\" title=\"The CoderPad logo with a 70% contrast effect applied\"\/><\/a><figcaption class=\"wp-element-caption\">Contrast is decreased in the CoderPad image, making all colors more contrasted<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>grayscale(): <\/strong>The colors of an element are changed to black and white in a grayscale. The grayscale <code>0%<\/code> represents the original element, while <code>100%<\/code> grayscale displays the element in grayscale entirely. Values of <code>grayscale<\/code> in between <code>0%<\/code> and <code>100%<\/code> are a mix of grayscale and color. Negative values are not accepted by grayscale.<\/li>\n<\/ul>\n\n\n\n<p>The result of 100% grayscale:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7bce864.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7bce864.png\" alt=\"The CoderPad logo with a grayscale effect applied\" title=\"The CoderPad logo with a grayscale effect applied\"\/><\/a><figcaption class=\"wp-element-caption\">The CoderPad logo entirely grayscaled. The red in the logo is now a dark gray<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>hue-rotate(): <\/strong>The image is given a different color rotation with <code>hue-rotate()<\/code>. The value specifies how many degrees the picture samples will be rotated around the color circle. The default value of 0 degrees represents the original image.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>70%<\/code> hue-rotate:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7cc64b1.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7cc64b1.png\" alt=\"The CoderPad logo with a hue-rotate effect applied\" title=\"The CoderPad logo with a hue-rotate effect applied\"\/><\/a><figcaption class=\"wp-element-caption\">A hue-rotated CoderPad logo, making the red look like a purple.<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>sepia(): <\/strong><code>sepia()<\/code> transforms an image into a sepia image, where <code>100%<\/code> of the image is sepia and 0% is the original image.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>70<\/code> sepia:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7db361e.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7db361e.png\" alt=\"The CoderPad logo with a sepia effect applied\" title=\"The CoderPad logo with a sepia effect applied\"\/><\/a><figcaption class=\"wp-element-caption\">The CoderPad logo with 70% sepia applied, making the colors more brown<\/figcaption><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>saturate():<\/strong> To control an element&#8217;s saturation, <code>saturate()<\/code> is used. <code>100%<\/code> saturate represents the original element, while <code>0%<\/code> saturate denotes an element that is entirely unsaturated. An element that is super-saturated has a value greater than <code>100%<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>The result when adjusted to <code>100<\/code> saturate:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/image-17.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"561\" height=\"254\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/image-17.png\" alt=\"\" class=\"wp-image-16748\" srcset=\"https:\/\/coderpad.io\/wp-content\/uploads\/2022\/09\/image-17.png 561w, https:\/\/coderpad.io\/wp-content\/uploads\/2022\/09\/image-17-300x136.png 300w\" sizes=\"auto, (max-width: 561px) 100vw, 561px\" \/><\/a><figcaption class=\"wp-element-caption\">The normal CoderPad logo, with 100% saturation, leading to a normal image<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Other CSS filters include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>invert(): <\/strong>The element is reversed by <code>invert()<\/code>. The default value of 0% represents the initial image. The image is entirely inverted when the percentage is <code>100%<\/code>. Negative values are not recognized by <code>invert<\/code>.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>opacity(): <\/strong>The image&#8217;s opacity effect is controlled by <code>opacity()<\/code>. When an element has<code> 0%<\/code> opacity, it is fully transparent; when it has <code>100%<\/code> opacity, the original element is displayed. A negative value is not recognized by this filter.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>drop-shadow(): <\/strong><code>drop-shadow()<\/code> gives the element a drop shadow appearance. It accepts the values <code>blur<\/code>, <code>spread<\/code>, <code>color<\/code>, <code>h-shadow<\/code>, and <code>v-shadow<\/code>. It can be applied to shapes as well as images because it can have the same shape as the original. The shadow will be moved to the left of the image by the negative values for the <code>h-shadow<\/code> and <code>v-shadow<\/code>.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>url(): <\/strong>In order to apply some effects to an HTML element, the url filter uses a string value linking to an <a href=\"https:\/\/www.adobe.com\/creativecloud\/file-types\/image\/vector\/svg-file.html#:~:text=frequently%20asked%20questions-,What%20is%20an%20SVG%20file%3F,and%20lines%20on%20a%20grid.\" target=\"_blank\" rel=\"noreferrer noopener\">SVG<\/a> filter element.<\/li>\n<\/ul>\n\n\n\n<p>To learn more about CSS Filter properties with more in-depth practical examples, check out our article titled \u201c<a href=\"https:\/\/coderpad.io\/blog\/development\/everything-you-need-to-know-about-all-11-css-filters\/\" target=\"_blank\" rel=\"noreferrer noopener\">Everything You Need to Know about All 11 CSS Filters<\/a>\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Set up a React project<\/strong><\/h2>\n\n\n\n<p>The first thing we want to do in order to create our CSS-filter-powered photo editing application is to create a React project. We can do this by running the following command on our terminal:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">npx create-react-app my-editor<\/code><\/span><\/pre>\n\n\n<p>This will automatically install all the dependencies needed to run a React app, and build a React project. To run your newly installed React app on your browser, run the <code>npm start<\/code> command. This is what it will look like in the browser:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7e875c8.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7e875c8.png\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">The official starter template for React rendering. It shows the React logo spinning and &#8220;Edit src\/App.js and save to reload.&#8221;<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Build out the HTML using a bit of JSX<\/strong><\/h2>\n\n\n\n<p>Let&#8217;s get started on adding in photo editing functionality to our newly generated React app by writing out some <a href=\"https:\/\/www.w3schools.com\/react\/react_jsx.asp\" target=\"_blank\" rel=\"noreferrer noopener\">JSX<\/a> for our application. The first thing we want to do is head into our <code>App.js<\/code> file and edit the code to look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import React from <span class=\"hljs-string\">'react'<\/span>;\nimport <span class=\"hljs-string\">'.\/App.css'<\/span>;\nimport Slider from <span class=\"hljs-string\">'.\/Slider'<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'container'<\/span>&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'main-image'<\/span> \/&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'sidebar'<\/span>&gt;\n\u00a0 \u00a0 \u00a0 \u00a0\n\u00a0 \u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;Slider&lt;\/strong&gt; \/&gt;\n\u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 );\n}\nexport <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we have created a <code>div<\/code> for our <code>container<\/code>, <code>main-image<\/code>, and <code>sidebar<\/code>. We&#8217;ll style these classes in the next section.<\/p>\n\n\n\n<p>After this, we created a <code>Slider.js<\/code> custom component and included the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import React from <span class=\"hljs-string\">'react'<\/span>;\nexport <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Slider<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'slider-container'<\/span>&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;input&lt;\/strong&gt; type=<span class=\"hljs-string\">'range'<\/span> ClassName=<span class=\"hljs-string\">'slider'<\/span> \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 \u00a0 )\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Within the <code>Slider<\/code> component we added an input to act as our slider. We did that by creating a&nbsp; <code>div<\/code> with a<code> className<\/code> of <code>slider-container<\/code> and, inside our <code>container<\/code>, added the expected <code>input<\/code> element. This is what it looks like when you run the code:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7eec0ce.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7eec0ce.png\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A browser pointed at localhost:3000 showing a browser&#8217;s default range slider rendered<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Now we have a slider for our project that we can use later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Style an app sidebar with CSS<\/strong><\/h2>\n\n\n\n<p>Let&#8217;s do some styling in our <code>App.css<\/code> file. In our <code>App.css<\/code> file, we&#8217;ll include the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\">*<span class=\"hljs-selector-pseudo\">::before<\/span>, *<span class=\"hljs-selector-pseudo\">::after<\/span> {\n\u00a0 <span class=\"hljs-attribute\">box-sizing<\/span>: border-box;\n}\n<span class=\"hljs-selector-tag\">body<\/span> {\n\u00a0 <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-class\">.container<\/span> {\n\u00a0 <span class=\"hljs-attribute\">display<\/span>: grid;\n\u00a0 <span class=\"hljs-attribute\">grid-template-columns<\/span>: <span class=\"hljs-number\">1<\/span>fr auto;\n\u00a0 <span class=\"hljs-attribute\">grid-template-rows<\/span>: <span class=\"hljs-number\">1<\/span>fr auto;\n\u00a0 <span class=\"hljs-attribute\">grid-template-areas<\/span>:\n\u00a0 \u00a0 <span class=\"hljs-string\">\"image sidebar\"<\/span>\n\u00a0 \u00a0 <span class=\"hljs-string\">\"slider sidebar\"<\/span>;\n\u00a0 <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n\u00a0 <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100vw<\/span>;\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-number\">#DADADA<\/span>;\n}\n<span class=\"hljs-selector-class\">.main-image<\/span> {\n\u00a0 <span class=\"hljs-attribute\">grid-area<\/span>: image;\n\u00a0 <span class=\"hljs-attribute\">background-image<\/span>: <span class=\"hljs-built_in\">url<\/span>(<span class=\"hljs-string\">\"https:\/\/coderpad.io\/wp-content\/themes\/coderpad\/assets\/logos\/coderpad.svg\"<\/span>);\n\u00a0 <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\u00a0 <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\u00a0 <span class=\"hljs-attribute\">background-position<\/span>: top center;\n\u00a0 <span class=\"hljs-attribute\">background-size<\/span>: contain;\n\u00a0 <span class=\"hljs-attribute\">background-repeat<\/span>: no-repeat;\n}\n<span class=\"hljs-selector-class\">.sidebar<\/span> {\n\u00a0 <span class=\"hljs-attribute\">grid-area<\/span>: sidebar;\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: pink;\n}\n<span class=\"hljs-selector-class\">.slider-container<\/span> {\n\u00a0 <span class=\"hljs-attribute\">grid-area<\/span>: slider;\n\u00a0 <span class=\"hljs-attribute\">margin-top<\/span>: <span class=\"hljs-number\">2rem<\/span>;\n\u00a0 <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">2rem<\/span>;\n}\n<span class=\"hljs-selector-class\">.slider<\/span> {\n\u00a0 <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n\u00a0 <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this code snippet, we first set our <code>margin<\/code>&nbsp; to <code>0<\/code>, to remove any margin from our body. Then we styled the rest of our project to make sure our image takes as much space as possible while everything else is pushed to the side.<\/p>\n\n\n\n<p>The image below shows the result of the CSS above:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7f12f6c.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7f12f6c.png\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A pink sidebar rendered to the right-hand side of the page. In the center of the page is the CoderPad logo and on the bottom of the page is our input slider.<\/figcaption><\/figure>\n<\/div>\n\n\n<p><strong>Sidebar<\/strong><\/p>\n\n\n\n<p>Before we style our sidebar, we need to actually put some content inside of it. To do that, we&#8217;ll first create a <code>SidebarItem<\/code> component in our <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'container'<\/span>&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'main-image'<\/span> \/&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">'sidebar'<\/span>&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;SidebarItem&lt;\/strong&gt; \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;SidebarItem&lt;\/strong&gt; \/&gt;\n\u00a0 \u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;Slider&lt;\/strong&gt; \/&gt;\n\u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 );\n}\nexport <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then we&#8217;ll create a <code>SidebarItem.js<\/code> component in our <code>src<\/code> folder, where we can include the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SidebarItem<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span>(\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;button&lt;<span class=\"hljs-regexp\">\/strong&gt; className='sidebar-item'&gt;Sidebar Item&lt;\/<\/span><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>button<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span><\/span>&gt;\n\u00a0 \u00a0 )\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This is the result in the image below:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7f85d72.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7f85d72.png\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">Two browser default styled buttons inside of the pink sidebar off to the right of the screen.<\/figcaption><\/figure>\n<\/div>\n\n\n<p><strong>Sidebar CSS<\/strong><\/p>\n\n\n\n<p>OK! Now to style our sidebar. Let\u2019s head into our <code>App.css<\/code> file again to make the following changes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-class\">.sidebar<\/span> {\n\u00a0 <span class=\"hljs-attribute\">grid-area<\/span>: sidebar;\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: pink;\n\u00a0 <span class=\"hljs-attribute\">border-left<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-built_in\">hsl<\/span>(<span class=\"hljs-number\">265<\/span>, <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">56%<\/span>);\n\u00a0 <span class=\"hljs-attribute\">display<\/span>: flex;\n\u00a0 <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n\u00a0 <span class=\"hljs-attribute\">align-items<\/span>: stretch;\n}\n<span class=\"hljs-selector-class\">.sidebar-item<\/span> {\n\u00a0 <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n\u00a0 <span class=\"hljs-attribute\">border<\/span>: none;\n\u00a0 <span class=\"hljs-attribute\">outline<\/span>: none;\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: pink;\n\u00a0 <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n\u00a0 <span class=\"hljs-attribute\">position<\/span>: relative;\n\u00a0 <span class=\"hljs-attribute\">transition<\/span>: background-color <span class=\"hljs-number\">150ms<\/span>;\n}\n<span class=\"hljs-selector-class\">.sidebar-item<\/span><span class=\"hljs-selector-pseudo\">:hover<\/span>, <span class=\"hljs-selector-class\">.sidebar-item<\/span><span class=\"hljs-selector-pseudo\">:focus<\/span> {\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">hsl<\/span>(<span class=\"hljs-number\">265<\/span>, <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">76%<\/span>);\n}\n<span class=\"hljs-selector-class\">.sidebar-item<\/span><span class=\"hljs-selector-pseudo\">::after<\/span> {\n\u00a0 <span class=\"hljs-attribute\">content<\/span>: <span class=\"hljs-string\">' '<\/span>;\n\u00a0 <span class=\"hljs-attribute\">position<\/span>: absolute;\n\u00a0 <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">80%<\/span>;\n\u00a0 <span class=\"hljs-attribute\">left<\/span>: <span class=\"hljs-number\">10%<\/span>;\n\u00a0 <span class=\"hljs-attribute\">bottom<\/span>: <span class=\"hljs-number\">0<\/span>;\n\u00a0 <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">1px<\/span>;\n\u00a0 <span class=\"hljs-attribute\">background-color<\/span>: <span class=\"hljs-built_in\">hsl<\/span>(<span class=\"hljs-number\">265<\/span>, <span class=\"hljs-number\">100%<\/span>, <span class=\"hljs-number\">46%<\/span>);\n}\n<span class=\"hljs-selector-class\">.sidebar-item<\/span><span class=\"hljs-selector-pseudo\">:last-child<\/span><span class=\"hljs-selector-pseudo\">::after<\/span> {\n\u00a0 <span class=\"hljs-attribute\">display<\/span>: none;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Using the above CSS, we styled our sidebar to give us the result in the GIF below:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7fcf309.gif\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f7fcf309.gif\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A right-handed sidebar with a darker background hover state and a light fade effect between hovering and not.<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Add in sidebar functionality with React<\/strong><\/h2>\n\n\n\n<p>Now that we&#8217;ve gotten styling out of the way &#8211; let&#8217;s get going on the fun part: where we add in different controls for CSS Filter options. To get started, we&#8217;ll first write some code in our <code>App.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> React, {useState, useMemo} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">'.\/App.css'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Slider <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/Slider'<\/span>\n<span class=\"hljs-keyword\">import<\/span> SidebarItem <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/SidebarItem'<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> getDefaultOptions = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> &#91;\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Brightness'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'brightness'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">100<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">200<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'%'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Contrast'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'contrast'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">100<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">200<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'%'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Saturation'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'saturate'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">100<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">200<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'%'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Grayscale'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'grayscale'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">100<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'%'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Sepia'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'sepia'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">100<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'%'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Hue Rotate'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'hue-rotate'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">360<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'deg'<\/span>\n\u00a0 },\n\u00a0 {\n\u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Blur'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">property<\/span>: <span class=\"hljs-string\">'blur'<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 <span class=\"hljs-attr\">range<\/span>: {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>: <span class=\"hljs-number\">0<\/span>,\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>: <span class=\"hljs-number\">20<\/span>\n\u00a0 \u00a0 },\n\u00a0 \u00a0 <span class=\"hljs-attr\">unit<\/span>: <span class=\"hljs-string\">'px'<\/span>\n\u00a0 }\n];\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> &#91;selectedOptionIndex, setSelectedOptionIndex] = useState(<span class=\"hljs-number\">0<\/span>)\n\u00a0 <span class=\"hljs-keyword\">const<\/span> &#91;options, setOptions] = useState(getDefaultOptions())\n\u00a0 <span class=\"hljs-keyword\">const<\/span> selectedOption = options&#91;selectedOptionIndex]\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'container'<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'main-image'<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'sidebar'<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 {options.map((option, index) =&gt; {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return (<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SidebarItem<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{index}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">{option.name}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">active<\/span>=<span class=\"hljs-string\">{index<\/span> === <span class=\"hljs-string\">selectedOptionIndex}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">handleClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setSelectedOptionIndex(index)}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 )\n\u00a0 \u00a0 \u00a0 \u00a0 })}\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Slider<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\u00a0 );\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>First, we create a variable <code>DEFAULT_OPTIONS<\/code> , then we set it to an array of objects. These objects define each one of our buttons, with each of them containing the names of the CSS filter we are using for the project. For each of our objects, there is a <code>property<\/code> field that is set to a CSS filter name, and this is what it corresponds to in CSS.<\/p>\n\n\n\n<p>We also have our default <code>value<\/code>, the <code>range<\/code> which is essentially the <code>min<\/code> and <code>max<\/code> of our slider, then we have our <code>unit<\/code> for each CSS filter object.<\/p>\n\n\n\n<p>Next, we&#8217;ll take our <code>const DEFAULT_OPTIONS<\/code>, and turn them into an <code>options<\/code> object we can use in React, and modify it. We&#8217;ll also edit our <code>sidebar.js<\/code> file to look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import React from <span class=\"hljs-string\">'react'<\/span>\nexport <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SidebarItem<\/span><span class=\"hljs-params\">({ name, active, handleClick\u00a0 })<\/span> <\/span>{\n\u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span>(\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;button&lt;\/strong&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 className={`sidebar-item ${active ? <span class=\"hljs-string\">'active'<\/span> : <span class=\"hljs-string\">''<\/span>}`}\n\u00a0 \u00a0 \u00a0 \u00a0 onClick={handleClick}\n\u00a0 \u00a0 \u00a0 \u00a0 &gt;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { name }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 &lt;\/&lt;strong&gt;button&lt;\/strong&gt;&gt;\n\u00a0 \u00a0 )\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we&#8217;re taking the <code>name<\/code> from the props in our <code>App.js<\/code> file like this; <code>{ name }<\/code>. Below are the results of our code above:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f80332ed.gif\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f80332ed.gif\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A list of CSS filters in the right-hand sidebar that includes the following filters: Brightness, Contrast, Saturation, Grayscale, Sepia, Hue Rotate, and Blur<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Make the CSS filter input slider functional<\/strong><\/h2>\n\n\n\n<p>Now we&#8217;ll look at how to make our slider correspond with our active value. In our <code>App.js<\/code> file, we&#8217;ll include the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Slider<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">min<\/span>=<span class=\"hljs-string\">{selectedOption.range.min}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">max<\/span>=<span class=\"hljs-string\">{selectedOption.range.max}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{selectedOption.value}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">handleChange<\/span>=<span class=\"hljs-string\">{handleSliderChange}<\/span>\n\u00a0 \u00a0 \u00a0 \/&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In our <code>Slider<\/code>, we passed in different props than we had previously, which in our case is the <code>min<\/code>, <code>max<\/code>, <code>value<\/code>, and <code>handleChange<\/code>. Then, inside of <code>App<\/code>, we created a function to handle changes in selected options for us:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> &#91;selectedOptionIndex, setSelectedOptionIndex] = useState(<span class=\"hljs-number\">0<\/span>)\n\u00a0 <span class=\"hljs-keyword\">const<\/span> &#91;options, setOptions] = useState(DEFAULT_OPTIONS)\n\u00a0 <span class=\"hljs-keyword\">const<\/span> selectedOption = options&#91;selectedOptionIndex]\n\n\n\u00a0 <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handleSliderChange<\/span>(<span class=\"hljs-params\">{ target }<\/span>) <\/span>{\n\u00a0 \u00a0 setOptions(<span class=\"hljs-function\"><span class=\"hljs-params\">prevOptions<\/span> =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> prevOptions.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">option, index<\/span>) =&gt;<\/span> {\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">if<\/span> (index !== selectedOptionIndex) <span class=\"hljs-keyword\">return<\/span> option\n\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-keyword\">return<\/span> { ...option, <span class=\"hljs-attr\">value<\/span>: target.value }\n\u00a0 \u00a0 \u00a0 })\n\u00a0 \u00a0 })\n\u00a0 }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we have our function created, we are passing all the needed values down to our <code>Slider<\/code>. Now, in our <code>slider.js<\/code> file let\u2019s use these new values. To do this, we&#8217;ll add the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import React from <span class=\"hljs-string\">'react'<\/span>\nexport <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Slider<\/span><span class=\"hljs-params\">({ min, max, value, handleChange})<\/span> <\/span>{\n\u00a0 <span class=\"hljs-keyword\">return<\/span> (\n\u00a0 \u00a0 &lt;&lt;strong&gt;div&lt;\/strong&gt; className=<span class=\"hljs-string\">\"slider-container\"<\/span>&gt;\n\u00a0 \u00a0 \u00a0 &lt;&lt;strong&gt;input&lt;\/strong&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 type=<span class=\"hljs-string\">\"range\"<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 className=<span class=\"hljs-string\">\"slider\"<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 min={min}\n\u00a0 \u00a0 \u00a0 \u00a0 max={max}\n\u00a0 \u00a0 \u00a0 \u00a0 value={value}\n\u00a0 \u00a0 \u00a0 \u00a0 onChange={handleChange}\n\u00a0 \u00a0 \u00a0 \/&gt;\n\u00a0 \u00a0 &lt;\/&lt;strong&gt;div&lt;\/strong&gt;&gt;\n\u00a0 )\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We now have the results below:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f80dbcef.gif\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f80dbcef.gif\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A user clicking between different CSS filter options and changing the input slider associated with this CSS filter. These options do not yet impact the image in any way<\/figcaption><\/figure>\n<\/div>\n\n\n<p>As shown in the example above, when we change these different values, it updates the values of the filter selected internally.<\/p>\n\n\n\n<p>While this is great progress, it&#8217;s not yet applying those CSS filters to the image itself. Let&#8217;s fix that.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The final product: Apply CSS filters to an image<\/strong><\/h2>\n\n\n\n<p>All that is left to do to make our image editor functional is take all the values and add them to our image and do the filtering for us:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>const<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> getImageStyle = useMemo (<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>function<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>getImageStyle<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span>() {\n\u00a0\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>const<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> filters = options.map(option =&gt; {\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>return<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> `${option.property}(${option.value}${option.unit})`\n\u00a0 }\n)\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>return<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> { filter: filters.join(' ') }\n}, &#91;options])\n\n\nconsole.log(getImageStyle)\n\n\u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>return<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> (\n\u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'container'<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"main-image\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{getImageStyle}<\/span> \/&gt;<\/span>\n\u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'sidebar'<\/span>&gt;<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 {options.map((option, index) =&gt; {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong<\/span>&gt;<\/span>return<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">strong<\/span>&gt;<\/span> (<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SidebarItem<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{index}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">{option.name}<\/span>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-attr\">active<\/span>=<span class=\"hljs-string\">{index<\/span> === <span class=\"hljs-string\">selectedOptionIndex}<\/span>\n\u00a0 \u00a0\n\u00a0 \u00a0\n\u00a0 <span class=\"hljs-attr\">handleClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setSelectedOptionIndex(index)}\n\u00a0 \u00a0 \u00a0 \u00a0 \/&gt;\n\u00a0 \u00a0 \u00a0 \u00a0 )\n\u00a0 \u00a0 \u00a0 })}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In our <code>App.js<\/code> file, we first create a <code><strong>const<\/strong> getImageStyle = useMemo<\/code>, which is going to contain the style we apply to our image. In our function, we created our <code>const filters = options. map<\/code>. This map loops through all of our options to get them converted to a usable CSS property.&nbsp;<\/p>\n\n\n\n<p>We are now done with our demo photo editor app with React and CSS Filters.<\/p>\n\n\n\n<p>Take a look at the practical results.<\/p>\n\n\n\n<p><strong>Here&#8217;s us modifying Brightness,<\/strong> <strong>Contrast,<\/strong> and <strong>Saturation:<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f830e214.gif\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f830e214.gif\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">A user changing the brightness of an image all the way down and back up, then doing the same with contrast and saturation. The CSS filters work the same way a traditional photo editing app would.<\/figcaption><\/figure>\n<\/div>\n\n\n<p><strong>Now here&#8217;s an example of us modifying the Grayscale,<\/strong> <strong>Sepia<\/strong>, <strong>Hue Rotate,<\/strong> and <strong>Blur:<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f877de1c.gif\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2022\/09\/img_631f6f877de1c.gif\" alt=\"\"\/><\/a><figcaption class=\"wp-element-caption\">The user is modifying different color properties, such as grayscale, sepia, and hue rotate. Then, they&#8217;re adding a blur to the final result.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Try out the photo editor in the sandbox below:<\/p>\n\n\n<div\n\tclass=\"sandbox-embed responsive-embed  sandbox-embed--full-width\"\n\tstyle=\"padding-top: 85%\"\ndata-block-name=\"coderpad-sandbox-embed\">\n\t<iframe src=\"https:\/\/embed.coderpad.io\/sandbox?question_id=238393&#038;use_question_button\" width=\"640\" height=\"544\" loading=\"lazy\" aria-label=\"Try out the CoderPad sandbox\"><\/iframe>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping up<\/strong><\/h2>\n\n\n\n<p>Wow! We\u2019ve learned quite a bit just by creating a simple photo editing application that uses CSS filters to apply different effects to an image.&nbsp;<\/p>\n\n\n\n<p>If you want to see the full source code for the React application we built today, you can see the source code over <a href=\"https:\/\/github.com\/uma-victor1\/photo-editor\" target=\"_blank\" rel=\"noreferrer noopener\">on my GitHub repository containing the project<\/a>.<\/p>\n\n\n\n<p>Once you&#8217;ve mastered CSS filters, you&#8217;ll likely want to use them in combination with CSS math functions throughout your app&#8217;s styling. <a href=\"https:\/\/coderpad.io\/blog\/development\/an-overview-of-five-css-math-functions\/\">Here&#8217;s an article outlining what CSS math functions are, and how to use them<\/a>.<\/p>\n\n\n\n<p>Lastly, as you continue to expand your React photo editor, you&#8217;ll need a way to show your users different pages based on the URL. <a href=\"https:\/\/coderpad.io\/blog\/development\/guide-to-react-router\/\">Here&#8217;s how you can add in a routing solution into React<\/a>.<\/p>\n\n\n\n<p>Hopefully this article has been helpful in learning how to practically apply CSS filters and build an app of your own. Until next time!<\/p>\n\n\n\n<p><em>Uma Victor is a software developer based in Nigeria who is familiar with a variety of different web technologies and frameworks. He is also keen on finding ways to explain things as simple as possible. You can reach out to me on <a href=\"https:\/\/twitter.com\/umavictor_\" target=\"_blank\" rel=\"noreferrer noopener\">twitter<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a world of constant development and evolution, especially in the software engineering world, CSS isn\u2019t left behind; it now includes new features that allow developers to apply effects that previously would only seem possible with graphics applications such as Adobe. Learn these new CSS filters by building a photo editor with React and CSS filters.<\/p>\n","protected":false},"author":12,"featured_media":16742,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[62,61],"keyword-cluster":[],"class_list":["post-16740","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=16740"}],"version-history":[{"count":73,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16740\/revisions"}],"predecessor-version":[{"id":32674,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/16740\/revisions\/32674"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/16742"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=16740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=16740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=16740"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=16740"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=16740"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=16740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}