PHP
<?php
// Query for posts and events in the 'News' category
$args = [
"post_type" => ["post", "events"], // Include both 'post' and 'events' post types
"posts_per_page" => 6,
"orderby" => "menu_order",
"order" => "DESC", // Specify the order direction
"category__in" => [14], // Replace 123 with the actual News category ID
];
$query = new WP_Query($args);
if ($query->have_posts()): ?>
<div id="posts-container">
<?php while ($query->have_posts()):
$query->the_post();
$dialog_id = "dialog-" . get_the_ID();
// Unique dialog ID
?>
<div class="post-item">
<?php if (has_post_thumbnail()): ?>
<figure class="news-bild">
<?php the_post_thumbnail("large"); ?>
</figure>
<?php endif; ?>
<h3 class="news-titel"><?php the_title(); ?></h3>
<p class="news-untertitel">
<?php
$untertitel = get_post_meta(
get_the_ID(),
"untertitel",
true
);
echo esc_html($untertitel);
?>
</p>
<button type="button" data-a11y-dialog-show="<?php echo $dialog_id; ?>">Read More</button>
<!-- Dialog Markup -->
<div class="dialog-container" id="<?php echo $dialog_id; ?>" aria-hidden="true" data-a11y-dialog>
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<div class="dialog-content" role="document">
<button type="button" data-a11y-dialog-hide aria-label="Close dialog">×</button>
<div class="dialog-heading"><h2><?php the_title(); ?></h2>
<p class="news-untertitel">
<?php
$untertitel = get_post_meta(
get_the_ID(),
"untertitel",
true
);
echo esc_html($untertitel);
?>
</p></div>
<?php if (has_post_thumbnail()): ?>
<figure class="news-bild dialog-inhalt-bild">
<?php the_post_thumbnail("full"); ?>
</figure>
<?php endif; ?>
<div class="dialog-inhalt"><?php the_content(); ?></div>
</div>
</div>
</div>
<?php
endwhile; ?>
</div>
<?php // Reset post data
wp_reset_postdata();else:echo "<p>Momentan gibt es keine aktuellen News</p>";endif;
?>
<script defer src="https://unpkg.com/a11y-dialog/a11y-dialog.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('[data-a11y-dialog]').forEach(function (dialogElement) {
new A11yDialog(dialogElement);
});
});
</script>Sass
// QUERY POSTS
#posts-container {
display: grid;
//grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
gap: 24px;
}
.post-item {
width: 100%; /* Ensure items fill their column */
background: var(--global-palette1) !important;
}
#posts-container > .post-item {
background: var(--global-palette1) !important;
}
h3.news-titel,
.news-untertitel {
color: white !important;
}
h3.news-titel {
line-height: 1.2 !important;
margin-bottom: 6px !important;
}
p.news-untertitel {
font-size: 1rem !important;
font-weight: 300 !important;
}
.post-item > *:not(.news-bild) {
padding: 0 12px;
}
.dialog-container,
.dialog-overlay {
position: fixed;
inset: 0;
z-index: 1000 !important;
}
.dialog-container {
display: flex;
width: 100% !important;
max-width: 840px;
margin-inline: auto;
}
.dialog-container[aria-hidden='true'] {
display: none;
}
.dialog-overlay {
background-color: rgb(43 46 56 / 1);
}
.dialog-content {
margin: auto;
z-index: 2000;
position: relative;
background-color: white;
//padding: clamp(1rem, 1.875vw, 1.5rem);
overflow: auto;
max-height: 90vh; /* Corrected max height for responsiveness */
}
// DIALOG CONTENT HEADING
.dialog-heading {
background: var(--global-palette1);
padding: 16px 24px;
}
.dialog-heading h2 {
color: #fff !important;
margin-bottom: 0px !important;
font-size: clamp(1.25rem, 1.875vw, 1.5rem);
}
// DIALOG INHALT
.dialog-inhalt {
padding: 0 24px 24px !important;
}
.dialog-content button {
position: absolute;
right: 0;
top: 0;
background: transparent;
color: #fff;
padding: 8px;
box-shadow: none !important;
}
.dialog-content:hover {
cursor: default !important;
}
/* Make the .post-item container visually interactive */
.post-item {
position: relative;
padding: 0;
border: 1px solid #003B8E;
margin-bottom: 15px;
cursor: pointer; /* Indicates interactivity */
transition: background-color 0.3s, box-shadow 0.3s; /* Smooth transition for hover and focus */
}
/* Hover effect for the container */
.post-item:hover {
background-color: #f9f9f9;
}
/* Style the button to cover the entire .post-item */
.post-item button[data-a11y-dialog-show] {
position: absolute;
inset: 0; /* Covers the entire container */
background: transparent; /* Ensure it's visually invisible */
border: none; /* Remove any borders */
opacity: 0; /* Visually hide the button */
pointer-events: all; /* Ensure the button captures clicks */
z-index: 1; /* Keep button on top of other elements */
color: transparent !important;
}
/* Apply focus-visible styles to the button */
.post-item button[data-a11y-dialog-show]:focus-visible {
opacity: 1; /* Make button visible when focused for outline visibility */
outline: 2px solid #003B8E; /* Blue outline */
outline-offset: -2px; /* Optional: Align outline with .post-item border */
box-shadow: 0 0 5px #003B8E; /* Subtle shadow for focus */
color: transparent !important;
}
/* Adjust internal content for proper layout */
figure.news-bild {
}
.news-bild img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
.news-bild.dialog-inhalt-bild img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
padding: 16px 16px 0 16px !important;
}
.single-content figure {
margin-bottom: 15px;
}
.news-titel {
margin-top: 0;
margin-bottom: 0 !important;
font-size: 1.25rem;
}
.news-excerpt {
margin-bottom: 10px;
font-size: 1rem;
font-weight: 300 !important;
}
.news-excerpt a.read-more {
display: none;
}
.dialog-content h2 {
margin-top: 0 !important;
}JavaScript
class A11yDialog {
constructor(dialogElement) {
if (!dialogElement) {
throw new Error("Dialog element is required.");
}
this.dialog = dialogElement;
this.dialog.setAttribute("aria-hidden", "true");
this.dialog.setAttribute("aria-modal", "true");
this.dialog.setAttribute("role", "dialog");
this.dialog.setAttribute("tabindex", "-1");
this.shown = false;
this.previouslyFocusedElement = null;
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleTriggerClick = this.handleTriggerClick.bind(this);
document.addEventListener("click", this.handleTriggerClick, true);
}
show(event = null) {
if (this.shown) return;
this.shown = true;
this.dialog.removeAttribute("aria-hidden");
this.setHeaderFooterZIndex(0); // Set header and footer z-index to 0
this.previouslyFocusedElement = document.activeElement;
// Prevent body from scrolling
document.body.style.overflow = "hidden";
this.focusFirstElement();
document.body.addEventListener("keydown", this.handleKeyDown);
this.fireEvent("show", event);
}
hide(event = null) {
if (!this.shown) return;
this.shown = false;
this.dialog.setAttribute("aria-hidden", "true");
this.setHeaderFooterZIndex(""); // Reset header and footer z-index
// Restore body scroll
document.body.style.overflow = "";
if (this.previouslyFocusedElement) {
this.previouslyFocusedElement.focus();
}
document.body.removeEventListener("keydown", this.handleKeyDown);
this.fireEvent("hide", event);
}
setHeaderFooterZIndex(value) {
const header = document.querySelector("header");
const footer = document.querySelector("footer");
if (header) {
header.style.zIndex = value;
}
if (footer) {
footer.style.zIndex = value;
}
}
focusFirstElement() {
const focusableElements = this.getFocusableElements();
if (focusableElements.length > 0) {
focusableElements[0].focus();
} else {
this.dialog.focus();
}
}
handleKeyDown(event) {
if (event.key === "Escape") {
event.preventDefault();
this.hide(event);
} else if (event.key === "Tab") {
this.trapTabKey(event);
}
}
trapTabKey(event) {
const focusableElements = this.getFocusableElements();
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (event.shiftKey && document.activeElement === firstElement) {
event.preventDefault();
lastElement.focus();
} else if (!event.shiftKey && document.activeElement === lastElement) {
event.preventDefault();
firstElement.focus();
}
}
getFocusableElements() {
const focusableSelectors = [
'a[href]',
'area[href]',
'input:not([disabled]):not([type="hidden"])',
'select:not([disabled])',
'textarea:not([disabled])',
'button:not([disabled])',
'[tabindex]:not([tabindex="-1"])'
];
return Array.from(
this.dialog.querySelectorAll(focusableSelectors.join(","))
).filter((el) => el.offsetWidth > 0 || el.offsetHeight > 0);
}
handleTriggerClick(event) {
const target = event.target;
if (target.matches(`[data-a11y-dialog-show="${this.dialog.id}"]`)) {
this.show(event);
} else if (
target.matches(`[data-a11y-dialog-hide="${this.dialog.id}"]`) ||
(target.closest(`[data-a11y-dialog-hide]`) && this.shown)
) {
this.hide(event);
}
}
fireEvent(eventName, eventDetail) {
const event = new CustomEvent(eventName, { detail: eventDetail, bubbles: true });
this.dialog.dispatchEvent(event);
}
destroy() {
this.hide();
document.removeEventListener("click", this.handleTriggerClick, true);
}
}
// Automatically initialize dialogs with `data-a11y-dialog` attribute
function initializeDialogs() {
document.querySelectorAll("[data-a11y-dialog]").forEach((dialogElement) => {
new A11yDialog(dialogElement);
});
}
document.addEventListener("DOMContentLoaded", initializeDialogs);