sebjel
September 8, 2025, 1:25pm
1
Hi guys, I wanna create a registration form and I wanna use the toggle to ask for permission to subscribe to a newsletter. Weirdly enough, the label is always very far away from the checkbox. I checked it and there seems to be an element called label.toggle-wrapper, that is way too big. But I can’t find a way to reduce to width.
Do you guys have any idea? Or is this maybe inheritted from other elements or classes? I couldn’t find any dependent classes
Hmmm…please share some code. The best would be a StackBlitz reproduction.
The examples don’t have that extra space - ion-toggle: Custom Toggle Button for Ionic Applications
sebjel
September 9, 2025, 1:08pm
3
<div class="ion-page" id="main-content">
<ion-header>
<ion-toolbar>
<ion-grid>
<ion-row class="ion-align-items-center">
<ion-col size="3">
<ion-buttons>
<ion-back-button defaultHref="/home" text=""></ion-back-button>
</ion-buttons>
</ion-col>
<ion-col size="6" class="ion-text-center">
<ion-img src="../assets/logos/logo_circle_500x500.png" style="height: 40px;"></ion-img>
</ion-col>
<ion-col size="3" style="display: flex; justify-content: center; align-items: center;">
<ion-menu-button></ion-menu-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-toolbar>
</ion-header>
<ion-content>
<form [formGroup]="registrationForm">
<div *ngIf="RegistrationStatus === 'essential'" formGroupName="essential">
<ion-title>Registrierung</ion-title>
<div class="description">
<ion-item class="input-field">
<ion-input
type="email"
formControlName="email"
placeholder="E-Mail"
></ion-input>
</ion-item>
<ion-text color="danger" *ngIf="registrationForm.get('essential.email')?.touched">
<ng-container *ngIf="registrationForm.get('essential.email')!.hasError('required')">
E-Mail ist erforderlich.
</ng-container>
<ng-container *ngIf="!registrationForm.get('essential.email')!.hasError('required') && registrationForm.get('essential.email')!.hasError('email')">
E-Mail nicht gültig.
</ng-container>
</ion-text>
<ion-item class="input-field">
<ion-input
type="text"
formControlName="username"
placeholder="Benutzername"
></ion-input>
</ion-item>
<ion-text color="danger" *ngIf="registrationForm.get('essential.username')!.hasError('required') && registrationForm.get('essential.username')?.touched">
Benutzername ist erforderlich.
</ion-text>
<ion-item class="input-field">
<ion-input
type="password"
formControlName="password"
placeholder="Passwort"
></ion-input>
</ion-item>
<ion-text color="danger" *ngIf="registrationForm.get('essential.password')?.touched">
<ng-container *ngIf="registrationForm.get('essential.password')!.hasError('required')">
Passwort ist erforderlich.
</ng-container>
<ng-container *ngIf="!registrationForm.get('essential.password')!.hasError('required') && registrationForm.get('essential.password')!.hasError('minlength')">
Passwort muss mindestens 8 Zeichen enthalten.
</ng-container>
</ion-text>
<ion-item class="input-field">
<ion-input
type="password"
formControlName="repeatPassword"
placeholder="Passwort wiederholen"
></ion-input>
</ion-item>
<ion-text color="danger" *ngIf="registrationForm.get('essential')?.hasError('passwordsMismatch') && registrationForm.get('essential')?.touched">
Die Passwörter stimmen nicht überein.
</ion-text>
<ion-item lines="none">
<ion-label>
Ich stimme der
<a routerLink="/about/data">Datenschutzerklärung</a> zu.
</ion-label>
<ion-toggle slot="start"></ion-toggle>
</ion-item>
<ion-item lines="none">
<ion-label>Ich möchte über Updates, Aktionen und Angebote per E-Mail informiert werden.</ion-label>
<ion-toggle slot="start" formControlName="newsletter"></ion-toggle>
</ion-item>
<ion-button
color="primary"
(click)="moveToNext('additional')"
[disabled]="registrationForm.get('essential')?.invalid"
>
Weiter
</ion-button>
</div>
</div>
<div *ngIf="RegistrationStatus === 'additional'" formGroupName="additional">
<ion-title>Weitere Infos</ion-title>
<div class="description">
<ion-item>
<ion-label>Geschlecht (optional)</ion-label>
<ion-select formControlName="gender" placeholder="Bitte wählen">
<ion-select-option value="male">Männlich</ion-select-option>
<ion-select-option value="female">Weiblich</ion-select-option>
<ion-select-option value="diverse">Divers</ion-select-option>
<ion-select-option value="noanswer">Keine Angabe</ion-select-option>
</ion-select>
</ion-item>
<ion-item class="input-field">
<ion-input
type="text"
formControlName="firstName"
placeholder="Vorname (optional)"
></ion-input>
</ion-item>
<ion-item class="input-field">
<ion-input
type="text"
formControlName="lastName"
placeholder="Nachname (optional)"
></ion-input>
</ion-item>
<ion-item formGroupName="birthDate">
<div style="display: flex; gap: 8px;">
<ion-input type="number" formControlName="day" placeholder="TT"></ion-input>
<ion-input type="number" formControlName="month" placeholder="MM"></ion-input>
<ion-input type="number" formControlName="year" placeholder="YYYY"></ion-input>
</div>
</ion-item>
<ion-item class="input-field">
<ion-input
type="text"
formControlName="city"
placeholder="Wohnort (optional)"
></ion-input>
</ion-item>
<ion-button color="primary" (click)="register()">
Registrieren
</ion-button>
</div>
</div>
<div *ngIf="RegistrationStatus === 'complete'">
<div class="description">
<p>Vielen Dank für deine Registrierung! Du kannst dich nun in deinem Konto anmelden und eine Tour buchen.</p>
</div>
<ion-button color="primary" routerLink="/auth">Zur Anmeldung</ion-button>
</div>
</form>
</ion-content>
</div>
So this is my HTML.
And this is the CSS:
/*
* App Global CSS
* ----------------------------------------------------------------------------
* Put style rules here that you want to apply globally. These styles are for
* the entire app and not just one component. Additionally, this file can be
* used as an entry point to import other CSS/Sass files to be included in the
* output CSS.
* For more information on global stylesheets, visit the documentation:
* https://ionicframework.com/docs/layout/global-stylesheets
*/
/* Core CSS required for Ionic components to work properly */
@import "@ionic/angular/css/core.css";
/* Basic CSS for apps built with Ionic */
@import "@ionic/angular/css/normalize.css";
@import "@ionic/angular/css/structure.css";
@import "@ionic/angular/css/typography.css";
@import "@ionic/angular/css/display.css";
/* Optional CSS utils that can be commented out */
@import "@ionic/angular/css/padding.css";
@import "@ionic/angular/css/float-elements.css";
@import "@ionic/angular/css/text-alignment.css";
@import "@ionic/angular/css/text-transformation.css";
@import "@ionic/angular/css/flex-utils.css";
/**
* Ionic Dark Mode
* -----------------------------------------------------
* For more info, please see:
* https://ionicframework.com/docs/theming/dark-mode
*/
/* @import "@ionic/angular/css/palettes/dark.always.css"; */
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
/* @import "@ionic/angular/css/palettes/dark.system.css"; */
// Ist eingebaut
ion-content {
--background: var(--ion-color-secondary);
text-align: left;
padding: 0;
margin: 0;
position: relative;
}
// Ist eingebaut
ion-button {
display: flex;
width: 70%;
margin-right: auto;
margin-left: auto;
flex-direction: column;
align-items: center;
gap: 10px;
}
// Ist eingebaut
.primary-button {
background-color: var(--ion-color-secondary);
--color: var(--ion-color-secondary);
}
// Ist eingebaut
.arrows {
display: flex;
width: 30%;
margin-right: 5px;
margin-left: 5px;
}
// Ist eingebaut
ion-grid {
padding: 0;
}
// Ist eingebaut
ion-row {
padding: 0;
}
// Ist eingebaut
ion-col {
padding: 0;
}
// Ist eingebaut
ion-modal {
--background: var(--ion-color-tertiary);
--width: 100%;
margin-top: 100%;
height: 50vh;
position: fixed;
bottom: 0;
border-radius: 20px 20px 0 0;
}
// Ist eingebaut
ion-title {
width: 100%;
text-align: center;
font-size: 18px;
padding: 10px;
}
// Ist eingebaut
.modal {
--background: var(--ion-color-primary);
--color: var(--ion-color-secondary);
padding: 16px;
}
// Ist eingebaut
.modal-toolbar {
--background: var(--ion-color-primary);
}
// Ist eingebaut
.modal-title {
background-color: var(--ion-color-primary);
color: var(--ion-color-secondary)
}
// Ist eingebaut
.product-name {
background-color: var(--ion-color-primary);
color: var(--ion-color-secondary)
}
// Ist eingebaut
.quantity-controls {
display: flex;
align-items: center;
justify-content: center;
padding-top: 10px;
}
// Ist eingebaut
.quantity-control-icons {
--color: var(--ion-color-secondary);
--ion-icon-size: 32px;
}
// Ist eingebaut
.quantity-input {
text-align: center;
font-size: 24px;
width: 60px;
background-color: var(--ion-color-secondary);
color: var(--ion-color-primary);
border-radius: 8px;
padding: 8px;
border: none;
margin-top: 0;
}
// Ist eingebaut
.quantity-input input {
background-color: var(--ion-color-primary);
color: var(--ion-color-secondary);
text-align: center;
font-size: 24px;
}
// Ist eingebaut
.thumbnail-col {
height: 150px;
overflow: hidden;
position: relative;
}
// Ist eingebaut
.info-col {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 10px;
}
// Ist eingebaut
.modal-button {
--background: var(--ion-color-secondary); /* Set background to secondary */
--color: var(--ion-color-primary); /* Set text color to primary */
margin-top: 15px;
margin-bottom: 15px;
margin-right: auto;
margin-left: auto;
align-self: center;
width: 80%;
}
// Ist eingebaut
.modal-cancel-button {
text-align: center; /* Centers the text */
color: var(--ion-color-secondary); /* Adjust color if needed */
}
// Ist eingebaut
.navigation-title {
background-color: #660202;
}
// Ist eingebaut
.navigation-image {
height: 40px;
background-color: #660202;
}
// Ist eingebaut
ion-icon.large-icon {
font-size: 150px;
display: block;
margin: 0px auto;
text-align: center;
color: var(--ion-color-primary);
}
// Ist eingebaut
.social-media-row {
width: 100%;
text-align: center;
}
// Ist eingebaut
.social-media-icons {
font-size: 60px;
margin-right: 20px;
margin-left: 20px;
display: flex;
justify-content: center;
}
// Ist eingebaut
ion-input {
color: var(--ion-color-secondary);
}
// Ist eingebaut
.description {
color: var(--ion-color-primary);
font-size: 15px;
text-align: left;
line-height: 1.6;
margin-top: 10px;
padding-left: 15px;
padding-right: 15px;
}
// Ist eingebaut
.buttons {
--color: var(--ion-color-secondary);
margin-top: 15px;
margin-bottom: 15px;
align-self: center;
}
// Ist eingebaut
.input-field {
--background: var(--ion-color-secondary);
--border-radius: 4px;
margin-bottom: 25px;
border-width: 1px;
border-style: solid;
}
// Ist eingebaut
.auth-logo {
display: flex;
justify-content: center;
margin: 20px 0;
}
// Ist eingebaut
.large-logo {
height: 200px;
object-fit: contain;
}
// Ist eingebaut
h2 {
font-size: 16px;
margin-top: 10px;
margin-left: 15px;
color: var(--ion-color-primary);
text-align: left;
}
// Ist eingebaut
.hero-image {
position: relative;
width: 100%;
height: 10rem;
object-fit: cover;
display: block;
margin: 0;
padding: 0;
}
// Ist eingebaut
.tour-map img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
// Ist eingebaut
.player-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
// Ist eingebaut
.player-controls ion-button img {
height: 24px;
width: 24px;
}
// Ist eingebaut
.profile-overview {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 20px;
text-align: center;
}
// Ist eingebaut
.header {
background-color: var(--ion-color-primary);
}
// Ist eingebaut
.header-image {
height: 40px;
margin: 0 auto;
width: 100%
}
// Ist eingebaut
.auth-input {
margin-right: 20px;
margin-left: 20px;
margin-bottom: 10px;
}
// Ist eingebaut
.home-tour-card {
display: block;
background-color: var(--ion-color-secondary);
color: var(--ion-color-primary);
padding: 0;
margin: 10px;
border-top: 1px solid var(--ion-color-primary);
border-right: 1px solid var(--ion-color-primary);
border-left: 1px solid var(--ion-color-primary);
border-bottom: 1px solid var(--ion-color-primary);
}
// Ist eingebaut
.home-tour-card-title {
font-size: 1.1rem;
text-align: center;
margin-top: 0;
margin-bottom: 0;
color: var(--ion-color-primary);
}
// Ist eingebaut
.home-tour-card-image {
height: 10vh;
width: 100%;
object-fit: cover;
}
// Ist eingebaut
.home-tour-card-icon {
height: 0.7rem;
padding-right: 3px;
}
//Ist eingebaut
.home-tour-card-price {
background-color: var(--ion-color-primary);
color: var(--ion-color-secondary);
position: absolute;
bottom: 10px;
right: 10px;
font-size: 15px;
padding: 4px 8px;
border-radius: 8px;
}
// Ist eingebaut
.home-tour-card-download-icon {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 24px;
color: var(--ion-color-secondary);
background-color: var(--ion-color-primary);
border-radius: 50%;
padding: 5px;
}
// Ist eingebaut
.info-button {
padding: 0;
}
// Ist eingebaut
.button-icon {
margin-right: 15px;
}
// Ist eingebaut
.info-flag-icon {
height: 1rem;
padding-right: 3px;
text-align: left;
}
// Ist eingebaut
.rating {
display: flex;
justify-content: space-around;
margin-top: 20px;
flex-wrap: wrap;
}
// Ist eingebaut
.rating-segments {
flex: 1;
min-width: 8%;
}
.tour-footer {
--background-color: var(--ion-color-primary);
position: sticky;
bottom: 0;
width: 100%;
z-index: 1000;
}
.footer-icons {
display: flex;
justify-content: space-evenly;
align-items: center;
padding: 0;
margin: 0;
width: 100%;
font-size: 30px;
}
.map {
position: absolute;
width: 100%;
height: 100%;
background-color: transparent;
opacity: 0;
transition: opacity 150ms ease-in;
}
.map.visible {
opacity: 1;
}
.playMap {
position: absolute;
width: 100%;
height: 65vh;
background-color: transparent;
opacity: 0;
transition: opacity 150ms ease-in;
}
.playMap.visible {
opacity: 1;
}
.alert .alert-title {
text-align: center;
width: 100%;
}
.center-row {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.title-center {
width: 100%;
margin: 0;
text-align: center;
}
ion-checkbox::part(container) {
width: auto; /* Verhindert, dass die Checkbox den ganzen Platz einnimmt */
margin-right: 8px; /* Abstand zwischen Checkbox und Label */
}