How to Use Gradient Mesh to Create Strawberries in a Milk Splash in Adobe Illustrator

Post pobrano z: How to Use Gradient Mesh to Create Strawberries in a Milk Splash in Adobe Illustrator

Final product image
What You’ll Be Creating

In this tutorial you will learn how to use the Mesh Tool and the Warp
effects, all while creating a pair of realistic strawberries in a splash of milk!

If
you’d like to skip this tutorial and wish to purchase the end result with some different fruits, head
over to GraphicRiver to purchase the Big Collection of Fruit and Berries in Milk Splashes.

Big Collection Of Fruit And Berries In Milk Splashes
Big Collection of Fruit and Berries in Milk Splashes

1. How to Create Two Strawberries

Step 1

Begin by creating a red rectangle and Filling it with the #DF0203 color.

Grab the Mesh Tool (U) and place a node in the top middle of the shape by left-clicking. Move the edges of the rectangle using the Mesh Tool by dragging them. Aim to create a strawberry-like shape.

Finally, create a couple more nodes with the Mesh Tool. There should be about eight rows and five columns of Mesh. Select all the nodes in the two bottom rows and color them with a darker color, #920000.

create the strawberry

Step 2

Continue by creating and coloring more nodes with the Mesh Tool, similarly to the last step.

The colors you will need for each substep are:

  1. #B20505
  2. #CC0304
  3. #B70404
color with the mesh tool

Step 3

Finally, color the middle node in the fifth row with #C00404.

color another middle node

Step 4

Our mesh for the strawberry is done, so let’s move on to creating the seeds!

As in our previous steps, create and modify a shape filled with #E7BD42, and then color the edges of the seed with a darker #DD8C0A.

stretch the bottom node into a tip

Step 5

Continue coloring the seed with Mesh.

The colors you will need are:

  1. #EBCC56
  2. #CE880D
  3. #F3CF71
  4. #D66D0C
color the seeds with the mesh tool

Step 6

Create one more Copy of our result.

Take the first copy and apply Effect > Warp > Inflate to the shape with the following settings:

  • Bend: 0%
  • Horizontal: 0%
  • Vertical: 22%

After applying the effect, go to Object > Expand Appearance.

Remember to do this after every warp!

expand appearance of seeds

Step 7

Modify the seed by flattening it a little and dragging its tip to the right.

flatten the seed

Step 8

Create a copy of the shape we just finished. Scale the copy to about half the size of the original.

scale the seed

Step 9

Let’s place our seeds onto the strawberry!

In the first substep, use the seed we finished in Step 5.

Next, use the one we created in Step 7.

Finally, finish the placement by using the seed from Step 8.

place seeds on the strawberry

Step 10

This should be your resulting strawberry!

the strawberry result after the seeds

Step 11

Now, let’s start creating a half of a strawberry.

Follow the steps in the image below to color the shape with Mesh.

You will need these colors:

  1. #D32D18
  2. None, shaping the strawberry.
  3. #E85D41
  4. None—you will need to delete the columns of Mesh on the sides of the shape and create four other columns that are closer to the middle.
  5. #AA0000
  6. #C93425
  7. #EB9383
  8. #ECBAB9
  9. #9F8D3C
  10. #ECC2C7
  11. #EAA39B
color it like a strawberry sliced in half

Step 12

Add some seeds on the edges of our finished Mesh strawberry, and let’s move on to creating the leaves!

add seeds on the edges

2. How to Create Leaves, Stalks, and Highlights

Step 1

Let’s draw the leaf! Follow the substeps below.

Here are the colors you will need to use:

  1. #6F7B24
  2. #60641A
  3. #BDBD87
  4. #97953B
  5. #4F3F13
  6. #5B5219
  7. #5F6D1D
  8. #535F18
how to create leaves

Step 2

For the details of the leaf, draw three jagged lines with the Pen Tool (P).

Apply a Stroke with the Arrowhead profile to the lines, and then change the color of the Stroke to the basic white-black Gradient.

Change the Transparency mode to Screen and Opacity to 30%.

Finally, select the paths and go to Object > Expand Appearance.

add the leaf details

Step 3

Place the lines on top of the leaf. I would suggest Grouping all of the shapes with Control-G.

place lines on the leaf

Step 4

Create two copies of the original leaf.

Grab the first copy and apply Effect > Warp > Squeeze with the following settings:

  • Bend: -13%
  • Horizontal: -55%
  • Vertical: -11%

Don’t forget to Expand Appearance.

Next, draw an outline similar to the yellow path in the screenshot. Select both the outline and the leaf, right-click on the image, and select Create Clipping Mask in the drop-down menu.

warp the leaves

Step 5

Create two copies of the leaf we finished in the previous step.

Grab the first copy and modify it by Edit > Edit Colors > Adjust Colors with the following settings:

  • Red: -11%
  • Green: -5%
  • Blue: -15%
adjust the leaf colors

Step 6

Take the second copy we made previously and modify its color by going to Edit > Edit Colors > Adjust Colors, now with these settings:

  • Red: -14%
  • Green: -14%
  • Blue: -15%
modify the second leafs colors

Step 7

Very similarly to Step 4, grab the second copy we made in that step and apply Effect > Warp > Arc with the following settings:

  • Bend: 25%
  • Horizontal: -26%
  • Vertical: 0%

Don’t forget to Expand Appearance.

Next,
draw an outline, indicated by the black path in the screenshot. Select
both the outline and the leaf, right-click on the image, and click Create Clipping Mask in the drop-down menu.

make the leaf smaller

Step 8

Move on to creating the stalk.

Draw a light-green rectangle filled with #E2E564. Next, bend it with Effect > Warp > Arc, using 45% BendExpand Appearance.

create the stalk

Step 9

Bend the right tip of the stalk to make it rounder. Then, following the substeps below, color the stalk with Mesh.

You will need these colors:

  1. #9E7943
  2. #A2A13F
  3. #70511A
  4. #FEFDA6
  5. #ADAD45
  6. #AB7F4E
  7. #CEB963
  8. #C2B248
bend the stalk

Step 10

Now that every element is done, let’s bring them all together!

Add the leaves according to the order they were created in, as indicated by the numbers below.

add leaves to the stalk

Step 11

Now let’s add our new leaves to the whole strawberry! Place them behind the berry by sending them to the back with Shift-Control-[.

add the leaves to the strawberry

Step 12

Do the same for the half of the strawberry.

add leaves to the half strawberry

Step 13

We’re almost done with our berries! All that’s left is to create the highlight for our whole strawberry.

Draw a shape like the one in the screenshot, and then three round shapes. The round shapes should be bigger than the seeds we placed.

Next, move the round shapes on top of the original drawing, select all of them, and click Exclude in the Pathfinder panel.

create highlights

Step 14

Draw a half-moon shape and place them as shown in the screenshot. You can use your strawberry with the seeds for reference while doing this—the grey shapes should not touch the seeds, but instead they should be in between.

The same goes for the previous shape.

create half moon shapes

Step 15

Select all the objects and go to Object > Compound Path > Make.

Next, Fill the resulting path with a Linear Gradient from white to #626161.

fill with a linear gradient

Step 16

Change the Transparency mode to Screen and Opacity to 70%.

change the transparency mode

Step 17

Move the highlight on top of the strawberry. If it doesn’t fit, don’t worry—you can modify the shape by dragging its nodes with the Direct Selection Tool (A).

adjust the strawberry highlight

Step 18

Move the half next to the whole strawberry.

move the strawberries

3. How to Create a Milk Splash

Step 1

In this final section, we will draw a milk splash for our strawberries. Prepare your Mesh Tool!

Let’s begin by drawing the first little splash out of five.

Use Mesh to modify and color the shape. The colors you will need for this one are:

  1. #ECEEF1
  2. #CBCFD6
  3. #FFFFFF
create a milk splash

Step 2

Create the next little splash with more Mesh.

  1. #ECEEF1
  2. #D0D5DB
  3. #FFFFFF
create the smaller milk splash

Step 3

Continue by creating the third splash.

  1. #ECEEF1
  2. #D0D5DB
  3. #FFFFFF
create the third milk splash

Step 4

The colors you will need for the fourth splash are:

  1. #E8EAED
  2. #D2D6DC
  3. #FFFFFF
create a fourth milk splash

Step 5

Finish off by creating a milk drop.

  1. #EFF1F3
  2. #DFE1E5
  3. #FFFFFF
create a milk drop

Step 6

This is how our little elements will be labeled later—don’t forget!

all of the milk splashes in order

Step 7

Let’s create our first big Mesh milk splash! You will need these colors:

  1. #F2F3F5
  2. Nothing, just shaping the object
  3. #D0D4DA
  4. #E1E3E7
  5. #FFFFFF
milk splash mesh

Step 8

Add little elements to our big splash! Consult Step 6 if you’re not sure which is which.

add elements to splash

Step 9

Move on to creating the second big splash. This time, you will need these:

  1. #9E7943
  2. Shaping
  3. #DADDE2
  4. #FFFFFF
  5. #E1E3E7
  6. #CBD0D7
add the second part of the splash

Step 10

Add little elements to this splash as well!

add more little elements

Step 11

Create the last part of the splash. Use these colors:

  1. #DFE2E6
  2. Shaping
  3. #C3CAD1
  4. #CFD3DA
  5. #F5F6F7
third part of the splash

Step 12

We won’t add any other elements to the last splash.

Let’s combine them! Green is the first splash we finished, red is the second one, and blue is the last splash.

combine last part behind the first two

Step 13

We’re almost done! Let’s add some milk drops.

Create four more copies of the milk drop we made in Step 5. Modify the first copy by applying Effect > Warp > Squeeze with these settings:

  • Bend: -35%
  • Horizontal: -18%
  • Vertical: 23%

Don’t forget to Object > Expand Appearance.

expand appearance

Step 14

Modify the second copy with Effect > Warp > Inflate with these settings:

  • Bend: 18%
  • Horizontal: -8%
  • Vertical: -40%

Make sure to Expand Appearance.

expand appearance of milk copy

Step 15

Apply Effect > Warp > Twist to the third copy.

  • Bend: -34%
  • Horizontal: 26%
  • Vertical: 36%

Expand Appearance.

expand appearance of third copy

Step 16

For the last copy, simply drag it to flatten it a bit.

flatten the milk drop

Step 17

Use the different milk drops we made in these steps to create something like this:

random placement of milk drops

Step 18

When you’re happy with the little random drops, add them to the big splash and place your strawberries „inside.” They should be on top of the third splash part.

add the milk drops to the composition

Step 19

The final touch will be the addition of a shadow.

Create an ellipse, Filling it with a Radial Gradient from #8B7065 to #FFFFFF. Set its Transparency mode to Multiply.

add a shadow

Step 20

Place the shadow under your milk splash, and you’re done!

place the shadow under the milk

Awesome Work, You’re Now Done!

What now? You can try any of my other tutorials from my profile, or check out my portfolio on GraphicRiver, as well as the original image we recreated in this tutorial.

Big Collection Of Fruit And Berries In Milk Splashes
Big Collection of Fruit and Berries in Milk Splashes

I hope you have enjoyed this tutorial, and I will be extremely happy to see any results, feedback or suggestions in the comments below!

Strawberry in Milk Vector Illustration Adobe Illustrator Tutorial

Reactive UI’s with VanillaJS – Part 1: Pure Functional Style

Post pobrano z: Reactive UI’s with VanillaJS – Part 1: Pure Functional Style

Last month Chris Coyier wrote a post investigating the question, „When Does a Project Need React?” In other words, when do the benefits of using React (acting as a stand-in for data-driven web frameworks in general), rather than server-side templates and jQuery, outweigh the added complexity of setting up the requisite tooling, build process, dependencies, etc.? A week later, Sacha Greif wrote a counterpoint post arguing why you should always use such a framework for every type of web project. His points included future-proofing, simplified workflow from project to project (a single architecture; no need to keep up with multiple types of project structures), and improved user experience because of client-side re-rendering, even when the content doesn’t change very often.

In this pair of posts, I delve into a middle ground: writing reactive-style UI’s in plain old JavaScript – no frameworks, no preprocessors.

Article Series:

  1. Pure Functional Style (You are here!)
  2. Class Based Components (Coming soon!)

There are two very different ways to write React components.

  1. You can write them as classes. Stateful objects with lifecycle hooks and internal data.
  2. Or, you can write them as functions. Just a piece of HTML that gets constructed and updated based on parameters that are passed in.

The former is often more useful for large, complex applications with lots of moving parts, while the latter is a more elegant way to display information if you don’t have a lot of dynamic state. If you’ve ever used a templating engine like Handlebars or Swig, their syntax looks pretty similar to function-style React code.

In this pair of posts, our target use case is websites that might otherwise be static, but would benefit from JavaScript-based rendering were it not for the overhead of setting up a framework like React. Blogs, forums, etc. Therefore, this first post will focus on the functional approach to writing a component-based UI, because it’ll be more practical for that type of scenario. The second post will be more of an experiment; I’ll really push the limit on how far we can take things without a framework, trying to replicate React’s class-based component pattern as closely as possible with only Vanilla JavaScript, probably at the expense of some practicality.

About functional programming

Functional programming has soared in popularity over the last couple years, driven primarily by Clojure, Python, and React. A full explanation of functional programming is outside the scope of this post, but the part that’s relevant to us right now is the concept of values that are functions of other values.

Let’s say your code needs to represent the concept of a rectangle. A rectangle has width and height, but it also has area, perimeter, and other attributes. At first, one might think to represent a rectangle with the following object:

var rectangle = {
  width: 2,
  height: 3,
  area: 6,
  perimeter: 10
};

But, it would quickly become apparent that there’s a problem. What happens if the width gets changed? Now we have to also change the area and perimeter, or they’d be wrong. It’s possible to have conflicting values, where you can’t just change one without the possibility of having to update something else. This is called having multiple sources of truth.

In the rectangle example, the functional programming-style solution is to make area and perimeter into functions of a rectangle:

var rectangle = {
  width: 2,
  height: 3
};

function area(rect) {
  return rect.width * rect.height;
}

function perimeter(rect) {
  return rect.width * 2 + rect.height * 2;
}

area(rectangle); // = 6
perimeter(rectangle); // = 10

This way, if width or height changes, we don’t have to manually modify anything else to reflect that fact. The area and perimeter just are correct. This is called having a single source of truth.

This idea is powerful when you substitute the rectangle with whatever data your application may have, and the area and perimeter with HTML. If you can make your HTML a function of your data, then you only have to worry about modifying data – not DOM – and the way it gets rendered on the page will be implicit.

UI components as functions

We want to make our HTML a function of our data. Let’s use the example of a blog post:

var blogPost = {
  author: 'Brandon Smith',
  title: 'A CSS Trick',
  body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
};

function PostPage(postData) {
  return  '<div class="page">' +
            '<div class="header">' + 
              'Home' +
              'About' +
              'Contact' +
            '</div>' + 
            '<div class="post">' + 
              '<h1>' + postData.title + '</h1>' + 
              '<h3>By ' + postData.author + '</h3>' +
              '<p>' + postData.body + '</p>' +
            '</div>' +
          '</div>';
}

document.querySelector('body').innerHTML = PostPage(blogPost);

Okay. We’ve made a function of a post object, which returns an HTML string that renders our blog post. It’s not really „componentized” though. It’s all one big thing. What if we also wanted to render all our blog posts in a sequence on the home page? What if we wanted to reuse that header across different pages? Luckily, it’s really easy to build functions out of other functions. This is called composing functions:

var blogPost = {
  author: 'Brandon Smith',
  title: 'A CSS Trick',
  body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
};

function Header() {
  return '<div class="header">' + 
            'Home' +
            'About' +
            'Contact' +
          '</div>';
}

function BlogPost(postData) {
  return '<div class="post">' + 
            '<h1>' + postData.title + '</h1>' + 
            '<h3>By ' + postData.author + '</h3>' +
            '<p>' + postData.body + '</p>' +
          '</div>';
}

function PostPage(postData) {
  return  '<div class="page">' +
            Header() +
            BlogPost(postData) +
          '</div>';
}

function HomePage() {
  return '<div class="page">' +
            Header() +
            '<h1>Welcome to my blog!</h1>' +
            '<p>It\'s about lorem ipsum dolor sit amet, consectetur ad...</p>' +
          '</div>';
}

document.querySelector('body').innerHTML = PostPage(blogPost);

That’s so much nicer. We didn’t have to duplicate the header for the home page; we have a single source of truth for that HTML code. If we wanted to display a post in a different context, we could do so easily.

Prettier syntax with template literals

Okay, but all those plus signs are horrible. They’re a pain to type, and they make it harder to read what’s going on. There has to be a better way, right? Well, the folks at W3C are way ahead of you. They created template literals – which, while still relatively new, have pretty good browser support at this point. Simply wrap your string in backticks instead of quotes, and it will get a couple of extra superpowers.

The first superpower is the ability to span multiple lines. So our BlogPost component up above can become:

// ...

function BlogPost(postData) {
  return `<div class="post">
            <h1>` + postData.title + `</h1>
            <h3>By ` + postData.author + `</h3>
            <p>` + postData.body + `</p>
          </div>`;
}

// ...

That’s nice. But the other power is even nicer: variable substitution. Variables (or any JavaScript expression, including function calls!) can be inserted directly into the string if they’re wrapped in ${ }:

// ...

function BlogPost(postData) {
  return `<div class="post">
            <h1>${postData.title}</h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

// ...

Much better. It almost looks like JSX now. Let’s see our full example again, with template literals:

var blogPost = {
  author: 'Brandon Smith',
  title: 'A CSS Trick',
  body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
};

function Header() {
  return `<div class="header">
            Home
            About
            Contact
          </div>`;
}

function BlogPost(postData) {
  return `<div class="post">
            <h1>${postData.title}</h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

function PostPage(postData) {
  return  `<div class="page">
            ${Header()}
            ${BlogPost(postData)}
          </div>`;
}

function HomePage() {
  return `<div class="page">
            ${Header()}
            <h1>Welcome to my blog!</h1>
            <p>It's about lorem ipsum dolor sit amet, consectetur ad...</p>
          </div>`;
}

document.querySelector('body').innerHTML = PostPage(blogPost);

More than just filling in blanks

So we can fill in variables, and even other components through functions, but sometimes more complex rendering logic is necessary. Sometimes we need to loop over data, or respond to a condition. Let’s go over some JavaScript language features that make it easier to do more complex rendering in a functional style.

The ternary operator

We’ll start with the simplest logic: if-else. Of course, since our UI components are just functions, we could use an actual if-else if we wanted to. Let’s see what that would look like:

var blogPost = {
  isSponsored: true,
  author: 'Brandon Smith',
  title: 'A CSS Trick',
  body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
};

function BlogPost(postData) {
  var badgeElement;
  if(postData.isSponsored) {
    badgeElement = `<img src="badge.png">`;
  } else {
    badgeElement = '';
  }

  return `<div class="post">
            <h1>${postData.title} ${badgeElement}</h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

That’s… not ideal. It adds a whole lot of lines for something that isn’t that complicated, and it separates part of our rendering code from its place within the rest of the HTML. This is because a classical if-else statement decides which lines of code to run, rather than which value to evaluate to. This is an important distinction to understand. You can only stick an expression into a template literal, not a series of statements.

The ternary operator is like an if-else, but for an expression instead of a set of statements:

var wantsToGo = true;
var response = wantsToGo ? 'Yes' : 'No'; // response = 'Yes'

wantsToGo = false;
response = wantsToGo ? 'Yes' : 'No'; // response = 'No'

It takes the form [conditional] ? [valueIfTrue] : [valueIfFalse]. So, the blog post example above becomes:

var blogPost = {
  isSponsored: true,
  author: 'Brandon Smith',
  title: 'A CSS Trick',
  body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
};

function BlogPost(postData) {
  return `<div class="post">
            <h1>
              ${postData.title} ${postData.isSponsored ? '<img src="badge.png">' : ''}
            </h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

Much better.

Array.map()

On to loops. Anytime we have an array of data that we want to render, we’re going to need to loop over those values to generate the corresponding HTML. But if we used a for-loop, we’d run into the exact same issue we had with the if-else statement above. A for loop doesn’t evaluate to a value, it executes a series of statements in a certain way. Luckily, ES6 added some very helpful methods to the Array type which serve this specific need.

Array.map() is an Array method that takes a single argument, which is a callback function. It loops over the array it’s called on (similar to Array.forEach()), and calls the supplied callback once for each item, passing the array element to it as an argument. The thing that makes it different from Array.forEach() is that the callback is supposed to return a value – presumably one that’s based on the corresponding item in the array – and the full expression returns the new array of all the items returned from the callback. For example:

var myArray = [ 'zero', 'one', 'two', 'three' ];

// evaluates to [ 'ZERO', 'ONE', 'TWO', 'THREE' ]
var capitalizedArray = myArray.map(function(item) {
  return item.toUpperCase();
});

You might be able to guess why this is so useful for what we’re doing. Earlier we established the concept of a value being a function of another value. Array.map() allows us to get an entire array, for which each item is a function of the corresponding item in another array. Let’s say we have an array of blog posts that we want to display:

function BlogPost(postData) {
  return `<div class="post">
            <h1>${postData.title}</h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

function BlogPostList(posts) {
  return `<div class="blog-post-list">
            ${posts.map(BlogPost).join('')}
          </div>`
}

var allPosts = [
  {
    author: 'Brandon Smith',
    title: 'A CSS Trick',
    body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
  },
  {
    author: 'Chris Coyier',
    title: 'Another CSS Trick',
    body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
  },
  {
    author: 'Bob Saget',
    title: 'A Home Video',
    body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
  }
]

document.querySelector('body').innerHTML = BlogPostList(allPosts);

Each object containing the info for a single blog post is passed, one by one, to the BlogPost function, and the returned HTML strings are placed into a new array. We then just call join() on that new array to combine the array of strings into a single string (separated by an empty string), and we’re done. No for-loops, just a list of objects converted to a list of HTML elements.

Re-rendering

We can now implicitly generate HTML for given data, in a way that’s reusable and composable, all within the browser. But, how do we update when the data changes? How do we even know when to trigger an update? This subject is one of the most complex and hotly debated in the JavaScript framework community today. Making large numbers of DOM updates efficiently is an amazingly difficult problem, one which engineers at Facebook and Google have spent years working on.

Luckily, our proverbial website is just a blog. The content pretty much only changes when we look at a different blog post. There aren’t a ton of interactions to detect, we don’t have to optimize our DOM operations. When we load a new blog post, we can just scrap the DOM and rebuild it.

document.querySelector('body').innerHTML = PostPage(postData);

We could make this a little nicer by wrapping it in a function:

function update() {
  document.querySelector('body').innerHTML = PostPage(postData);
}

Now whenever we load a new blog post, we can just call update() and it will appear. If our application were complicated enough that it needed to re-render frequently – maybe a couple times per second in certain situations – it would get choppy really fast. You could write complex logic to figure out which sections of the page truly need to update given a particular change in data and only update those, but that’s the point where you should just use a framework.

Not just for content

At this point pretty much all our rendering code has been used to determine the actual HTML and text content inside the elements, but we don’t have to stop there. Since we’re just creating an HTML string, anything inside there is fair game. CSS classes?

function BlogPost(postData) {
  return `<div class="post ${postData.isSponsored ? 'sponsored-post' : ''}">
            <h1>
              ${postData.title} ${postData.isSponsored ? '<img src="badge.png">' : ''}
            </h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

Check. HTML attributes?

function BlogPost(postData) {
  return `<div class="post ${postData.isSponsored ? 'sponsored-post' : ''}">
            <input type="checkbox" ${postData.isSponsored ? 'checked' : ''}>
            <h1>
              ${postData.title} ${postData.isSponsored ? '<img src="badge.png">' : ''}
            </h1>
            <h3>By ${postData.author}</h3>
            <p>${postData.body}</p>
          </div>`;
}

Check. Feel free to get really creative with this. Think about your data, and think about how all the different aspects of it should be represented in markup, and write expressions that turn one into the other.

Summary

Hopefully, this post gives you a good set of tools for writing simple reactive, data-driven web interfaces without the overhead of any tools or frameworks. This type of code is far easier to write and maintain than jQuery spaghetti, and there’s no hurdle at all to using it right now. Everything we’ve talked about here comes free with all reasonably modern browsers, without so much as a library.

Part 2 will focus on class-based, stateful components, which will get near the territory of too-complicated-to-reasonably-do-in-VanillaJS. But by golly, we’re going to try anyway, and it’s going to be interesting.

Article Series:

  1. Pure Functional Style (You are here!)
  2. Class Based Components (Coming soon!)

Reactive UI’s with VanillaJS – Part 1: Pure Functional Style is a post from CSS-Tricks