Can’t Select Multiple aria Descendants

In Outlook web access OWA, the following selector is intended to select all aria descendants of an element ID, but only the first one gets selected. What am i doing wrong?

#ReadingPaneContainerId [aria-label='Message body']

I want to select all message bodies in the reading pane, in a conversation.

Thx!

also asked on freecodecamp

1 Like

Solved! This method doesn’t require iteration, and doesn’t generate a mountain of style tags. It just creates and keeps rewriting the same temporary style tag. Performance seems very fast, with no lags in the slider.

This depends on global vars, so if page state breaks then the slider won’t work. I don’t know if that’s an issue with Javascript.

Mozilla recommends transform:scale instead of zoom, but a weird problem with transform:scale. Seems to cause divs to slide toward left side of window. Maybe just a codepen issue?

Here’s the working solution, using zoom.

// reusable function to return node by selector
var $$ = function (sel) {
  return document.querySelector(sel);
};

// create slider

// slider for zoom
$$("#TopBar").insertAdjacentHTML(
  "beforeend",
  "<input type='range' min='50' max='200' id='slidZoom' value='100' step='1'>"
);

/* 
// slider for transform: scale
$$("#TopBar").insertAdjacentHTML(
  "beforeend",
  "<input type='range' min='0.5' max='2' id='slidZoom' value='1' step='0.1'>"
);
*/

// add temp style tag to hold the zoom css
var styleTag = document.createElement("style");
document.head.appendChild(styleTag);

// define selector for Outlook reading pane
var selector = "#ReadingPaneContainerId [aria-label='Message body']";

// define slider event
$$("#slidZoom").addEventListener("input", function () {

  // change css in temp style tag
  
  // works, using zoom
  styleTag.innerHTML = selector + " {zoom: " + $$("#slidZoom").value + "%}";
  
  // transform:scale causes divs to slide toward left side of window
  // styleTag.innerHTML = selector + " {transform: scale(" + $$("#slidZoom").value + ")}";
});

I’ll move this to the JS forum as it doesn’t seem to be a css question :slight_smile:

It looks to me as though you were trying to select a group of elements in JS but you would need to iterate through all the elements that matched (Js doesn’t work the same as css).

Also note that zoom does not work in Firefox and transform would not keep the element in the flow. If you were just enlarging the letter/text then I guess just changing font-size would suffice.

Hopefully one of the JS gurus will look in here and advise of the best way to do this :slight_smile:

You wouldn’t “need” to iterate. Iteration is one solution. My solution is a different, and i believe superior solution.

Generally, i avoid iteration. I believe it’s a performance hog, and ties up the processor. We’re styling multiple elements while dragging a slider. If we’re styling multiple elements, then of course iteration has to happen someplace. Why not let the highly-optimized browser rendering engine handle the iteration, instead of my Javascript? That’s why I believe straight CSS is going to give better performance for this requirement. Also, loooops are more verbose. My solution is a single line of code while dragging the slider.

Certainly there’s nothing “wrong” with setting CSS with JS, although in my experience some JS purists are hostile to CSS.

I want to resize all the content, not just fonts.

I’m aware of that. For my personal usage, zoom works fine on Chrome. For general usage, Mozilla recommends transform:scale.

…as i described in my solution. Would be great if someone here can solve the problem with transform:scale.

Update: i’m trying these solutions:

Yes I was really referring to your first question and not your later solution:)

I believe that originally you were using js to find those elements and that would require you to iterate through them. Your later solution instead updates the css which of course does not need to iterate.

Ok good :slight_smile:

Yes I mentioned that transform and zoom do different things. When you zoom the element remains in the flow of the document. That means anything not zoomed will move out of the way and not get overlapped.

Transform on the other hand does not alter the flow of the document and therefore will overlap other elements that happen to be in the way (unless you are zooming everything but your demo doesn’t show that to be the case).

To stop it moving you just need to set the transform origin to left ( transform-origin: left; or transform-origin: 0 0; which wil kepp the top position also) but of course does not solve the problem of overlapping if anything is in the way. Here’s a codepen (css only) that shows both zoom and transform in action to illustrate my points.

Ah ok :slight_smile:

1 Like

Here’s a fix for the scale positioning issue

  transform: scale(4);
  transform-origin: left center;
}

But subsequent elements don’t move down as desired. They overlap. How to fix that?

image

Maybe i could create a pseudoelement after the resized elements to push subsequent element, but wotta hack! Firefox, please support zoom!

Yes I mentioned transform-origin a couple of times already :slight_smile:

You’d need to account for the change in size and compensate in some way. I see that in the post you linked to from SO above someone has already written a js routine to do similar using height but it looks very fragile to me.

I don’t see an easy solution I’m afraid.:frowning:

1 Like

Fortunately for me, i use Chrome. But that won’t help Firefox users.

Imo, Firefox should support zoom. I think it’s not appropriate for them to recommend transform:scale – it’s a different functionality.

Cheers!

You are right. They do different things. It looks like it has been a bone of contention for about 15 years now.

1 Like

If you agree that Firefox should support zoom, put your comment here:

and here

1 Like

Bearing in mind I’m a css guy and JS is not my thing I had a go at attempting a simple zoom for moz. It occurred to me that if you could find the height of the transformed element you could set a height on it to keep it in the flow.

Unfortunately it wasn’t as simple as that as it seems the height needs to be on a wrapper element instead of the transformed element to work properly so the elements have to have outer divs created dynamically.

I realise that this may not be any use at all in your app but I just wanted to see how far I could get :slight_smile:

One f the js gurus here may want to have a go at tidying it up or making it work properly :wink:

Note that you will never be able to replicate zoom completely because zoom still allows text content to wrap in the window while transform scale just makes the element bigger and bigger and stretches the window.

1 Like

Thx!

Too bad about the wrap thing. But would still be useful.

What about create a pseudoelement after the resized elements to push subsequent elements? Wouldn’t that be pretty easy?

Yes, i did see a couple solutions out there involving a Container element. But since we don’t have control over the HTML, that might be difficult.

The new :has selector might work as a parent-selector if it is supported by Firefox, and can work even if you don’t know the class or ID of the parent. Since you’re a css guy, maybe you can figure that out!

https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector

In my example the container is added dynamically around the element you want to zoom. You don’t need to access the html as long as you have a way to select the element you want to zoom (which it seems you have as that was your first question :slight_smile:

A pseudo element would be part of the transformed element so would be no use. You could add it to the next element perhaps but then that’s no different to my method of dynamically adding a wrapper. The routines in essence would be similar. :slight_smile:

Thanks for posting your excellent cross-browser solution!

I simplified your pen to make it clearer for me – i’m easily confused. I removed things which aren’t essential to demonstrate the behavior, or which aren’t used for anything. I changed names to be more understandable for me, and less ambiguous.

Changes:

html

  • removed non-essential elements , like the range div at the beginning, and your label.
  • on zoomed elements, changed class to aria-label, to be consistent with other examples in this thread
  • removed the unused classes
  • changed the slider id from range to ZoomSlider. range has an additional meaning, which is the input type.
  • changed one of the images, to prove it zooms differently sized elements

css

  • changed transform to -moz-transform, to self-document that it only applies to firefox. Otherwise my brain thinks “chrome supports transform too, so isn’t Chrome getting double-zoomed?”
  • removed extra eye candy, like borders
  • removed @supports and new-div styles, they aren’t used

javascript

  • Changed AllScale to ZoomElements.
  • Changed result to SupportsZoom.
  • Changed rangeInput to ctlZoomSlider, to indicate it’s a control, and since there could be other range inputs on the page.
  • changed new-div to zoom-wrapper

1 Like

Good job. Glad it helped :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.