Relational Selectors: Intersection Area

July 24, 2024
Academy
Big title Relational Selectors: Intersection Area in white font with dark purple border. Three dark purple arrows from top left, top right and bottom right pointing at it. Man looking surprised at it with left hand near to his head and holding a notepad in his right arm. Background is a gradient from wine red top right to neon green bottom left. There is also a nearly transparent deep purple cross spanning the whole picture in the background .
linkedin icontwitter icon

Relational selectors like above() or leftOf() help you to detect elements related to another element.

But there are some edge cases like textfields with not enough space between them that lead to a lot of frustration.

AskUI now supports an optional parameter intersection_area for the relational selectors above(), below(), rightOf() and leftOf() that gives you control over HOW elements are detected.

This blog post explains the different options with examples and illustrations.

Prerequisites

The Example: Untargetable Elements

Let's look at an example that illustrates the different use cases:

A rectangular text box labeled "TEXT1" on the left side. Three rectangular text boxes labeled "TEXT2," "TEXT0," and "TEXT3" arranged vertically in the center. A rectangular button labeled "BUTTON" on the right side. The background color of the text boxes is a light grey, and the button is a slightly darker grey. All the labels are centered within their respective boxes.

Up until now, relational selectors used the area in the direction of the element which was determined by the edges to find elements. You can see an example for the instruction text().rightOf().button() in the next picture, where Text0 and Text1 will be detected:

A rectangular text box labeled "TEXT1" on the left side, highlighted with a green outline. Three rectangular text boxes labeled "TEXT2," "TEXT0," and "TEXT3" arranged vertically in the center. "TEXT0" is highlighted with a green outline. A rectangular button labeled "BUTTON" on the right side. A horizontal green bar that spans across the image, intersecting "TEXT1," "TEXT0," and the "BUTTON"

This seemed like the behavior that a user would expect from a relational selector. However, you could experience the following challenges:

  • How do I target Text0 only when the bounding box of Text1 overlaps with the bounding box of Text0?
  • How do I even target Text2 and Text3? Hint: You could not!
  • How do I target Text0 only in this example?

The Solution: Parameter intersection_area

This is why we implemented an optional parameter intersection_area that gives you more control over the area elements will be related to.

It can take the following values:

  • element_center_line - considered above/below/left/right of the other element if element's bounding box intersects with a horizontal line passing through the center of the other element
  • element_edge_area - considered above/below/left/right of the other element if element's bounding box intersects with an area between the top and the bottom edge of the other element
  • display_edge_area - considered above/below/left/right of the other element no matter where it is placed vertically on the screen (y-axis)

You have to specify the area after the index parameter. Please find a few usage examples below and also check the API docs:

-- CODE language-ts line-numbers -- // Select first text in the edge area above button ...text().leftOf(0, 'element_edge_area').button() // Select the third text in the display edge area ...text().leftOf(2, 'display_edge_area').button() // Select the second text in the center line from button ...text().leftOf(1, 'element_center_line').button()

Intersection: Horizontal Line

If you set intersection_area to element_center_line the elements that are touched by the line starting from the center of the element will be detected. In the following image, Text1 will not be detected because of this.

The image displays a graphical user interface with the following elements: A rectangular text box labeled "TEXT1" on the left side. Three rectangular text boxes labeled "TEXT2," "TEXT0," and "TEXT3" arranged vertically in the center. A rectangular button labeled "BUTTON" on the right side. The background is mostly white, covering the entire area except for a horizontal green line that starts at the "BUTTON" and goes all the way to the right side. The text box "Text0" is highlighted green because it is touched by the line. All the labels are centered within their respective boxes.

This is useful in edge cases where Text1 is unintentionally detected because the bounding box of Text1 overlaps with the edge area of the button.

For example, adjacent textfields that do not have enough spacing between them are usually prone to this problem.

Intersection: Area

This default value element_edge_area was used until the update and will be used if you do not specify an intersection_area. It is a sensible default that is the correct behavior in most cases.

A rectangular text box labeled "TEXT1" on the left side, highlighted with a green outline. Three rectangular text boxes labeled "TEXT2," "TEXT0," and "TEXT3" arranged vertically in the center. "TEXT0" is highlighted with a green outline. A rectangular button labeled "BUTTON" on the right side. A horizontal green bar that spans across the image, intersecting "TEXT1," "TEXT0," and the "BUTTON".

Intersection: Display

If you set the intersection_area to display_edge_area everything, and everything means everything in the area spanned vertically and horizontally, on the screen in the direction of the relational selector will be detected.

Note: You have to experiment with the index as the order of the detected elements may not be obvious or logical.

The image displays a graphical user interface with the following elements: A rectangular text box labeled "TEXT1" on the left side. Three rectangular text boxes labeled "TEXT2," "TEXT0," and "TEXT3" arranged vertically in the center. A rectangular button labeled "BUTTON" on the right side. The background is mostly green, covering the entire area except for a vertical strip on the right side where the "BUTTON" is located. The text boxes and button are all light grey with black text, and all the labels are centered within their respective boxes.

Conclusion

This update to relational selectors was a needed one. It gets rid of some unsolvable edge cases like overlapping bounding boxes. It also provides fine-grained control over selecting elements relationally.

If you have questions or need support, do not hesitate to join our Outverse-Community.

Johannes Dienst
·
July 24, 2024
On this page