accessability check

This commit is contained in:
Sabrina Hennrich 2025-05-20 15:05:05 +02:00
parent fa1f912089
commit 5771bb7cdd
3 changed files with 397 additions and 396 deletions

View File

@ -2,7 +2,7 @@
<div <div
class="contactBubble" class="contactBubble"
:class="{ active: isContactBubbleOpen }" :class="{ active: isContactBubbleOpen }"
aria-hidden="false" :aria-hidden="!isContactBubbleOpen"
:aria-expanded="isContactBubbleOpen" :aria-expanded="isContactBubbleOpen"
aria-labelledby="controlIcon" aria-labelledby="controlIcon"
role="dialog" role="dialog"
@ -16,6 +16,7 @@
> >
<use :xlink:href="`/assets/icons/collection.svg#${isContactBubbleOpen ? 'times' : 'talk'}`" /> <use :xlink:href="`/assets/icons/collection.svg#${isContactBubbleOpen ? 'times' : 'talk'}`" />
</svg> </svg>
<div <div
v-show="isContactBubbleOpen" v-show="isContactBubbleOpen"
class="contactContainer" class="contactContainer"
@ -23,6 +24,7 @@
aria-labelledby="contactTitle" aria-labelledby="contactTitle"
> >
<div class="row left m-2"> <div class="row left m-2">
<!-- Linke Seite -->
<div id="hintBox" class="col-md-6"> <div id="hintBox" class="col-md-6">
<NuxtImg <NuxtImg
v-if="screenWidth <= 768" v-if="screenWidth <= 768"
@ -41,10 +43,13 @@
</svg> </svg>
<span>{{ companyinfo.phone }}</span> <span>{{ companyinfo.phone }}</span>
</p> </p>
<div v-if="screenWidth > 768" class="pt-3"> <div v-if="screenWidth > 768" class="pt-3">
<h3>{{ $t('contactForm.ourOffice') }}</h3> <h3>{{ $t('contactForm.ourOffice') }}</h3>
<p class="address"> <p class="address">
{{ companyinfo.company }}<br>{{ companyinfo.street }} <br>{{ companyinfo.postalcode }} {{ companyinfo.city }} {{ companyinfo.company }}<br />
{{ companyinfo.street }} <br />
{{ companyinfo.postalcode }} {{ companyinfo.city }}
</p> </p>
<p class="aspProf">{{ $t('contactForm.yourcontactperson') }} <b>Sabrina Hennrich</b></p> <p class="aspProf">{{ $t('contactForm.yourcontactperson') }} <b>Sabrina Hennrich</b></p>
<div class="aspBox"> <div class="aspBox">
@ -59,57 +64,92 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6">
<!-- Rechte Seite -->
<div class="col-md-6">
<div v-if="!formSent"> <div v-if="!formSent">
<form @submit.prevent="submitForm" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $t('contactForm.name') }}</label> <label for="name">{{ $t('contactForm.name') }}</label>
<input <input
id="name" id="name"
class="form-control"
v-model="form.name" v-model="form.name"
type="text" type="text"
name="name" name="name"
aria-required="true" required
autocomplete="name" autocomplete="name"
@blur="validateName" @blur="validateName"
:aria-invalid="!!errors.name"
:aria-describedby="errors.name ? 'error-name' : null"
/>
<span
v-if="errors.name"
id="error-name"
class="error"
role="alert"
> >
<span v-if="errors.name" class="error">{{ errors.name }}</span> {{ errors.name }}
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="email">{{ $t('contactForm.email') }}</label> <label for="email">{{ $t('contactForm.email') }}</label>
<input <input
id="email" id="email"
class="form-control"
v-model="form.email" v-model="form.email"
type="email" type="email"
name="email" name="email"
required
autocomplete="email" autocomplete="email"
@blur="validateEmail" @blur="validateEmail"
:aria-invalid="!!errors.email"
:aria-describedby="errors.email ? 'error-email' : null"
/>
<span
v-if="errors.email"
id="error-email"
class="error"
role="alert"
> >
<span v-if="errors.email" class="error">{{ errors.email }}</span> {{ errors.email }}
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="phone">{{ $t('contactForm.phone') }}</label> <label for="phone">{{ $t('contactForm.phone') }}</label>
<input <input
id="phone" id="phone"
class="form-control"
v-model="form.phone" v-model="form.phone"
type="tel" type="tel"
name="phone" name="phone"
autocomplete="tel" autocomplete="tel"
@blur="validatePhone" @blur="validatePhone"
:aria-invalid="!!errors.phone"
:aria-describedby="errors.phone ? 'error-phone' : null"
/>
<span
v-if="errors.phone"
id="error-phone"
class="error"
role="alert"
> >
<span v-if="errors.phone" class="error">{{ errors.phone }}</span> {{ errors.phone }}
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="message">{{ $t('contactForm.message') }}</label> <label for="message">{{ $t('contactForm.message') }}</label>
<textarea <textarea
id="message" id="message"
class="form-control mt-4"
v-model="form.message" v-model="form.message"
name="message" name="message"
class="mt-4" rows="4"
/> required
></textarea>
</div> </div>
<p class="smallText"> <p class="smallText">
@ -123,28 +163,29 @@
</NuxtLinkLocale> </NuxtLinkLocale>
</p> </p>
<button <button
type="submit" type="submit"
:aria-label="$t('contactForm.sendMessage')"
class="pinkBtn" class="pinkBtn"
@click="submitForm" :aria-label="$t('contactForm.sendMessage')"
> >
{{ $t('contactForm.sendMessage') }} {{ $t('contactForm.sendMessage') }}
</button> </button>
</form>
</div> </div>
<!-- Dankeschön-Text -->
<div v-else class="mt-5 thx"> <div v-else class="mt-5 thx">
<h3 class="pt-5">{{ $t('contactForm.confirmation.thx') }}</h3> <h3 class="pt-5">{{ $t('contactForm.confirmation.thx') }}</h3>
<p>{{ $t('contactForm.confirmation.info') }}</p> <p>{{ $t('contactForm.confirmation.info') }}</p>
<p>{{ $t('contactForm.confirmation.salutation') }}</p> <p>{{ $t('contactForm.confirmation.salutation') }}</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useMainStore } from '@/stores/main'; import { useMainStore } from '@/stores/main';
import { ref, reactive, computed } from 'vue'; import { ref, reactive, computed } from 'vue';

View File

@ -1,5 +1,4 @@
<template> <template>
<div>
<div class="banner-wrapper"> <div class="banner-wrapper">
<!-- Obere Welle --> <!-- Obere Welle -->
<svg <svg
@ -21,43 +20,21 @@
<div class="container"> <div class="container">
<h2 class="pt-4 pb-3">{{ title }}</h2> <h2 class="pt-4 pb-3">{{ title }}</h2>
<div class="marquee marquee--hover-pause mt-5"> <div class="marquee">
<!-- Haupt-Liste --> <div class="marquee-track">
<ul class="marquee__content"> <ul class="marquee-list">
<li v-for="(item, index) in items" :key="index"> <li
<NuxtLink v-if="item.link" :to="item.link" class="custLogoLink"> v-for="(item, index) in items"
<NuxtImg :key="index"
provider="strapi" class="marquee-item"
:src="item.logo.url" >
:alt="item.logo.alternativeText || 'Logo'"
width="250"
format="webp"
loading="lazy"
class="custLogo"
/>
</NuxtLink>
<NuxtImg
v-else
provider="strapi"
:src="item.logo.url"
:alt="item.logo.alternativeText || 'Logo'"
width="250"
format="webp"
loading="lazy"
class="custLogo"
/>
</li>
</ul>
<!-- Duplizierte Liste für Endlos-Scroll -->
<ul class="marquee__content duplicate" aria-hidden="true">
<li v-for="(item, index) in items" :key="'dup-' + index">
<NuxtLink v-if="item.link" :to="item.link" class="custLogoLink"> <NuxtLink v-if="item.link" :to="item.link" class="custLogoLink">
<NuxtImg <NuxtImg
provider="strapi" provider="strapi"
:src="item.logo.url" :src="item.logo.url"
:alt="item.logo.alternativeText || 'Logo'" :alt="item.logo.alternativeText || 'Logo'"
width="250" width="250"
height="50"
format="webp" format="webp"
loading="lazy" loading="lazy"
class="custLogo" class="custLogo"
@ -69,6 +46,7 @@
:src="item.logo.url" :src="item.logo.url"
:alt="item.logo.alternativeText || 'Logo'" :alt="item.logo.alternativeText || 'Logo'"
width="250" width="250"
height="50"
format="webp" format="webp"
loading="lazy" loading="lazy"
class="custLogo" class="custLogo"
@ -78,8 +56,9 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Untere Wellen --> <!-- Wellen unten -->
<div class="waveBox"> <div class="waveBox">
<div id="waver"> <div id="waver">
<div class="waveWrapper waveAnimation"> <div class="waveWrapper waveAnimation">
@ -105,40 +84,25 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
import { computed } from 'vue'
// Runtime config & base CMS URL
const runtimeConfig = useRuntimeConfig() const runtimeConfig = useRuntimeConfig()
const cmsUrl = computed(() => runtimeConfig.public.cmsBaseUrl) const cmsUrl = computed(() => runtimeConfig.public.cmsBaseUrl)
// Props
const props = defineProps({ const props = defineProps({
items: { items: {
type: Array, type: Array,
required: true, required: true,
}, },
logoHeight: {
type: Number,
default: 50,
},
title: { title: {
type: String, type: String,
default: '', default: '',
}, },
link: {
type: String,
default: 'projekt',
},
}) })
</script> </script>
<style lang="sass"> <style lang="sass" scoped>
.banner-wrapper .banner-wrapper
position: relative position: relative
svg svg
@ -146,6 +110,7 @@
@media(max-width: $breakPointSM) @media(max-width: $breakPointSM)
svg svg
margin: 0 margin: 0
.box .box
background-color: $beige background-color: $beige
width: 100% width: 100%
@ -158,47 +123,43 @@
font-family: 'Mainfont-Bold' font-family: 'Mainfont-Bold'
.marquee .marquee
--gap: 1rem
position: relative
display: flex
overflow: hidden overflow: hidden
user-select: none width: 100%
gap: var(--gap)
ul
list-style-type: none
&:hover .marquee__content
animation-play-state: paused
.marquee__content .marquee-track
flex-shrink: 0
display: flex display: flex
justify-content: space-around animation: scroll 20s linear infinite
gap: var(--gap) width: max-content
min-width: 100%
animation: scroll 30s linear infinite
li
&::before
display: none
@keyframes scroll .marquee-list
from display: flex
transform: translateX(0) gap: 3rem
to list-style: none
transform: translateX(calc(-100% - var(--gap))) padding: 1rem 0
margin: 0
.marquee-item
flex-shrink: 0
.custLogo .custLogo
width: auto width: auto
max-width: 250px max-width: 250px
height: 50px height: 50px
margin: 0 3rem
filter: grayscale(100%) filter: grayscale(100%)
transition: filter 0.3s ease transition: filter 0.3s ease
&:hover &:hover
filter: grayscale(0) filter: grayscale(0)
@keyframes scroll
from
transform: translateX(0)
to
transform: translateX(-50%)
.waveBox .waveBox
position: relative position: relative
height: 120px height: 120px
#waver #waver
display: block display: block
position: absolute position: absolute
@ -269,4 +230,3 @@
background-size: auto 100% background-size: auto 100%
animation: move_wave 15s linear infinite animation: move_wave 15s linear infinite
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 198 KiB