Get Elements by Style

Prompt
Could you implemenet a function called getElementsByStyle
that takes in an element, a property string, and a value string representing the style's property/value pair to be matched on the elements descendants. E.g. getElementsByStyle(document.body, 'font-size', '20px')
.
This function does not exist natively in the DOM API.
However, we would like to build it as part of our interview today.
Example
<main>
<div>
<p style="font-weight: bold;">Bold Paragraph</p>
<p style="font-size: 20px;">Large Paragraph</p>
</div>
</main>
const elements = getElementsByStyle(document.body, 'font-weight', 'bold');
console.log(elements); // [p]
You can use window.getComputedStyle(element)
to retrieve the computed style of an element. This returns a CSSStyleDeclaration object containing all the element's computed styles.
You can take a look at the MDN docs for more details about this object.
The computedStyles
object has a getPropertyValue
method that can be used to retrieve the value of a specific property. You can check this value against the value
parameter to determine if the element matches the style criteria. If it does, you can add the element to the result array and return the array at the end of the function.
Solution
Explanation
The getElementsByStyle
function allows us to search the DOM for elements with specific computed style values, a capability not natively provided by the DOM API.
Understanding the Problem
Our implementation of getElementsByStyle
does the following:
- Searches through DOM elements to find those with a specific CSS property value
- Returns all matching elements as an array
- Only includes descendants of the starting element (not the element itself)
Our solution leverages the getComputedStyle
method and the getPropertyValue
method of the CSSStyleDeclaration
object.
The Window.getComputedStyle()
method returns an object containing the values of all CSS properties of an element, after applying active stylesheets and resolving any basic computation those values may contain.
// window.getComputedStyle() - Returns the computed style of an element
const computedStyles = getComputedStyle(el);
// CSSStyleDeclaration.getPropertyValue() - Gets the value of a specific CSS property
const propertyValue = computedStyles.getPropertyValue(property);
DOM Traversal with Style Checking
function traverse(el) {
if (el == null) {
return;
}
const computedStyles = getComputedStyle(el);
if (computedStyles.getPropertyValue(property) === value) {
elements.push(el);
}
for (const child of el.children) {
traverse(child);
}
}
The traverse
function implements a depth-first search of the DOM tree.
- It checks if the current element's computed style for the specified property matches our target value
- If it matches, it adds the element to our results array
- Then it recursively processes each child element
Important Considerations with Computed Styles
A crucial aspect of working with getComputedStyle()
is understanding that it returns browser-calculated final values:
- CSS keywords are often converted to their computed equivalents:
font-weight: bold
becomes"700"
color: red
becomes"rgb(255, 0, 0)"
or similar
- Relative units are converted to absolute values:
2em
might become"32px"
depending on the context- Percentages are typically calculated into pixels
This explains why in our test case, we're matching 'font-weight'
with '700'
rather than 'bold'
because that's how the browser represents it internally.
Starting with Children
We start by iterating through the children of the input element:
for (const child of element.children) {
traverse(child);
}
This ensures we don't include the root element itself in our results, matching the behavior of native DOM methods like getElementsByTagName
.