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?
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
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
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 recommendstransform:scale.
…as i described in my solution. Would be great if someone here can solve the problem with transform:scale.
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
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.
Yes I mentioned transform-origin a couple of times already
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.
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
One f the js gurus here may want to have a go at tidying it up or making it work properly
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.
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!
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
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.
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.