Handling styles
So far our VDOM library supports styling elements via the className
prop, but sometimes you need to apply styles directly to an element. There are two ways you could do this: by specifying a CSS string, or by specifying an object of CSS properties.
{// CSS strings are valid values for the `style` propstyle: "text-align: center;"// So are objects of CSS propertiesstyle: {color: "blue",fontWeight: bold,}}
I'm going to modify our example application to add some styles to the elements.
return createVNode("div",{ className: "container", style: "text-align: center" },[createVNode("h1", null, ["Hello, World!"]),createVNode("p", { style: { color: "blue" } }, ["We're building a ",createVNode("small", { style: { fontWeight: "bold" } }, ["(really simple)",])," virtual DOM library.",]),]);
Let's see what happens when we mount this with the code we have so far:
The string styles are applied, but the object styles are not. We'll have to write some more code to support them. The first thing we'll do is create a new setProperty()
function where we can start to handle the different edge cases. Our mount()
function will now call setProperty()
rather than setting the props directly on the DOM node:
if (vnode.props) {for (const prop in vnode.props) {setProperty(domNode, prop, vnode.props[prop]);}}
Now we can write the setProperty()
function with some extra logic to handle the style
prop.
function setProperty(domNode, prop, value) {if (prop === "style") {if (typeof value === "string") {// Set string styles on the cssText propertydomNode.style.cssText = value;} else {// Set object styles on the style objectfor (const styleProp in value) {domNode.style[styleProp] = value[styleProp];}}} else {// For all other props, we can set them directly on the DOM node.domNode[prop] = value;}}
With those changes, the styles in our example application are being applied correctly.
In the next section we're going to cover one of the most (maybe the most) important parts of any front-end library: custom components.