Element style doesn't apply when using cdkDropList (Angluar cdk drag and drop)
Asked Answered
E

3

11

I am posting this question just to answer it myself in case anyone is struggling like I did!

I'm working on an angular project to implement a Trello-like application. I want to be able to drag an element from one list to another so I installed the Angular cdk module and followed their guide.

enter image description here

NOTICE: My application is broken into several pages/components, the page were I am implementing that interface (Trello) is called BoardPageComponent.

First I added the cdkDrag directive and the element became draggable which is a good start!

Then I added the cdkDropList directive to the parent element, the children elements were still draggable BUT their style no longer works while they are dragged !

Solution

When dragging an element inside of a cdkDropList the DragAndDropModule creates a clone of that element but at the body level of the document. So if your component is encapsulated then it's style won't apply !

Solution 1: One quick solution would be to just move the style of that draggable element and put it in the global style file.

Solution 2: Another solution would be to disable the encapsulation of that component with ViewEncaplusation.None:

@Component({
  selector: 'app-board-page',
  templateUrl: './board-page.component.html',
  styleUrls: ['./board-page.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class BoardPageComponent implements OnInit, OnDestroy {
  ....
}

This will work but you should be aware that this may leak some style to other components of your application. So make sure to encapsulate the component's style manually.

Or maybe there is another way ??

Eyelid answered 2/5, 2020 at 13:4 Comment(0)
I
3

I had the same issue: the dragged element was unstyled. And yes, there may be another way.

While keeping the default ViewEncapsulation.Emulated, my solution was to ensure my component's CSS was not overly scoped (e.g. having draggable parent's selectors in the path for draggable may be too specific).

Using .cdk-drag-preview was helpful to me.

Infundibuliform answered 1/9, 2021 at 20:16 Comment(0)
S
1

In your scss file add specific css in host ng deep selector

:host ::ng-deep h2 {
    color: red;
 }
Sergio answered 2/5, 2020 at 13:22 Comment(0)
T
1

My take on this answer

TLDR: I had nested selectors in my SCSS code, and the styles were not used because the drag action creates a copy of the element, but without its parents (which I had in the nested selector)

Here is how I got my styles to be properly copied across.

What is happening?


When the .cdk-drag-preview is created, it copies the element that is being dragged.

It is created and appended near the end of the <body> element of the HTML.

The most important thing here is that only the dragged element is copied, and not its parent elements.

What is the problem?


In my case, the problem was that my SCSS selector was nested, and it expected my dragged element to start with a parent class, which doesn't exist when we drag.

Example:

.example-parent-class {
  // Styles for the parent element

  .example-dragged-class { 
    // Styles for the item that we want to drag
  }
}

And when we drag, this is what was recorded in the <body> tag:

<body>
  <div cdkdrag class="example-dragged-class cdk-drag cdk-drag-preview"></div>
</body>

and the parent element nor it's class was nowhere to be found, thus my styles were not working.

How to find this information?


While dragging the element with the Inspector open (F12 on Chrome), you can quickly right-click, and go to the </body> selector in your Elements tab. The dragged element will still stay dragged and you can inspect the HTML that is being generated.

What is the solution?


My fix was to remove that nesting, and let my dragged element's class be standalone in my components scss so it can be accurately used by the .cdk-drag-preview

Example:

.example-parent-class {
  // Styles for the parent element
}

.example-dragged-class {
  // Styles for the item that we want to drag
}

And thus finally, the styles for my original element were properly copied across, there was no need for additional setup or anything similar.

Maybe additionally you can add styles for the placeholder or something similar.

Example:

.cdk-drag-placeholder {
  opacity: 0;
}
Talapoin answered 16/8, 2022 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.