diff --git a/docs/unit_definition_changelog.txt b/docs/unit_definition_changelog.txt
index 042e4f737d0b9de7f415ccda328255a0d554778b..666cb4c08bcfb51fc380c3af63ea651a8f97c180 100644
--- a/docs/unit_definition_changelog.txt
+++ b/docs/unit_definition_changelog.txt
@@ -200,10 +200,13 @@ iqb-aspect-definition@1.0.0
 - all elements: new property "alias"
 
 - TextAreaMath
-  - new property: inputAssistancePreset
-  - new property: inputAssistancePosition
-  - new property: inputAssistanceFloatingStartPosition
-  - new property: showSoftwareKeyboard
-  - new property: hideNativeKeyboard
-  - new property: addInputAssistanceToKeyboard
-  - new property: hasArrowKeys
+  - new property:inputAssistancePreset
+  - new property:inputAssistanceCustomKeys
+  - new property:inputAssistancePosition
+  - new property:inputAssistanceFloatingStartPosition;
+  - new property:restrictedToInputAssistanceChars
+  - new property:hasArrowKeys
+  - new property:hasBackspaceKey
+  - new property:showSoftwareKeyboard
+  - new property:addInputAssistanceToKeyboard
+  - new property:hideNativeKeyboard
diff --git a/projects/common/components/input-elements/math-field.component.ts b/projects/common/components/input-elements/math-field.component.ts
index e9d1c7c50aa6a2279169dd8f5eb0accf2dc72aa1..98d728e903ca909a1b8600df404bf1084a3dbbb2 100644
--- a/projects/common/components/input-elements/math-field.component.ts
+++ b/projects/common/components/input-elements/math-field.component.ts
@@ -3,8 +3,8 @@ import {
   Component, Input, Pipe, PipeTransform
 } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { FormElementComponent } from 'common/directives/form-element-component.directive';
 import { MathFieldElement } from 'common/models/elements/input-elements/math-field';
+import { TextInputComponent } from 'common/directives/text-input-component.directive';
 
 @Component({
   selector: 'aspect-math-field',
@@ -18,10 +18,12 @@ import { MathFieldElement } from 'common/models/elements/input-elements/math-fie
        [style.background-color]="elementModel.styling.backgroundColor">
       <label>{{elementModel.label}}</label><br>
       <aspect-math-input [value]="$any(elementModel.value) | getValue: elementFormControl.value : parentForm"
-                                  [readonly]="elementModel.readOnly"
-                                  [enableModeSwitch]="elementModel.enableModeSwitch"
-                                  (input)="elementFormControl.setValue($any($event.target).value)"
-                                  (focusout)="elementFormControl.markAsTouched()">
+                         [readonly]="elementModel.readOnly"
+                         [enableModeSwitch]="elementModel.enableModeSwitch"
+                         (input)="elementFormControl.setValue($any($event.target).value)"
+                         (focusIn)="focusChanged.emit({ inputElement: $event, focused: true })"
+                         (focusOut)="elementFormControl.markAsTouched();
+                                     focusChanged.emit({ inputElement: $event, focused: true })">
       </aspect-math-input>
       <mat-error *ngIf="elementFormControl.errors && elementFormControl.touched"
                  class="error-message">
@@ -31,7 +33,7 @@ import { MathFieldElement } from 'common/models/elements/input-elements/math-fie
   `,
   styles: ['.error-message {font-size: 75%; margin-top: 15px; margin-left: 10px;}']
 })
-export class MathFieldComponent extends FormElementComponent {
+export class MathFieldComponent extends TextInputComponent {
   @Input() elementModel!: MathFieldElement;
 }
 
diff --git a/projects/common/components/input-elements/text-area-math/area-segment.component.ts b/projects/common/components/input-elements/text-area-math/area-segment.component.ts
index e4734a67537ced9a91bfd3d0fa6fb0174f3545e0..ba27b24f02e2dbeb5f019f5f2ee26d41afb4a3f2 100644
--- a/projects/common/components/input-elements/text-area-math/area-segment.component.ts
+++ b/projects/common/components/input-elements/text-area-math/area-segment.component.ts
@@ -12,7 +12,8 @@ import { BehaviorSubject } from 'rxjs';
       <aspect-math-input #inputComponent
                                   [fullWidth]="false"
                                   [value]="value"
-                                  (focusIn)="selectedFocus.next(this.index)"
+                                  (focusIn)="onFocusIn($event)"
+                                  (focusOut)="focusOut.emit($event)"
                                   (valueChange)="valueChanged.emit({ index: index, value: $event})">
       </aspect-math-input>
     } @else {
@@ -50,9 +51,6 @@ export class AreaSegmentComponent {
   @ViewChild('inputComponent') inputComponent!: AreaTextInputComponent | MathInputComponent;
 
   setFocus(offset?: number) {
-    // if (document.activeElement instanceof HTMLElement) {
-    //   document.activeElement.blur();
-    // }
     this.inputComponent.setFocus(offset);
   }
 
diff --git a/projects/common/components/input-elements/text-area-math/text-area-math.component.ts b/projects/common/components/input-elements/text-area-math/text-area-math.component.ts
index 758ea4c31f8213242a2b89922534df2c79c0f628..4c3c86e74dbcc7b717cbd88550c83539501624d3 100644
--- a/projects/common/components/input-elements/text-area-math/text-area-math.component.ts
+++ b/projects/common/components/input-elements/text-area-math/text-area-math.component.ts
@@ -2,16 +2,17 @@ import {
   Component, ElementRef, EventEmitter, Input, OnInit, Output, QueryList, ViewChild, ViewChildren
 } from '@angular/core';
 import { TextAreaMathElement, TextAreaMath } from 'common/models/elements/input-elements/text-area-math';
-import { FormElementComponent } from 'common/directives/form-element-component.directive';
 import {
   AreaSegmentComponent
 } from 'common/components/input-elements/text-area-math/area-segment.component';
 import { BehaviorSubject } from 'rxjs';
 import { RangeSelectionService } from 'common/services/range-selection-service';
+import { TextInputComponent } from 'common/directives/text-input-component.directive';
 
 @Component({
   selector: 'aspect-text-area-math',
   template: `
+    <label class="label">{{elementModel.label}}</label><br>
     <button class="insert-formula-button"
             mat-button
             cdkOverlayOrigin #trigger="cdkOverlayOrigin"
@@ -42,9 +43,9 @@ import { RangeSelectionService } from 'common/services/range-selection-service';
           [selectedFocus]="selectedFocus"
           (valueChanged)="onValueChanged($event)"
           [index]="i"
+          (onKeyDown)="onKeyDown.emit($event)"
           (focusIn)="focusChanged.emit({ inputElement: $event, focused: true })"
           (focusOut)="focusChanged.emit({ inputElement: $event, focused: false })"
-          (onKeyDown)="onKeyDown.emit($event)"
           (remove)="removeSegment($event)">
         </aspect-text-area-math-segment>
       }
@@ -54,22 +55,16 @@ import { RangeSelectionService } from 'common/services/range-selection-service';
     </mat-error>
   `,
   styles: [
+    '.label {font-size: 20px; line-height: 135%;}',
     '.alignment-fix {padding: 15px 0; display: inline-block; width: 0;}',
-    '.text-area {border: 1px solid black; border-radius: 3px; padding: 5px;}',
-    ':host {display: flex; flex-direction: column; height: 100%;}',
+    '.text-area {border: 1px solid black; border-radius: 3px; padding: 3px;}',
     '.insert-formula-button {font-size: large; width: 160px; background-color: #ddd; padding: 15px 10px; height: 55px;}'
   ]
 })
-export class TextAreaMathComponent extends FormElementComponent implements OnInit {
+export class TextAreaMathComponent extends TextInputComponent implements OnInit {
   @Input() elementModel!: TextAreaMathElement;
   @Output() mathInputFocusIn: EventEmitter<FocusEvent> = new EventEmitter();
   @Output() mathInputFocusOut: EventEmitter<FocusEvent> = new EventEmitter();
-  @Output() focusChanged = new EventEmitter<{ inputElement: HTMLElement; focused: boolean }>();
-  @Output() onKeyDown = new EventEmitter<{
-    keyboardEvent: KeyboardEvent;
-    inputElement: HTMLElement;
-  }>();
-
   @ViewChildren(AreaSegmentComponent) segmentComponents!: QueryList<AreaSegmentComponent>;
   @ViewChild('textArea') textArea!: ElementRef;
 
diff --git a/projects/common/directives/text-input-component.directive.ts b/projects/common/directives/text-input-component.directive.ts
index a2cfa91eee777e60e2768c8400161b5ebeb6e025..06755a8c491d82f7db421926894a016d456cd328 100644
--- a/projects/common/directives/text-input-component.directive.ts
+++ b/projects/common/directives/text-input-component.directive.ts
@@ -8,6 +8,6 @@ export abstract class TextInputComponent extends FormElementComponent implements
   @Output() focusChanged = new EventEmitter<{ inputElement: HTMLElement; focused: boolean }>();
   @Output() onKeyDown = new EventEmitter<{
     keyboardEvent: KeyboardEvent;
-    inputElement: HTMLInputElement | HTMLTextAreaElement
+    inputElement: HTMLInputElement | HTMLTextAreaElement | HTMLElement;
   }>();
 }
diff --git a/projects/common/math-editor.module.ts b/projects/common/math-editor.module.ts
index edc3fa49d6f9e3fe3b0d3b225ca153237db21f55..9d83c806a48b1a7ebb308ae5925a733413f6b3e3 100644
--- a/projects/common/math-editor.module.ts
+++ b/projects/common/math-editor.module.ts
@@ -21,8 +21,8 @@ import { MatButtonToggleChange, MatButtonToggleModule } from '@angular/material/
          [class.full-width]="fullWidth"
          [class.inline-block]="!fullWidth"
          [class.read-only]="readonly"
-         (focusin)="onFocusIn($event)"
-         (focusout)="onFocusOut($event)">
+         (focusin)="onFocusIn()"
+         (focusout)="onFocusOut()">
     </div>
   `,
   styles: [`
@@ -58,8 +58,8 @@ export class MathInputComponent implements AfterViewInit, OnChanges {
   @Input() readonly: boolean = false;
   @Input() enableModeSwitch: boolean = false;
   @Output() valueChange: EventEmitter<string> = new EventEmitter();
-  @Output() focusIn: EventEmitter<FocusEvent> = new EventEmitter();
-  @Output() focusOut: EventEmitter<FocusEvent> = new EventEmitter();
+  @Output() focusIn: EventEmitter<MathfieldElement> = new EventEmitter();
+  @Output() focusOut: EventEmitter<MathfieldElement> = new EventEmitter();
   @ViewChild('inputRef') inputRef!: ElementRef;
   @ViewChild('container') container!: ElementRef;
 
@@ -79,6 +79,7 @@ export class MathInputComponent implements AfterViewInit, OnChanges {
     this.inputRef.nativeElement.appendChild(this.mathFieldElement);
     this.mathFieldElement.value = this.value;
     this.mathFieldElement.readOnly = this.readonly;
+    setTimeout(() => { this.mathFieldElement.menuItems = []; }); // Disable context menu
   }
 
   ngOnChanges(changes: SimpleChanges): void {
@@ -105,14 +106,14 @@ export class MathInputComponent implements AfterViewInit, OnChanges {
     this.valueChange.emit(this.mathFieldElement.getValue());
   }
 
-  onFocusIn(event: FocusEvent) {
-    this.focusIn.emit(event);
+  onFocusIn() {
+    this.focusIn.emit(this.mathFieldElement);
     window.mathVirtualKeyboard.show();
   }
 
-  onFocusOut(event: FocusEvent) {
+  onFocusOut() {
+    this.focusOut.emit(this.mathFieldElement);
     window.mathVirtualKeyboard.hide();
-    this.focusOut.emit(event);
   }
 }
 
diff --git a/projects/common/models/elements/input-elements/text-area-math.ts b/projects/common/models/elements/input-elements/text-area-math.ts
index 7f3d3e22c19deb08138bf5b9e753d3315d7b4dfe..e244d59d5d23ce3d015d938461662f33c0a2e0a9 100644
--- a/projects/common/models/elements/input-elements/text-area-math.ts
+++ b/projects/common/models/elements/input-elements/text-area-math.ts
@@ -1,6 +1,4 @@
-import {
-  InputElement
-} from 'common/models/elements/element';
+import { TextInputElement } from 'common/models/elements/element';
 import {
   BasicStyles,
   PositionProperties,
@@ -13,25 +11,16 @@ import { TextAreaMathComponent } from 'common/components/input-elements/text-are
 import { environment } from 'common/environment';
 import {
   AbstractIDService,
-  InputAssistancePreset,
-  InputElementProperties,
-  KeyInputElementProperties,
+  KeyInputElementProperties, TextInputElementProperties,
   UIElementType
 } from 'common/interfaces';
 import { InstantiationEror } from 'common/errors';
 
-export class TextAreaMathElement extends InputElement implements TextAreaMathProperties {
+export class TextAreaMathElement extends TextInputElement implements TextAreaMathProperties {
   type: UIElementType = 'text-area-math';
   value: TextAreaMath[] = [];
   rowCount: number = 2;
   hasAutoHeight: boolean = false;
-  inputAssistancePreset: InputAssistancePreset = null;
-  inputAssistancePosition: 'floating' | 'right' = 'floating';
-  inputAssistanceFloatingStartPosition: 'startBottom' | 'endCenter' = 'startBottom';
-  showSoftwareKeyboard: boolean = false;
-  addInputAssistanceToKeyboard: boolean = false;
-  hideNativeKeyboard: boolean = false;
-  hasArrowKeys: boolean = false;
   position: PositionProperties;
   styling: BasicStyles & {
     lineHeight: number;
@@ -45,13 +34,6 @@ export class TextAreaMathElement extends InputElement implements TextAreaMathPro
     if (isTextAreaMathProperties(element)) {
       this.rowCount = element.rowCount;
       this.hasAutoHeight = element.hasAutoHeight;
-      this.inputAssistancePreset = element.inputAssistancePreset;
-      this.inputAssistancePosition = element.inputAssistancePosition;
-      this.inputAssistanceFloatingStartPosition = element.inputAssistanceFloatingStartPosition;
-      this.showSoftwareKeyboard = element.showSoftwareKeyboard;
-      this.addInputAssistanceToKeyboard = element.addInputAssistanceToKeyboard;
-      this.hideNativeKeyboard = element.hideNativeKeyboard;
-      this.hasArrowKeys = element.hasArrowKeys;
       this.position = { ...element.position };
       this.styling = { ...element.styling };
     } else {
@@ -91,7 +73,7 @@ export class TextAreaMathElement extends InputElement implements TextAreaMathPro
   }
 }
 
-export interface TextAreaMathProperties extends InputElementProperties, KeyInputElementProperties {
+export interface TextAreaMathProperties extends TextInputElementProperties, KeyInputElementProperties {
   rowCount: number;
   hasAutoHeight: boolean;
   position: PositionProperties;
diff --git a/projects/common/services/range-selection-service.ts b/projects/common/services/range-selection-service.ts
index 43d3914428335ec56dd2363949cae832bdcc104d..816961d7072eec4a2afa608510fa4aff6e413792 100644
--- a/projects/common/services/range-selection-service.ts
+++ b/projects/common/services/range-selection-service.ts
@@ -51,24 +51,21 @@ export class RangeSelectionService {
       if (node.nodeType === Node.TEXT_NODE) {
         const textLength = node.textContent?.length || 0;
 
-        // Prüfen, ob Startpunkt im aktuellen Textknoten liegt
         if (start >= charCount && start <= charCount + textLength) {
           range.setStart(node, start - charCount);
         }
 
-        // Prüfen, ob Endpunkt im aktuellen Textknoten liegt
         if (end >= charCount && end <= charCount + textLength) {
           range.setEnd(node, end - charCount);
-          return true; // Fertig, wenn beide Punkte gesetzt sind
+          return true;
         }
 
         charCount += textLength;
       } else {
-        // Rekursive Durchsuchung von Kindknoten
         const childNodes = node.childNodes;
         for (let i = 0; i < childNodes.length; i++) {
           if (setRangeOffsets(childNodes[i])) {
-            return true; // Fertig, wenn beide Punkte gesetzt sind
+            return true;
           }
         }
       }
diff --git a/projects/player/modules/logging/services/log.service.ts b/projects/player/modules/logging/services/log.service.ts
index 47ad6e1470521a76f710c99328d720ea766cdfb1..651ce17b326927578aeda3f932f784ed34945986 100644
--- a/projects/player/modules/logging/services/log.service.ts
+++ b/projects/player/modules/logging/services/log.service.ts
@@ -6,7 +6,7 @@ export enum LogLevel { NONE = 0, ERROR = 1, WARN = 2, INFO = 3, DEBUG = 4 }
   providedIn: 'root'
 })
 export class LogService {
-  static level: LogLevel = 4;
+  static level: LogLevel = 0;
 
   static error(...args: unknown[]): void {
     if (LogService.level >= LogLevel.ERROR) {
diff --git a/projects/player/src/app/app.module.ts b/projects/player/src/app/app.module.ts
index 3aed1aae1abb86388f581007f584b77d9c9c17cf..645d65a633dd252c0a75ff721c40a18242e0734f 100644
--- a/projects/player/src/app/app.module.ts
+++ b/projects/player/src/app/app.module.ts
@@ -67,6 +67,9 @@ import { ExternalAppGroupElementComponent } from
 import { InputAssistanceCustomKeysPipe } from './pipes/input-assistance-custom-keys.pipe';
 import { HasNextPagePipe } from './pipes/has-next-page.pipe';
 import { IsValidPagePipe } from './pipes/is-valid-page.pipe';
+import {
+  MathKeyboardContainerComponent
+} from 'player/src/app/components/math-keyboard-container/math-keyboard-container.component';
 
 @NgModule({
   declarations: [
@@ -125,7 +128,8 @@ import { IsValidPagePipe } from './pipes/is-valid-page.pipe';
     MarkablesContainerComponent,
     IsEnabledNavigationTargetPipe,
     MarkingPanelComponent,
-    UnitNavNextComponent
+    UnitNavNextComponent,
+    MathKeyboardContainerComponent
   ],
   providers: [
     { provide: APIService, useExisting: MetaDataService },
diff --git a/projects/player/src/app/components/elements/compound-group-element/compound-group-element.component.ts b/projects/player/src/app/components/elements/compound-group-element/compound-group-element.component.ts
index 6d04165a05f85d7d08dc4c4eab23aa9f6063d53b..3086e8532f9658419584933f05925e5277854bac 100644
--- a/projects/player/src/app/components/elements/compound-group-element/compound-group-element.component.ts
+++ b/projects/player/src/app/components/elements/compound-group-element/compound-group-element.component.ts
@@ -45,6 +45,7 @@ import { ValidationService } from '../../../services/validation.service';
 import { KeypadService } from '../../../services/keypad.service';
 import { KeyboardService } from '../../../services/keyboard.service';
 import { DeviceService } from '../../../services/device.service';
+import { MathKeyboardService } from 'player/src/app/services/math-keyboard.service';
 
 @Component({
   selector: 'aspect-compound-group-element',
@@ -74,6 +75,7 @@ export class CompoundGroupElementComponent extends TextInputGroupDirective imple
     public keyboardService: KeyboardService,
     public deviceService: DeviceService,
     public keypadService: KeypadService,
+    public mathKeyboardService: MathKeyboardService,
     public unitStateService: UnitStateService,
     public elementModelElementCodeMappingService: ElementModelElementCodeMappingService,
     public veronaSubscriptionService: VeronaSubscriptionService,
@@ -330,7 +332,7 @@ export class CompoundGroupElementComponent extends TextInputGroupDirective imple
 
   private onKeyDown(event: {
     keyboardEvent: KeyboardEvent;
-    inputElement: HTMLInputElement | HTMLTextAreaElement
+    inputElement: HTMLInputElement | HTMLTextAreaElement | HTMLElement
   }, elementModel: InputElement): void {
     this.detectHardwareKeyboard(elementModel);
     this.checkInputLimitation(event, elementModel);
diff --git a/projects/player/src/app/components/elements/element-group-selection/element-group-selection.component.ts b/projects/player/src/app/components/elements/element-group-selection/element-group-selection.component.ts
index f2e4e1505fbbcb1a3a61e91332bfb5a29058807a..1ca7ff0ccc3fc1f32e1a5849ef62c0de9e91d1f8 100644
--- a/projects/player/src/app/components/elements/element-group-selection/element-group-selection.component.ts
+++ b/projects/player/src/app/components/elements/element-group-selection/element-group-selection.component.ts
@@ -13,13 +13,13 @@ export class ElementGroupSelectionComponent implements OnInit {
   @Input() pageIndex!: number;
 
   groups: ElementGroupInterface[] = [
-    { name: 'textInputGroup', types: ['text-field', 'text-area', 'spell-correct', 'text-area-math'] },
+    { name: 'textInputGroup', types: ['text-field', 'text-area', 'spell-correct', 'text-area-math', 'math-field'] },
     { name: 'mediaPlayerGroup', types: ['audio', 'video'] },
     {
       name: 'inputGroup',
       types: [
         'checkbox', 'slider', 'drop-list', 'radio', 'radio-group-images',
-        'dropdown', 'hotspot-image', 'math-field'
+        'dropdown', 'hotspot-image'
       ]
     },
     { name: 'compoundGroup', types: ['cloze', 'likert', 'table'] },
diff --git a/projects/player/src/app/components/elements/input-group-element/input-group-element.component.html b/projects/player/src/app/components/elements/input-group-element/input-group-element.component.html
index 95562c52cb0ab636057e3a3ca6a818fb9e1820a9..9fb3b161a585086b22907c4ffe325841a020c903 100644
--- a/projects/player/src/app/components/elements/input-group-element/input-group-element.component.html
+++ b/projects/player/src/app/components/elements/input-group-element/input-group-element.component.html
@@ -35,9 +35,4 @@
                    [parentForm]="form"
                    [elementModel]="elementModel | cast: DropdownElement">
   </aspect-dropdown>
-  <aspect-math-field *ngIf="elementModel.type === 'math-field'"
-                     #elementComponent
-                     [parentForm]="form"
-                     [elementModel]="elementModel | cast: MathFieldElement">
-  </aspect-math-field>
 </form>
diff --git a/projects/player/src/app/components/elements/input-group-element/input-group-element.component.ts b/projects/player/src/app/components/elements/input-group-element/input-group-element.component.ts
index 53ddef17adeb75d85617ec384ae2cdf3ab0205f9..8efde3f1742c02eff3771187217ceacd225e3a03 100644
--- a/projects/player/src/app/components/elements/input-group-element/input-group-element.component.ts
+++ b/projects/player/src/app/components/elements/input-group-element/input-group-element.component.ts
@@ -11,7 +11,6 @@ import { RadioButtonGroupComplexElement } from 'common/models/elements/input-ele
 import { DropdownElement } from 'common/models/elements/input-elements/dropdown';
 import { InputElement } from 'common/models/elements/element';
 import { HotspotImageElement } from 'common/models/elements/input-elements/hotspot-image';
-import { MathFieldElement } from 'common/models/elements/input-elements/math-field';
 import { ValidationService } from '../../../services/validation.service';
 import { ElementFormGroupDirective } from '../../../directives/element-form-group.directive';
 import { ElementModelElementCodeMappingService } from '../../../services/element-model-element-code-mapping.service';
@@ -31,7 +30,6 @@ export class InputGroupElementComponent extends ElementFormGroupDirective implem
   RadioButtonGroupComplexElement!: RadioButtonGroupComplexElement;
   DropdownElement!: DropdownElement;
   HotspotImageElement!: HotspotImageElement;
-  MathFieldElement!: MathFieldElement;
 
   constructor(
     public unitStateService: UnitStateService,
diff --git a/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.html b/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.html
index 1485b28a82640cab96c6176245720a0946751a73..d8cda8bdc51dcee1b13f0c4bcdeacc3b1f2d9572 100644
--- a/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.html
+++ b/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.html
@@ -32,6 +32,13 @@
     (onKeyDown)="detectHardwareKeyboard(elementModel)"
     (focusChanged)="toggleKeyInput($event, elementComponent)">
   </aspect-text-area-math>
+  <aspect-math-field
+    *ngIf="elementModel.type === 'math-field'"
+    #elementComponent
+    [parentForm]="form"
+    [elementModel]="elementModel | cast: MathFieldElement"
+    (focusChanged)="toggleKeyInput($event, elementComponent)">
+  </aspect-math-field>
 </form>
 
 <aspect-floating-keypad
diff --git a/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.ts b/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.ts
index e877382e97500f518e9dac30b19f743da1d49ff2..84cb33d6eea300b03eecb8b1fbb62866f2af913f 100644
--- a/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.ts
+++ b/projects/player/src/app/components/elements/text-input-group-element/text-input-group-element.component.ts
@@ -7,8 +7,10 @@ import { TextAreaElement } from 'common/models/elements/input-elements/text-area
 import { TextFieldElement } from 'common/models/elements/input-elements/text-field';
 import { SpellCorrectElement } from 'common/models/elements/input-elements/spell-correct';
 import { TextAreaMathElement } from 'common/models/elements/input-elements/text-area-math';
+import { MathFieldElement } from 'common/models/elements/input-elements/math-field';
 import { InputElement } from 'common/models/elements/element';
 import { TextInputGroupDirective } from 'player/src/app/directives/text-input-group.directive';
+import { MathKeyboardService } from 'player/src/app/services/math-keyboard.service';
 import { DeviceService } from '../../../services/device.service';
 import { KeyboardService } from '../../../services/keyboard.service';
 import { ValidationService } from '../../../services/validation.service';
@@ -29,10 +31,12 @@ export class TextInputGroupElementComponent
   TextFieldElement!: TextFieldElement;
   SpellCorrectElement!: SpellCorrectElement;
   TextAreaMathElement!: TextAreaMathElement;
+  MathFieldElement!: MathFieldElement;
 
   constructor(
     public keyboardService: KeyboardService,
     public keypadService: KeypadService,
+    public mathKeyboardService: MathKeyboardService,
     public unitStateService: UnitStateService,
     public elementModelElementCodeMappingService: ElementModelElementCodeMappingService,
     public veronaSubscriptionService: VeronaSubscriptionService,
diff --git a/projects/player/src/app/components/floating-keypad/floating-keypad.component.ts b/projects/player/src/app/components/floating-keypad/floating-keypad.component.ts
index cfd646f89d20a431bcbe8d7c6ab943baecddacb0..1779df5004144554e4f95d67762cdd7d412cb33b 100644
--- a/projects/player/src/app/components/floating-keypad/floating-keypad.component.ts
+++ b/projects/player/src/app/components/floating-keypad/floating-keypad.component.ts
@@ -56,7 +56,7 @@ export class FloatingKeypadComponent implements OnChanges {
             ...position,
             offsetY: this.getOffsetY(this.keypadService.elementComponent.elementModel.type, index > 0)
           }));
-      } else {
+      } else if (startPosition === 'endCenter') {
         this.overlayPositions = [...FloatingKeypadComponent.overlayPositionsConfig[startPosition]];
       }
     }
diff --git a/projects/player/src/app/components/layouts/player-layout/player-layout.component.html b/projects/player/src/app/components/layouts/player-layout/player-layout.component.html
index a601a230735cbecd8e54afde8c05716143ffbcab..3a2b161e55d48434a2ea43f253c18fc42b35fd90 100644
--- a/projects/player/src/app/components/layouts/player-layout/player-layout.component.html
+++ b/projects/player/src/app/components/layouts/player-layout/player-layout.component.html
@@ -4,31 +4,33 @@
       <ng-content></ng-content>
     </div>
       <aspect-keypad
-          *ngIf="keypadService.isOpen && keypadService.position === 'right'"
-          @keypadSlideInOut
-          [@.disabled] = "isKeypadAnimationDisabled"
-          [inputElement]="keypadService.inputElement"
-          [position]="keypadService.position"
-          [preset]="keypadService.preset"
-          [customKeys]="keypadService.elementComponent.elementModel.inputAssistanceCustomKeys | inputAssistanceCustomKeys"
-          [restrictToAllowedKeys]="!!keypadService.elementComponent.elementModel.restrictedToInputAssistanceChars"
-          [hasArrowKeys]="!!keypadService.elementComponent.elementModel.hasArrowKeys"
-          [hasBackspaceKey]="!!keypadService.elementComponent.elementModel.hasBackspaceKey"
-          [hasReturnKey]="keypadService.elementComponent.elementModel | hasReturnKey"
-          (backSpaceClicked)="keypadService.deleteCharacters.emit(true)"
-          (keyClicked)="keypadService.enterKey.emit($event)"
-          (select)="keypadService.select.emit($event)">
+        *ngIf="keypadService.isOpen && keypadService.position === 'right'"
+        @keypadSlideInOut
+        [@.disabled] = "isKeypadAnimationDisabled"
+        [inputElement]="keypadService.inputElement"
+        [position]="keypadService.position"
+        [preset]="keypadService.preset"
+        [customKeys]="keypadService.elementComponent.elementModel.inputAssistanceCustomKeys | inputAssistanceCustomKeys"
+        [restrictToAllowedKeys]="!!keypadService.elementComponent.elementModel.restrictedToInputAssistanceChars"
+        [hasArrowKeys]="!!keypadService.elementComponent.elementModel.hasArrowKeys"
+        [hasBackspaceKey]="!!keypadService.elementComponent.elementModel.hasBackspaceKey"
+        [hasReturnKey]="keypadService.elementComponent.elementModel | hasReturnKey"
+        (backSpaceClicked)="keypadService.deleteCharacters.emit(true)"
+        (keyClicked)="keypadService.enterKey.emit($event)"
+        (select)="keypadService.select.emit($event)">
       </aspect-keypad>
   </div>
   <aspect-keyboard
-      *ngIf="keyboardService.isOpen"
-      @keyboardSlideInOut
-      [@.disabled] = "isKeyboardAnimationDisabled"
-      (@keyboardSlideInOut.done)="keyboardService.scrollElement()"
-      [addInputAssistanceToKeyboard]="keyboardService.addInputAssistanceToKeyboard"
-      [preset]="keyboardService.preset"
-      [customKeys]="keyboardService.elementComponent.elementModel.inputAssistanceCustomKeys | inputAssistanceCustomKeys"
-      (keyClicked)="keyboardService.enterKey.emit($event)"
-      (backspaceClicked)="keyboardService.deleteCharacters.emit(true)">
+    *ngIf="keyboardService.isOpen"
+    @keyboardSlideInOut
+    [@.disabled] = "isKeyboardAnimationDisabled"
+    (@keyboardSlideInOut.done)="keyboardService.scrollElement()"
+    [addInputAssistanceToKeyboard]="keyboardService.addInputAssistanceToKeyboard"
+    [preset]="keyboardService.preset"
+    [customKeys]="keyboardService.elementComponent.elementModel.inputAssistanceCustomKeys | inputAssistanceCustomKeys"
+    (keyClicked)="keyboardService.enterKey.emit($event)"
+    (backspaceClicked)="keyboardService.deleteCharacters.emit(true)">
   </aspect-keyboard>
+  <aspect-math-keyboard-container>
+  </aspect-math-keyboard-container>
 </div>
diff --git a/projects/player/src/app/components/layouts/player-layout/player-layout.component.spec.ts b/projects/player/src/app/components/layouts/player-layout/player-layout.component.spec.ts
index b5cfac127ee17c1bf40474e2e76824efaede0341..42e8848c372ad3d54ab19ddf9e619e3c2d1c626d 100644
--- a/projects/player/src/app/components/layouts/player-layout/player-layout.component.spec.ts
+++ b/projects/player/src/app/components/layouts/player-layout/player-layout.component.spec.ts
@@ -6,11 +6,13 @@ import { Component, Directive, Input } from '@angular/core';
 import { Page } from 'common/models/page';
 import { APIService } from 'common/shared.module';
 import { PagingMode } from 'player/modules/verona/models/verona';
+import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations';
 import { PlayerLayoutComponent } from './player-layout.component';
 
 describe('PlayerLayoutComponent', () => {
   let component: PlayerLayoutComponent;
   let fixture: ComponentFixture<PlayerLayoutComponent>;
+
   @Directive({ selector: '[aspectPlayerState]' })
   class PlayerStateStubDirective {
     @Input() validPages!: Record<string, string>;
@@ -33,6 +35,9 @@ describe('PlayerLayoutComponent', () => {
     @Input() alwaysVisiblePagePosition!: 'top' | 'bottom' | 'left' | 'right';
   }
 
+  @Component({ selector: 'aspect-math-keyboard-container', template: '' })
+  class MockMathKeyboardContainerComponent {}
+
   beforeEach(async () => {
     await TestBed.configureTestingModule({
       declarations: [
@@ -40,9 +45,15 @@ describe('PlayerLayoutComponent', () => {
         PagesLayoutStubComponent,
         AlwaysVisiblePagePipe,
         ScrollPagesPipe,
-        PlayerStateStubDirective
+        PlayerStateStubDirective,
+        MockMathKeyboardContainerComponent
+      ],
+      imports: [
+        BrowserAnimationsModule
       ],
-      providers: [{ provide: APIService, useClass: ApiStubService }]
+      providers: [
+        provideAnimations(),
+        { provide: APIService, useClass: ApiStubService }]
     })
       .compileComponents();
   });
diff --git a/projects/player/src/app/components/layouts/player-layout/player-layout.component.ts b/projects/player/src/app/components/layouts/player-layout/player-layout.component.ts
index 32d3e432ac50ac996768e95b324d289f519cb9d8..9df6e040d39e576c5be5a0d5c6c422e8ccde82ae 100644
--- a/projects/player/src/app/components/layouts/player-layout/player-layout.component.ts
+++ b/projects/player/src/app/components/layouts/player-layout/player-layout.component.ts
@@ -39,6 +39,8 @@ export class PlayerLayoutComponent implements OnDestroy {
   private isKeyboardToggling: number = 0;
   private ngUnsubscribe = new Subject<void>();
 
+  protected readonly window = window;
+
   constructor(
     public keypadService: KeypadService,
     public keyboardService: KeyboardService
diff --git a/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.html b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0b0428089e70be13081bae36ca879047ddb8970a
--- /dev/null
+++ b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.html
@@ -0,0 +1,3 @@
+<div #mathKeyboard
+     [style.height.px]="mathKeyboardService.keyboardHeight"
+     class="math-keyboard-container"></div>
diff --git a/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.scss b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..139597f9cb07c5d48bed18984ec4747f4b4f3438
--- /dev/null
+++ b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.scss
@@ -0,0 +1,2 @@
+
+
diff --git a/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.ts b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ee1e06a55a84f05c74cc6f4826635f40d2d98b0c
--- /dev/null
+++ b/projects/player/src/app/components/math-keyboard-container/math-keyboard-container.component.ts
@@ -0,0 +1,34 @@
+import {
+  AfterViewInit, Component, ElementRef, OnDestroy, ViewChild
+} from '@angular/core';
+import { MathKeyboardService } from 'player/src/app/services/math-keyboard.service';
+
+@Component({
+  selector: 'aspect-math-keyboard-container',
+  standalone: true,
+  imports: [],
+  templateUrl: './math-keyboard-container.component.html',
+  styleUrl: './math-keyboard-container.component.scss'
+})
+export class MathKeyboardContainerComponent implements AfterViewInit, OnDestroy {
+  @ViewChild('mathKeyboard') mathKeyboard!: ElementRef;
+
+  constructor(public mathKeyboardService: MathKeyboardService) {}
+
+  ngAfterViewInit(): void {
+    window.mathVirtualKeyboard.container = this.mathKeyboard.nativeElement;
+    window.mathVirtualKeyboard.addEventListener('geometrychange', () => this.updateKeyboard());
+  }
+
+  updateKeyboard(): void {
+    this.mathKeyboardService.keyboardHeight =
+      window.mathVirtualKeyboard.boundingRect.height;
+    if (this.mathKeyboardService.keyboardHeight) {
+      setTimeout(() => this.mathKeyboardService.scrollElement());
+    }
+  }
+
+  ngOnDestroy(): void {
+    window.mathVirtualKeyboard.removeEventListener('geometrychange', () => this.updateKeyboard());
+  }
+}
diff --git a/projects/player/src/app/directives/text-input-group.directive.ts b/projects/player/src/app/directives/text-input-group.directive.ts
index 2c02fed1dc5b57e8125b9cdfaac06c7a5164163a..9fd1c36ee62b49aa0a082867198327144eb369df 100644
--- a/projects/player/src/app/directives/text-input-group.directive.ts
+++ b/projects/player/src/app/directives/text-input-group.directive.ts
@@ -8,8 +8,10 @@ import { DeviceService } from 'player/src/app/services/device.service';
 import { KeypadService } from 'player/src/app/services/keypad.service';
 import { KeyboardService } from 'player/src/app/services/keyboard.service';
 import { TextInputComponentType } from 'player/src/app/models/text-input-component.type';
-import { TextAreaMathComponent } from 'common/components/input-elements/text-area-math/text-area-math.component';
 import { RangeSelectionService } from 'common/services/range-selection-service';
+import { MathfieldElement } from 'mathlive';
+import { MathKeyboardService } from 'player/src/app/services/math-keyboard.service';
+import { MathFieldComponent } from 'common/components/input-elements/math-field.component';
 
 @Directive()
 export abstract class TextInputGroupDirective extends ElementFormGroupDirective implements OnDestroy {
@@ -25,6 +27,7 @@ export abstract class TextInputGroupDirective extends ElementFormGroupDirective
   abstract deviceService: DeviceService;
   abstract keypadService: KeypadService;
   abstract keyboardService: KeyboardService;
+  abstract mathKeyboardService: MathKeyboardService;
 
   private shallOpenKeypad(elementModel: InputElement): boolean {
     return !!elementModel.inputAssistancePreset &&
@@ -34,50 +37,59 @@ export abstract class TextInputGroupDirective extends ElementFormGroupDirective
   }
 
   async toggleKeyInput(focusedTextInput: { inputElement: HTMLElement; focused: boolean },
-                       elementComponent: TextInputComponentType | TextAreaMathComponent): Promise<void> {
+                       elementComponent: TextInputComponentType | MathFieldComponent): Promise<void> {
+    const isMathInput = focusedTextInput.inputElement instanceof MathfieldElement;
     const promises: Promise<boolean>[] = [];
-    if (elementComponent.elementModel.showSoftwareKeyboard && !elementComponent.elementModel.readOnly) {
-      promises.push(this.keyboardService
-        .toggleAsync(focusedTextInput, elementComponent, this.deviceService.isMobileWithoutHardwareKeyboard));
-    }
-    if (this.shallOpenKeypad(elementComponent.elementModel)) {
-      promises.push(this.keypadService.toggleAsync(focusedTextInput, elementComponent));
-    }
-    if (promises.length) {
-      await Promise.all(promises)
-        .then(() => {
-          if (this.keyboardService.isOpen) {
-            this.subscribeForKeyboardEvents(elementComponent.elementModel, elementComponent);
-          } else {
-            this.unsubscribeFromKeyboardEvents();
-          }
-          if (this.keypadService.isOpen) {
-            this.subscribeForKeypadEvents(elementComponent.elementModel, elementComponent);
-          } else {
-            this.unsubscribeFromKeypadEvents();
-          }
-          this.isKeypadOpen = this.keypadService.isOpen;
-          if (this.keyboardService.isOpen || this.keypadService.isOpen) {
-            this.inputElement = this.getInputElement(focusedTextInput.inputElement);
-          }
-        });
+    if (isMathInput) {
+      this.mathKeyboardService
+        .toggle(focusedTextInput as { inputElement: MathfieldElement; focused: boolean },
+          elementComponent);
+    } else if (!(elementComponent instanceof MathFieldComponent)) {
+      if (elementComponent.elementModel.showSoftwareKeyboard && !elementComponent.elementModel.readOnly) {
+        promises.push(this.keyboardService
+          .toggleAsync(focusedTextInput, elementComponent, this.deviceService.isMobileWithoutHardwareKeyboard));
+      }
+      if (this.shallOpenKeypad(elementComponent.elementModel)) {
+        promises.push(this.keypadService.toggleAsync(focusedTextInput, elementComponent));
+      }
+      if (promises.length) {
+        await Promise.all(promises)
+          .then(() => {
+            if (this.keyboardService.isOpen) {
+              this.subscribeForKeyboardEvents(elementComponent.elementModel, elementComponent);
+            } else {
+              this.unsubscribeFromKeyboardEvents();
+            }
+            if (this.keypadService.isOpen) {
+              this.subscribeForKeypadEvents(elementComponent.elementModel, elementComponent);
+            } else {
+              this.unsubscribeFromKeypadEvents();
+            }
+            this.isKeypadOpen = this.keypadService.isOpen;
+            if (this.keyboardService.isOpen || this.keypadService.isOpen) {
+              this.inputElement = this.getInputElement(focusedTextInput.inputElement);
+            }
+          });
+      }
     }
   }
 
   // eslint-disable-next-line class-methods-use-this
   checkInputLimitation(event: {
     keyboardEvent: KeyboardEvent;
-    inputElement: HTMLInputElement | HTMLTextAreaElement
+    inputElement: HTMLInputElement | HTMLTextAreaElement | HTMLElement;
   }, elementModel: UIElement): void {
+    const inputValue = TextInputGroupDirective.getValueOfInput(event.inputElement);
     if (elementModel.maxLength &&
       elementModel.isLimitedToMaxLength &&
-      event.inputElement.value.length === elementModel.maxLength &&
+      inputValue.length === elementModel.maxLength &&
       !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'ArrowDown', 'ArrowUp'].includes(event.keyboardEvent.key)) {
       event.keyboardEvent.preventDefault();
     }
   }
 
   detectHardwareKeyboard(elementModel: UIElement): void {
+    console.log('detectHardwareKeyboard', elementModel);
     if (elementModel.showSoftwareKeyboard) {
       this.deviceService.hasHardwareKeyboard = true;
       this.keyboardService.close();
@@ -228,10 +240,14 @@ export abstract class TextInputGroupDirective extends ElementFormGroupDirective
   }
 
   private getInputElementValue(): string {
-    if (this.inputElement instanceof HTMLInputElement || this.inputElement instanceof HTMLTextAreaElement) {
-      return this.inputElement.value;
+    return TextInputGroupDirective.getValueOfInput(this.inputElement);
+  }
+
+  private static getValueOfInput(inputElement: HTMLElement | HTMLInputElement | HTMLTextAreaElement): string {
+    if (inputElement instanceof HTMLInputElement || inputElement instanceof HTMLTextAreaElement) {
+      return inputElement.value;
     }
-    return this.inputElement.textContent || '';
+    return inputElement.textContent || '';
   }
 
   private insert(keyAtPosition: {
diff --git a/projects/player/src/app/models/text-input-component.type.ts b/projects/player/src/app/models/text-input-component.type.ts
index 58209b816949de52a026fd17c7a4812a39cff19b..c11cc285a57f2d5c9a9cf1647e4ddb71797d9ff8 100644
--- a/projects/player/src/app/models/text-input-component.type.ts
+++ b/projects/player/src/app/models/text-input-component.type.ts
@@ -4,6 +4,9 @@ import { SpellCorrectComponent } from 'common/components/input-elements/spell-co
 import {
   TextFieldSimpleComponent
 } from 'common/components/compound-elements/cloze/cloze-child-elements/text-field-simple.component';
+import { MathTableComponent } from 'common/components/input-elements/math-table.component';
+import { TextAreaMathComponent } from 'common/components/input-elements/text-area-math/text-area-math.component';
+import { MathFieldComponent } from 'common/components/input-elements/math-field.component';
 
 export type TextInputComponentType =
-  TextAreaComponent | TextFieldComponent | SpellCorrectComponent | TextFieldSimpleComponent;
+  TextAreaComponent | TextFieldComponent | SpellCorrectComponent | TextFieldSimpleComponent | TextAreaMathComponent;
diff --git a/projects/player/src/app/services/input-service.ts b/projects/player/src/app/services/input-service.ts
index 123c0c06907f7886558fbe9e306bbd3b655a2856..4b412b11da5c246187ee5aa5683f074c856dc4ed 100644
--- a/projects/player/src/app/services/input-service.ts
+++ b/projects/player/src/app/services/input-service.ts
@@ -3,13 +3,14 @@ import { TextInputComponentType } from 'player/src/app/models/text-input-compone
 import { MathTableComponent } from 'common/components/input-elements/math-table.component';
 import { InputAssistancePreset } from 'common/interfaces';
 import { TextAreaMathComponent } from 'common/components/input-elements/text-area-math/text-area-math.component';
+import { MathFieldComponent } from 'common/components/input-elements/math-field.component';
 
 @Injectable({
   providedIn: 'root'
 })
 export abstract class InputService {
   preset: InputAssistancePreset = null;
-  elementComponent!: TextInputComponentType | MathTableComponent | TextAreaMathComponent;
+  elementComponent!: TextInputComponentType | MathTableComponent | TextAreaMathComponent | MathFieldComponent;
   inputElement!: HTMLTextAreaElement | HTMLInputElement | HTMLElement;
   isOpen: boolean = false;
 
@@ -20,7 +21,7 @@ export abstract class InputService {
 
   setCurrentKeyInputElement(
     focusedElement: HTMLElement,
-    elementComponent: TextInputComponentType | MathTableComponent | TextAreaMathComponent
+    elementComponent: TextInputComponentType | MathTableComponent | TextAreaMathComponent | MathFieldComponent
   ): void {
     this.inputElement = focusedElement;
     this.elementComponent = elementComponent;
diff --git a/projects/player/src/app/services/keyboard.service.ts b/projects/player/src/app/services/keyboard.service.ts
index d48a7e508c9e939923e04f9efbc28dfd340ecf9b..54fb8355a814515852f11cd778216ce9e99ca0f1 100644
--- a/projects/player/src/app/services/keyboard.service.ts
+++ b/projects/player/src/app/services/keyboard.service.ts
@@ -2,12 +2,12 @@ import { Injectable } from '@angular/core';
 import { TextInputComponentType } from 'player/src/app/models/text-input-component.type';
 import { MathTableComponent } from 'common/components/input-elements/math-table.component';
 import { TextAreaMathComponent } from 'common/components/input-elements/text-area-math/text-area-math.component';
-import { InputService } from './input-service';
+import { ScrollToInputService } from 'player/src/app/services/scroll-to-input.service';
 
 @Injectable({
   providedIn: 'root'
 })
-export class KeyboardService extends InputService {
+export class KeyboardService extends ScrollToInputService {
   addInputAssistanceToKeyboard: boolean = false;
 
   async toggleAsync(focusedTextInput: { inputElement: HTMLElement; focused: boolean },
@@ -37,28 +37,8 @@ export class KeyboardService extends InputService {
        elementComponent: TextInputComponentType | MathTableComponent | TextAreaMathComponent): void {
     this.addInputAssistanceToKeyboard = elementComponent.elementModel.addInputAssistanceToKeyboard;
     this.preset = elementComponent.elementModel.inputAssistancePreset;
+    this.keyboardHeight = this.addInputAssistanceToKeyboard ? 380 : 280;
     this.setCurrentKeyInputElement(inputElement, elementComponent);
     this.isOpen = true;
   }
-
-  scrollElement(): void {
-    if (this.isOpen && this.isElementHiddenByKeyboard()) {
-      const scrollPositionTarget = this.isViewHighEnoughToCenterElement() ? 'center' : 'start';
-      this.elementComponent.domElement.scrollIntoView({ block: scrollPositionTarget });
-    }
-  }
-
-  private isViewHighEnoughToCenterElement(): boolean {
-    return window.innerHeight - this.getKeyboardHeight() >
-      this.elementComponent.domElement.getBoundingClientRect().height;
-  }
-
-  private isElementHiddenByKeyboard(): boolean {
-    return window.innerHeight - this.elementComponent.domElement.getBoundingClientRect().bottom <
-      this.getKeyboardHeight();
-  }
-
-  private getKeyboardHeight(): number {
-    return this.addInputAssistanceToKeyboard ? 380 : 280;
-  }
 }
diff --git a/projects/player/src/app/services/math-keyboard.service.spec.ts b/projects/player/src/app/services/math-keyboard.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4101a6ca1c11fd456201d2e1f1deea1ceb90a31
--- /dev/null
+++ b/projects/player/src/app/services/math-keyboard.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MathKeyboardService } from './math-keyboard.service';
+
+describe('MathKeyboardService', () => {
+  let service: MathKeyboardService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MathKeyboardService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/projects/player/src/app/services/math-keyboard.service.ts b/projects/player/src/app/services/math-keyboard.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b94e24c912ce05a1443ad3a6d46e534858663ef0
--- /dev/null
+++ b/projects/player/src/app/services/math-keyboard.service.ts
@@ -0,0 +1,31 @@
+import { Injectable } from '@angular/core';
+import { MathfieldElement } from 'mathlive';
+import { TextAreaMathComponent } from 'common/components/input-elements/text-area-math/text-area-math.component';
+import { InputService } from 'player/src/app/services/input-service';
+import { ScrollToInputService } from 'player/src/app/services/scroll-to-input.service';
+import { TextInputComponentType } from 'player/src/app/models/text-input-component.type';
+import { MathFieldComponent } from 'common/components/input-elements/math-field.component';
+import { MathTableComponent } from 'common/components/input-elements/math-table.component';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MathKeyboardService extends ScrollToInputService {
+  isOpen: boolean = false;
+
+  toggle(focusedTextInput: { inputElement: MathfieldElement; focused: boolean },
+         elementComponent: TextInputComponentType | MathFieldComponent): boolean {
+    if (focusedTextInput.focused) {
+      console.log('focusedTextInput.focused', focusedTextInput.inputElement);
+      this.open(focusedTextInput.inputElement, elementComponent);
+    } else {
+      this.close();
+    }
+    return this.isOpen;
+  }
+
+  private open(inputElement: MathfieldElement, elementComponent: TextInputComponentType | MathFieldComponent): void {
+    this.setCurrentKeyInputElement(inputElement, elementComponent);
+    this.isOpen = true;
+  }
+}
diff --git a/projects/player/src/app/services/scroll-to-input.service.ts b/projects/player/src/app/services/scroll-to-input.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d483e4b8b4bb11c82f5b9a38dea140c2285f886a
--- /dev/null
+++ b/projects/player/src/app/services/scroll-to-input.service.ts
@@ -0,0 +1,27 @@
+import { Injectable } from '@angular/core';
+import { InputService } from 'player/src/app/services/input-service';
+
+@Injectable({
+  providedIn: 'root'
+})
+export abstract class ScrollToInputService extends InputService {
+  keyboardHeight: number = 0;
+
+  scrollElement(): void {
+    if (this.isOpen && this.isElementHiddenByKeyboard()) {
+      const scrollPositionTarget = this.isViewHighEnoughToCenterElement() ? 'center' : 'start';
+      console.log('scrollPositionTarget', scrollPositionTarget);
+      this.elementComponent.domElement.scrollIntoView({ block: scrollPositionTarget });
+    }
+  }
+
+  private isViewHighEnoughToCenterElement(): boolean {
+    return window.innerHeight - this.keyboardHeight >
+      this.elementComponent.domElement.getBoundingClientRect().height;
+  }
+
+  private isElementHiddenByKeyboard(): boolean {
+    return window.innerHeight - this.elementComponent.domElement.getBoundingClientRect().bottom <
+      this.keyboardHeight;
+  }
+}