diff --git a/projects/common/element-component.directive.ts b/projects/common/element-component.directive.ts
index 0ae755a49103645cb6dc3099c3e32c69a71eded6..5b864a46c18f8abbfc34415692d1c06324263e91 100644
--- a/projects/common/element-component.directive.ts
+++ b/projects/common/element-component.directive.ts
@@ -1,9 +1,15 @@
 import {
-  Directive
+  Directive, ElementRef
 } from '@angular/core';
 import { UIElement } from './models/uI-element';
 
 @Directive()
 export abstract class ElementComponent {
   abstract elementModel: UIElement;
+
+  constructor(private elementRef: ElementRef) {}
+
+  get domElement(): Element {
+    return this.elementRef.nativeElement;
+  }
 }
diff --git a/projects/common/element-components/compound-elements/compound-element.directive.ts b/projects/common/element-components/compound-elements/compound-element.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a0aa4ab1dff2c841e9207e1e73d8084ea7cfacc
--- /dev/null
+++ b/projects/common/element-components/compound-elements/compound-element.directive.ts
@@ -0,0 +1,21 @@
+import {
+  AfterViewInit,
+  Directive, EventEmitter, Output, QueryList
+} from '@angular/core';
+import { FormGroup } from '@angular/forms';
+import { ElementComponent } from '../../element-component.directive';
+import { InputElement } from '../../models/uI-element';
+
+@Directive({ selector: 'app-compound-element' })
+
+export abstract class CompoundElementComponent implements AfterViewInit {
+  @Output() childrenAdded = new EventEmitter<QueryList<ElementComponent>>();
+  compoundChildren!: QueryList<ElementComponent>;
+  parentForm!: FormGroup;
+
+  ngAfterViewInit(): void {
+    this.childrenAdded.emit(this.compoundChildren);
+  }
+
+  abstract getFormElementModelChildren(): InputElement[];
+}
diff --git a/projects/common/element-components/compound-elements/likert.component.ts b/projects/common/element-components/compound-elements/likert.component.ts
index f9a69a49e648ac2bfab1b05281e30a76766ad978..90cf1c9e2af0ce6d7e6a6c9d74f91a42c514dc0d 100644
--- a/projects/common/element-components/compound-elements/likert.component.ts
+++ b/projects/common/element-components/compound-elements/likert.component.ts
@@ -1,8 +1,12 @@
-import { Component, EventEmitter, Output } from '@angular/core';
+import {
+  Component, EventEmitter, Output, QueryList, ViewChildren
+} from '@angular/core';
 import { FormGroup } from '@angular/forms';
 import { LikertElement } from '../../models/compound-elements/likert-element';
-import { InputElementValue, ValueChangeElement } from '../../models/uI-element';
+import { ValueChangeElement } from '../../models/uI-element';
 import { LikertElementRow } from '../../models/compound-elements/likert-element-row';
+import { LikertRadioButtonGroupComponent } from './likert-radio-button-group.component';
+import { CompoundElementComponent } from './compound-element.directive';
 
 @Component({
   selector: 'app-likert',
@@ -65,15 +69,13 @@ import { LikertElementRow } from '../../models/compound-elements/likert-element-
     '::ng-deep app-likert mat-radio-button span.mat-radio-container {left: calc(50% - 10px)}'
   ]
 })
-export class LikertComponent {
+export class LikertComponent extends CompoundElementComponent {
   @Output() formValueChanged = new EventEmitter<ValueChangeElement>();
+  @ViewChildren(LikertRadioButtonGroupComponent) compoundChildren!: QueryList<LikertRadioButtonGroupComponent>;
   elementModel!: LikertElement;
   parentForm!: FormGroup;
 
-  getChildElementValues(): { id: string, value: InputElementValue }[] {
-    return this.elementModel.questions
-      .map((question: LikertElementRow): { id: string, value: InputElementValue } => (
-        { id: question.id, value: question.value }
-      ));
+  getFormElementModelChildren(): LikertElementRow[] {
+    return this.elementModel.questions;
   }
 }
diff --git a/projects/player/src/app/app.module.ts b/projects/player/src/app/app.module.ts
index 0565961ea2ea7321aa77aebb508eff6bdb5ea756..59da62818076cc63a124221e256c67432b733d04 100644
--- a/projects/player/src/app/app.module.ts
+++ b/projects/player/src/app/app.module.ts
@@ -9,7 +9,7 @@ import { AppComponent } from './app.component';
 import { PageComponent } from './components/page/page.component';
 import { SectionComponent } from './components/section/section.component';
 import { SharedModule } from '../../../common/shared.module';
-import { ElementComponent } from './components/element/element.component';
+import { ElementContainerComponent } from './components/element/element-container.component';
 import { UnitStateComponent } from './components/unit-state/unit-state.component';
 import { PlayerStateComponent } from './components/player-state/player-state.component';
 import { PlayerTranslateLoader } from './classes/player-translate-loader';
@@ -30,7 +30,7 @@ import { NumbersAndOperatorsKeyboardComponent }
     AppComponent,
     PageComponent,
     SectionComponent,
-    ElementComponent,
+    ElementContainerComponent,
     UnitStateComponent,
     PlayerStateComponent,
     LayoutComponent,
diff --git a/projects/player/src/app/components/element/element.component.css b/projects/player/src/app/components/element/element-container.component.css
similarity index 100%
rename from projects/player/src/app/components/element/element.component.css
rename to projects/player/src/app/components/element/element-container.component.css
diff --git a/projects/player/src/app/components/element/element.component.html b/projects/player/src/app/components/element/element-container.component.html
similarity index 100%
rename from projects/player/src/app/components/element/element.component.html
rename to projects/player/src/app/components/element/element-container.component.html
diff --git a/projects/player/src/app/components/element/element.component.ts b/projects/player/src/app/components/element/element-container.component.ts
similarity index 73%
rename from projects/player/src/app/components/element/element.component.ts
rename to projects/player/src/app/components/element/element-container.component.ts
index 2556a170aa748fe473a9a7dbab52479670d2534a..74358834cd97ab21ae0d06e1eb0e2eeafabc36b3 100644
--- a/projects/player/src/app/components/element/element.component.ts
+++ b/projects/player/src/app/components/element/element-container.component.ts
@@ -1,6 +1,5 @@
 import {
-  Component, OnInit, Input, ComponentFactoryResolver,
-  ViewChild, ViewContainerRef
+  Component, OnInit, Input, ComponentFactoryResolver, ViewChild, ViewContainerRef, QueryList
 } from '@angular/core';
 import {
   FormBuilder, FormControl, FormGroup, ValidatorFn
@@ -16,19 +15,21 @@ import { UnitStateService } from '../../services/unit-state.service';
 import { MarkingService } from '../../services/marking.service';
 import {
   InputElement,
-  InputElementValue,
   UIElement,
   ValueChangeElement
 } from '../../../../../common/models/uI-element';
 import { TextFieldElement } from '../../../../../common/models/text-field-element';
 import { FormElementComponent } from '../../../../../common/form-element-component.directive';
+import { ElementComponent } from '../../../../../common/element-component.directive';
+import { CompoundElementComponent }
+  from '../../../../../common/element-components/compound-elements/compound-element.directive';
 
 @Component({
-  selector: 'app-element',
-  templateUrl: './element.component.html',
-  styleUrls: ['./element.component.css']
+  selector: 'app-element-container',
+  templateUrl: './element-container.component.html',
+  styleUrls: ['./element-container.component.css']
 })
-export class ElementComponent implements OnInit {
+export class ElementContainerComponent implements OnInit {
   @Input() elementModel!: UIElement;
   @Input() parentForm!: FormGroup;
   @Input() parentArrayIndex!: number;
@@ -53,24 +54,23 @@ export class ElementComponent implements OnInit {
     const elementComponentFactory =
       ElementFactory.getComponentFactory(this.elementModel.type, this.componentFactoryResolver);
     const elementComponent = this.elementComponentContainer.createComponent(elementComponentFactory).instance;
-    elementComponent.elementModel = this.elementModel;
-
-    const unitStateElementCode = this.unitStateService.getUnitStateElement(this.elementModel.id);
-    if (unitStateElementCode && unitStateElementCode.value !== undefined) {
-      switch (this.elementModel.type) {
-        case 'text':
-          elementComponent.elementModel.text = unitStateElementCode.value;
-          break;
-        case 'video':
-        case 'audio':
-          elementComponent.elementModel.playbackTime = unitStateElementCode.value;
-          break;
-        default:
-          elementComponent.elementModel.value = unitStateElementCode.value;
-      }
+    elementComponent.elementModel = this.unitStateService.restoreUnitStateValue(this.elementModel);
+
+    if (elementComponent.domElement) {
+      this.unitStateService.registerElement(elementComponent.elementModel, elementComponent.domElement);
     }
 
-    this.unitStateService.registerElement(elementComponent.elementModel.id, elementComponent.elementModel.value);
+    if (elementComponent.childrenAdded) {
+      elementComponent.childrenAdded
+        .pipe(takeUntil(this.ngUnsubscribe))
+        .subscribe((children: QueryList<ElementComponent>) => {
+          children.forEach(child => {
+            if (child.domElement) {
+              this.unitStateService.registerElement(child.elementModel, child.domElement);
+            }
+          });
+        });
+    }
 
     if (elementComponent.applySelection) {
       elementComponent.applySelection
@@ -88,47 +88,36 @@ export class ElementComponent implements OnInit {
         });
     }
 
-    if (elementComponent instanceof FormElementComponent || this.elementModel.type === 'likert') {
-      const elementForm = this.formBuilder.group({});
+    if (elementComponent.formValueChanged) {
+      elementComponent.formValueChanged
+        .pipe(takeUntil(this.ngUnsubscribe))
+        .subscribe((changeElement: ValueChangeElement) => {
+          this.unitStateService.changeElementValue(changeElement);
+        });
+    }
+
+    if (elementComponent.setValidators) {
+      elementComponent.setValidators
+        .pipe(takeUntil(this.ngUnsubscribe))
+        .subscribe((validators: ValidatorFn[]) => {
+          this.formService.setValidators({
+            id: this.elementModel.id,
+            validators: validators,
+            formGroup: elementForm
+          });
+        });
+    }
+
+    const elementForm = this.formBuilder.group({});
+    if (elementComponent instanceof FormElementComponent) {
       elementComponent.parentForm = elementForm;
       this.registerFormGroup(elementForm);
-
       this.formService.registerFormControl({
         id: this.elementModel.id,
         formControl: new FormControl((this.elementModel as InputElement).value),
         formGroup: elementForm
       });
 
-      if (this.elementModel.type === 'likert') {
-        elementComponent.getChildElementValues()
-          .forEach((element: { id: string, value: InputElementValue }) => {
-            this.unitStateService.registerElement(element.id, element.value);
-            this.formService.registerFormControl({
-              id: element.id,
-              formControl: new FormControl((element as InputElement).value),
-              formGroup: elementForm
-            });
-          });
-      }
-
-      if (elementComponent.setValidators) {
-        elementComponent.setValidators
-          .pipe(takeUntil(this.ngUnsubscribe))
-          .subscribe((validators: ValidatorFn[]) => {
-            this.formService.setValidators({
-              id: this.elementModel.id,
-              validators: validators,
-              formGroup: elementForm
-            });
-          });
-      }
-
-      elementComponent.formValueChanged
-        .pipe(takeUntil(this.ngUnsubscribe))
-        .subscribe((changeElement: ValueChangeElement) => {
-          this.unitStateService.changeElementValue(changeElement);
-        });
-
       if (this.elementModel.inputAssistancePreset !== 'none' &&
         (this.elementModel.type === 'text-field' || this.elementModel.type === 'text-area')) {
         this.keyboardLayout = (this.elementModel as TextFieldElement).inputAssistancePreset;
@@ -138,7 +127,18 @@ export class ElementComponent implements OnInit {
           this.initEventsForKeyboard(elementComponent as TextAreaComponent);
         }
       }
-    } // no else
+    } else if (elementComponent instanceof CompoundElementComponent) {
+      elementComponent.parentForm = elementForm;
+      elementComponent.getFormElementModelChildren()
+        .forEach((element: InputElement) => {
+          this.registerFormGroup(elementForm);
+          this.formService.registerFormControl({
+            id: element.id,
+            formControl: new FormControl(element.value),
+            formGroup: elementForm
+          });
+        });
+    }
   }
 
   private registerFormGroup(elementForm: FormGroup): void {
diff --git a/projects/player/src/app/components/page/page.component.ts b/projects/player/src/app/components/page/page.component.ts
index 884707906b06666461c1261a74716f24f6afec86..e2fe8f023764b1425ec58a21a70be9346da99a28 100644
--- a/projects/player/src/app/components/page/page.component.ts
+++ b/projects/player/src/app/components/page/page.component.ts
@@ -40,11 +40,11 @@ export class PageComponent implements OnInit {
     });
   }
 
-  onIntersection(detection: { detectionType: 'top' | 'bottom' | 'full', id: string }): void {
-    if (detection.detectionType === 'bottom') {
+  onIntersection(detectionType: 'top' | 'bottom'): void {
+    if (detectionType === 'bottom') {
       this.unitStateService.addPresentedPage(this.index);
     }
-    if (detection.detectionType === 'top' || this.isLastPage) {
+    if (detectionType === 'top' || this.isLastPage) {
       this.selectedIndexChange.emit(this.index);
     }
   }
diff --git a/projects/player/src/app/components/section/section.component.html b/projects/player/src/app/components/section/section.component.html
index cfb69b543ff512688e770f152ac34637d4125f11..0a6aea1334a2a6ffe76dd8667e85939c7f68b084 100644
--- a/projects/player/src/app/components/section/section.component.html
+++ b/projects/player/src/app/components/section/section.component.html
@@ -2,12 +2,7 @@
 
 <ng-template #staticElements>
   <ng-container *ngFor="let element of section.elements; let i = index">
-    <app-element
-        appIntersectionDetection
-        detectionType="full"
-        [intersectionContainer]="document"
-        [id]="element.id"
-        (intersecting)="onIntersection($event)"
+    <app-element-container
         [style.display]="'block'"
         [style.overflow]="'auto'"
         [style.width.px]="element.width"
@@ -18,7 +13,7 @@
         [elementModel]="element"
         [parentForm]="sectionForm"
         [parentArrayIndex]="i">
-    </app-element>
+    </app-element-container>
   </ng-container>
 </ng-template>
 
@@ -29,12 +24,7 @@
        [style.grid-auto-columns]="section.autoColumnSize ? 'auto' : undefined"
        [style.grid-auto-rows]="section.autoRowSize ? 'auto' : undefined">
     <ng-container *ngFor="let element of section.elements; let i = index">
-      <app-element
-          appIntersectionDetection
-          detectionType="full"
-          [intersectionContainer]="document"
-          [id]="element.id"
-          (intersecting)="onIntersection($event)"
+      <app-element-container
           [style.min-width.px]="element.width"
           [style.min-height.px]="element.height"
           [style.margin-left.px]="element.marginLeft"
@@ -48,7 +38,7 @@
           [elementModel]="element"
           [parentForm]="sectionForm"
           [parentArrayIndex]="i">
-      </app-element>
+      </app-element-container>
     </ng-container>
   </div>
 </ng-template>
diff --git a/projects/player/src/app/components/section/section.component.ts b/projects/player/src/app/components/section/section.component.ts
index 785c6d2f86dfaebc32c1fb7928ea33c21626f325..4200ed3182d3b08e989ec057356750700075644e 100644
--- a/projects/player/src/app/components/section/section.component.ts
+++ b/projects/player/src/app/components/section/section.component.ts
@@ -5,7 +5,6 @@ import { FormBuilder, FormGroup } from '@angular/forms';
 import { DOCUMENT } from '@angular/common';
 import { FormService } from '../../services/form.service';
 import { Section } from '../../../../../common/models/section';
-import { UnitStateService } from '../../services/unit-state.service';
 
 @Component({
   selector: 'app-section',
@@ -20,7 +19,6 @@ export class SectionComponent implements OnInit {
 
   constructor(private formService: FormService,
               private formBuilder: FormBuilder,
-              private unitStateService: UnitStateService,
               @Inject(DOCUMENT) public document: Document) {
   }
 
@@ -35,8 +33,4 @@ export class SectionComponent implements OnInit {
       parentArrayIndex: this.parentArrayIndex
     });
   }
-
-  onIntersection(detection: { detectionType: 'top' | 'bottom' | 'full', id: string }): void {
-    this.unitStateService.changeElementStatus({ id: detection.id, status: 'DISPLAYED' });
-  }
 }
diff --git a/projects/player/src/app/directives/intersection-detection.directive.ts b/projects/player/src/app/directives/intersection-detection.directive.ts
index 0542cc78816701bae52cac4652abc8b2267bfc40..1f64c05f86bcafa1392ba805fc44892511c3a625 100644
--- a/projects/player/src/app/directives/intersection-detection.directive.ts
+++ b/projects/player/src/app/directives/intersection-detection.directive.ts
@@ -6,10 +6,9 @@ import {
   selector: '[appIntersectionDetection]'
 })
 export class IntersectionDetectionDirective implements OnInit, OnDestroy {
-  @Input() detectionType!: 'top' | 'bottom' | 'full';
-  @Input() id!: string;
-  @Output() intersecting = new EventEmitter<{ detectionType: 'top' | 'bottom' | 'full', id: string }>();
-  @Input() intersectionContainer!: HTMLElement | Document;
+  @Input() detectionType!: 'top' | 'bottom';
+  @Output() intersecting = new EventEmitter<'top' | 'bottom'>();
+  @Input() intersectionContainer!: HTMLElement;
 
   intersectionObserver!: IntersectionObserver;
 
@@ -18,11 +17,7 @@ export class IntersectionDetectionDirective implements OnInit, OnDestroy {
   constructor(private elementRef: ElementRef) {}
 
   ngOnInit(): void {
-    if (this.detectionType === 'top') {
-      this.constraint = '0px 0px -95% 0px';
-    } else {
-      this.constraint = this.detectionType === 'full' ? '0px 0px 0px 0px' : '-95% 0px 0px 0px';
-    }
+    this.constraint = this.detectionType === 'top' ? '0px 0px -95% 0px' : '-95% 0px 0px 0px';
     this.initIntersectionObserver();
   }
 
@@ -30,7 +25,7 @@ export class IntersectionDetectionDirective implements OnInit, OnDestroy {
     this.intersectionObserver = new IntersectionObserver(
       (entries: IntersectionObserverEntry[]): void => entries.forEach(entry => {
         if (entry.isIntersecting) {
-          this.intersecting.emit({ detectionType: this.detectionType, id: this.id });
+          this.intersecting.emit(this.detectionType);
         }
       }), {
         root: this.intersectionContainer,
diff --git a/projects/player/src/app/services/intersection.service.ts b/projects/player/src/app/services/intersection.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df382b5b02c4308c2e08a7dc440e2ca0f366a9df
--- /dev/null
+++ b/projects/player/src/app/services/intersection.service.ts
@@ -0,0 +1,47 @@
+import {
+  EventEmitter, Inject, Injectable, Output
+} from '@angular/core';
+import { DOCUMENT } from '@angular/common';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class IntersectionService {
+  intersectionObserver!: IntersectionObserver;
+  elements: { id: string, element: Element }[] = [];
+  @Output() intersecting = new EventEmitter<string>();
+
+  constructor(@Inject(DOCUMENT) private document: Document) {
+    this.initIntersectionObserver();
+  }
+
+  private initIntersectionObserver(): void {
+    this.intersectionObserver = new IntersectionObserver(
+      (entries: IntersectionObserverEntry[]): void => {
+        entries.forEach(entry => {
+          if (entry.isIntersecting) {
+            this.intersectionDetected(entry.target);
+          }
+        });
+      }, {
+        root: document,
+        rootMargin: '0px 0px 0px 0px'
+      }
+    );
+  }
+
+  observe(id: string, element: Element): void {
+    this.elements.push({ id, element });
+    this.intersectionObserver.observe(element);
+  }
+
+  private intersectionDetected(element: Element):void {
+    const intersectedElementIndex = this.elements.findIndex(e => e.element === element);
+    if (intersectedElementIndex > -1) {
+      const intersectedElement = this.elements[intersectedElementIndex];
+      this.intersecting.emit(intersectedElement.id);
+      this.intersectionObserver.unobserve(intersectedElement.element);
+      this.elements.splice(intersectedElementIndex, 1);
+    }
+  }
+}
diff --git a/projects/player/src/app/services/unit-state.service.ts b/projects/player/src/app/services/unit-state.service.ts
index 665a1feb8ddd8e518efc46ce05777aee3eb79fd8..5fe370dc834eabbf856f94a767c4332b17184343 100644
--- a/projects/player/src/app/services/unit-state.service.ts
+++ b/projects/player/src/app/services/unit-state.service.ts
@@ -6,7 +6,13 @@ import {
   UnitStateElementCodeStatus,
   UnitStateElementCodeStatusValue
 } from '../models/verona';
-import { InputElementValue, ValueChangeElement } from '../../../../common/models/uI-element';
+import {
+  InputElement, InputElementValue, UIElement, ValueChangeElement
+} from '../../../../common/models/uI-element';
+import { TextElement } from '../../../../common/models/text-element';
+import { VideoElement } from '../../../../common/models/video-element';
+import { AudioElement } from '../../../../common/models/audio-element';
+import { IntersectionService } from './intersection.service';
 
 @Injectable({
   providedIn: 'root'
@@ -16,7 +22,9 @@ export class UnitStateService {
   private _unitStateElementCodeChanged = new Subject<UnitStateElementCode>();
   unitStateElementCodes!: UnitStateElementCode[];
 
-  getUnitStateElement(id: string): UnitStateElementCode | undefined {
+  constructor(private intersectionService: IntersectionService) {}
+
+  private getUnitStateElement(id: string): UnitStateElementCode | undefined {
     return this.unitStateElementCodes
       .find((elementCode: UnitStateElementCode): boolean => elementCode.id === id);
   }
@@ -48,8 +56,31 @@ export class UnitStateService {
     return this._presentedPageAdded.asObservable();
   }
 
-  registerElement(id: string, value: InputElementValue): void {
-    this.addUnitStateElementCode(id, value);
+  registerElement(elementModel: UIElement, element: Element): void {
+    this.initUnitStateValue(elementModel);
+    this.intersectionService.observe(elementModel.id, element);
+    this.intersectionService.intersecting
+      .subscribe((id: string) => {
+        this.changeElementStatus({ id: id, status: 'DISPLAYED' });
+      });
+  }
+
+  restoreUnitStateValue(elementModel: UIElement): UIElement {
+    const unitStateElementCode = this.getUnitStateElement(elementModel.id);
+    if (unitStateElementCode && unitStateElementCode.value !== undefined) {
+      switch (elementModel.type) {
+        case 'text':
+          elementModel.text = unitStateElementCode.value;
+          break;
+        case 'video':
+        case 'audio':
+          elementModel.playbackTime = unitStateElementCode.value;
+          break;
+        default:
+          elementModel.value = unitStateElementCode.value;
+      }
+    }
+    return elementModel;
   }
 
   addPresentedPage(presentedPage: number): void {
@@ -70,6 +101,22 @@ export class UnitStateService {
     this.setUnitStateElementCodeStatus(elementStatus.id, elementStatus.status);
   }
 
+  private initUnitStateValue(elementModel: UIElement): void {
+    switch (elementModel.type) {
+      case 'text':
+        this.addUnitStateElementCode(elementModel.id, (elementModel as TextElement).text);
+        break;
+      case 'video':
+        this.addUnitStateElementCode(elementModel.id, (elementModel as VideoElement).playbackTime);
+        break;
+      case 'audio':
+        this.addUnitStateElementCode(elementModel.id, (elementModel as AudioElement).playbackTime);
+        break;
+      default:
+        this.addUnitStateElementCode(elementModel.id, (elementModel as InputElement).value);
+    }
+  }
+
   private addUnitStateElementCode(id: string, value: InputElementValue): void {
     if (!this.getUnitStateElement(id)) {
       const unitStateElementCode: UnitStateElementCode = { id: id, value: value, status: 'NOT_REACHED' };