The hidden attribute introduced in HTML5 is a semantic way of marking an element as hidden. It will prevent the element from being rendered/displayed on all devices.
Here is what it looks like:
<p>I'm just a normal visible paragraph</p> <p hidden>I'm a hidden paragraph</p>
On a browser it will behave much like
display: none in CSS. (You actually can override the default behavior and make a hidden element visible by applying CSS, but I don't recommend it).
aria-hidden on the other hand is hidden from (most) screen readers, but is still visible in the browser.
aria-hidden should be used with cation as it can introduce accessibility problems, and it works inconsistently in browsers. Read more about this at: https://www.w3.org/TR/wai-aria-1.1/#aria-hidden
display: none in CSS also hides the element from all devices (browsers, screen readers). But it lacks the semantics of the hidden attribute. (Also it won't work if the CSS for some reason fails to load).
One problem with both the hidden attribute and
display: none is animation. It's hard to do transitions on element if you want them to toggle from hidden to visible.
You can read more about accessibility and animations in this article: https://whatabout.dev/animations-and-accessibility