SELF-Treffen in Mannheim 2025

SELFHTML wird 30 Jahre alt!
Die Mitgliederversammlung findet am 24.05.2025 um 10:00 statt. Alle Mitglieder und Interessierte sind herzlich eingeladen.
Davor und danach gibt es Gelegenheiten zum gemütlichen Beisammensein. → Veranstaltungs-Ankündigung.

Beispiel:HTML-custom-3.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>toggle-switch</title>
<style>body:has(#halloween-style:state(checked)) {
  background: black;
	color: white;
	
	h1,h2,h3 {
		color: orange;
		border-bottom: medium solid;
		width: max-content;
	}
	img {
		opacity: 1;
	}
}

body {
 	max-width: 40em;
	margin: 0 auto;
	position: relative;
}

label {
	position:absolute;
	top: 1em;
	right: 1em;
}
img.pumpkin {
	width: 200px;
	float:right;
	margin-left:1em;
	max-width: 100%;
	opacity: 0;
}



</style>
</head>

<body>
<h1>custom elements</h1>

<label for="halloween-style" id="toggle-label">Halloween Style einschalten
	<toggle-switch id="halloween-style"></toggle-switch>
</label>

<h2>Halloween</h2>

<p><img class="pumpkin" src="https://upload.wikimedia.org/wikipedia/commons/a/a2/Jack-o%27-Lantern_2003-10-31.jpg" alt="Jack o Lantern">Halloween (Aussprache: <em>/hæləˈwiːn, hæloʊ̯ˈiːn/</em>, von englisch All Hallows’ Eve, der Abend vor Allerheiligen) benennt die Volksbräuche am Abend und in der Nacht vor dem Hochfest Allerheiligen, vom 31. Oktober auf den 1. November. Dieses Brauchtum war ursprünglich vor allem im seinerzeit katholisch geprägten Irland verbreitet.</p>
<p>Seit den 1990er Jahren verbreiten sich Halloween-Bräuche in US-amerikanischer Ausprägung auch in Deutschland und seinen Nachbarländern.</p>



<script>
'use strict';
class ToggleSwitch extends HTMLElement {
    static observedAttributes = [ 'checked' ];
    
    static css =
        `:host {
            --padding: 0.5em;
            display: block;            
            width: 7.5rem;
            container-type: inline-size;
            cursor: pointer;
        }
        div {
            box-sizing: border-box;
            transition: all 0.5s ease-in-out;         
        }
        .track {
            user-select: none;
            aspect-ratio: 2 / 1;
            border: thin solid currentColor;
            background-color: steelBlue;
            border-radius: var(--padding);
            padding: var(--padding) calc(2*var(--padding));
        }
        .thumb {
            width: calc(70% - 2*var(--padding));
            aspect-ratio: 1 / 1;
            background-color: transparent;
			border: medium solid orange;
            border-radius: 50%;
        }
        :host(:state(checked)) .frame {
            background-color: lightblue;
        }
        :host(:state(checked)) .thumb {
            background-color: orange;
            transform: translateX(100%);
        }`;
    
    static html =
        `<div class="track"><div class="thumb"></div></div>`;

    #internals;
    
    constructor() {
        super();
        this.attachShadow({mode: "open"});
        this.#internals = this.attachInternals();
        this.#render();
        
        this.setAttribute('role', 'switch'); // Set ARIA role to 'switch'
        this.setAttribute('tabindex', '0'); // Make element focusable
    }

	// Shadow-DOM des Toggle-Switch aufbauen und Eventhandling vorbereiten
    #render() {
        this.shadowRoot.innerHTML = 
        `<style>${ToggleSwitch.css.trim()}</style>
        ${ToggleSwitch.html}`;
        
        this.addEventListener('click', () => {
            this.#changeToggle();
        });
        this.addEventListener('keydown', (event) => {
            if (event.key === ' ' || event.key === 'Enter') {
                event.preventDefault(); // Prevent scrolling when space is pressed
                this.#changeToggle();
            }
        });
    }
	// Darauf reagieren, ob das checked-Attribut geändert wurde
    attributeChangedCallback(name, oldValue, newValue) {
        console.log("attr <%s> <%s> <%s>", name, oldValue, newValue);
        if (name == "checked" && oldValue != newValue) {
            this.#fixChecked();
        }
    }
	// Getter für checked-Eigenschaft
    get checked() {
		// checked-Eigenschaft reflektiert Existenz des checked-Attributs
        return this.hasAttribute('checked');
    }
	// Setter für checked-Eigenschaft
    set checked(check) {
		// Eigenschaftsänderung in Attribut widerspiegeln
        this.toggleAttribute('checked', check);
		// Übrige Eigenschaften anpassen
        this.#fixChecked();
    }
	// Änderungen am checked-Zustand in State und Aria-Zustand übertragen
    #fixChecked() {
        const check = this.checked;
        if (check) {
            this.#internals.states.add('checked');
        }
        else {
            this.#internals.states.delete('checked');
        }
        this.#internals.ariaChecked = check ? "true" : "false";
        this.setAttribute('aria-checked', check);
    }
    // Useraktionen, die den checked-Zustand umschalten, landen hier
	// change-Event nur werfen, wenn der User den Zustand geändert hat!
    #changeToggle() {
        this.checked = !this.checked;
        this.dispatchEvent(
            new Event("change", { bubbles: true, cancelable: true})
        );
    }
}

// Custom-Element bei HTML anmelden - fertig.
customElements.define('toggle-switch', ToggleSwitch);
</script>

</body>
</html>