Pure CSS drag and drop effect code

Time:2021-10-13

Using your imagination, CSS can also achieve drag and drop effects.

1、 Drag effect example

This is a very common effect on the mobile terminal, which can be dragged around by pressing and holding. For example, the following starting point [1] touch screen version:

This kind of effect can be easily realized with JS, which means more calculations, more critical scenarios, and more code. However, after some brain holes, I found that CSS can almost achieve this effect, and then look down.

2、 CSS implementation principle

In the traditional web, page scrolling is a very common interaction, which is easy to operateUse the mouse wheel or drag the scroll bar directly。 However, the mobile terminal is different,Drag the page directly with your finger to scroll.Usually the page scrolls either vertically or horizontally,What if you can scroll in both directions?for example


.dragbox{
  width: 300px;
  height: 300px;
  overflow: auto
}
.dragcon{
  width: 500px;
  height: 500px;
}

You only need the width and height of the internal element to be greater than the container to roll in both directions (remember to set it)overflow:auto), as shown below

Generally, the mouse wheel can only scroll in one direction at the same time (press and hold)ShiftYou can scroll in the other direction), but the mobile end canDrag the content directly and scroll freely, as shown below

Now, add an element in the middle of the content and scroll along with the content area

Next, hide the following text

Is it a littleDragWhat’s the smell of? The principle is so simple!

3、 CSS implementation details

Firstly, the size relationship between the drag target and the drag container is determined. It is assumed that the size of the drag target isw * h, then it is easy to get the dimensional relationship as follows:The internal size is twice the size of the container minus the size of the drag target


.dragbox{
  width: 100%;
  height: 100%;
}
.dragcon{
  width: calc(200% - w);
  height: calc(200% - h);
}

Use a dynamic diagram to describe as follows (the orange block in the middle represents the drag target)

4、 CSS implementation layout

Next, you need to add this feature to the page. Here are two layouts

1. Fixed positioning

Now add the layout directly to the page and addfixedlocation

<body>
  ... other elements on the page
  <div class=“dragbox”>
    <div class=“dragcon”></div>
    <div class=“ball”></div> <!-- Drag element -- >
  </div>
</body>

The key styles are as follows


.dragbox{
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: auto
}

The hierarchical schematic relationship is as follows:

thus,dragboxIt must have obscured the original part of the page, so it needs to be addedpointer-events: none;Add while draggingpointer-events: all


.dragbox{
  /*...*/
  pointer-events: none;
}
.ball{
  /*...*/
  pointer-events: all;
}
.dragbox.active{
  /*...*/
  pointer-events: all;
}

With JS, the outer container scrolling can be triggered when pressed


ball.addEventListener('touchstart',(ev)=>{
   dragbox.classList.add('active');
})
document.addEventListener('touchend',()=>{
   dragbox.classList.remove('active');
})

The actual effect is as follows

Full code accessible https://codepen.io/xboxyan/pen/PobwxBK (please open the mobile terminal mode for PC access)

You can also scan the following QR codes directly

1. Absolute positioning + hierarchy

The previous layout is due tofixedDue to the influence of positioning level, we have to use js to dynamically change the state of the container. Is there any way to achieve itYou can drag and drop without affecting the original pageAnd? Let’s look at this layout, which usesab s olutelocation

You need to wrap the original pagedivContainers, as follows

<body>
  <div class=“dragbox”>
    <div class=“dragcon”></div>
    <div class=“ball”></div>
  </div>
  <div class=“body”> <!-- Page scrolling with a separate layer -- >
    ... other elements on the page
  </div>
</body>

The key styles are as follows

.dragbox{
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: auto;
}
.body{
  position: relative;
  height: 100%;
  overflow: auto;
}
.ball{
  position: relative;
  z-index: 10;  /* The level of drag target is set higher*/
}

Now the hierarchical relationship becomes like this

Here, the original page content is at the level ofdragboxandDrag targetTherefore, the scrolling of the original page will not be affected when dragging,No JS processing is required

Full code accessible https://codepen.io/xboxyan/pen/bGBNQxL (please open the mobile terminal mode for PC access)

You can also scan the following QR codes directly

Tip: of the above two layout methods, the first one has better adaptability and does not affect existing projects; The second experience is better, but it will be useddivAs a page scrolling container, some changes will be made to the page structure, which can be selected according to the actual situation.

5、 CSS implements other functions

1. Adsorption function

Many times, it needs to be automatically adsorbed on the edge at the end of dragging, just like the schematic diagram at the beginning of the article. So, what properties can be associated with adsorption?

The answer is CSS scroll snap [2]

<body>
  ... other elements on the page
  <div class=“dragbox”>
    <div class=“dragcon”>A</div>
    <div class=“dragcon”>B</div>
    <div class=“ball”></div>
  </div>
</body>

Here are the key styles


.dragbox{
  ...
  scroll-snap-type: x mandatory;
}
.dragcon{
  scroll-snap-align: start;
}

The actual effect is as follows

Full code accessible https://codepen.io/xboxyan/pen/XWNJyPw (please open the mobile terminal mode for PC access)

You can also scan the following QR codes directly

1. Set the initial position

By default, the drag target has only the lower right corner. How can it be located in the lower left corner? Very simple. Drag and drop here is implemented by rolling containers, so onlyNeed to changeScrollleft or scrolltop


dragbox.scrollLeft = 999;
dragbox.scrollTop = 999;

In addition, it can also be implemented in pure HTML,Use the autofocus of elements to automatically focus on the visual range

<div class=“dragcon">
  ...
  <button class="pos" autofocus></button> <!-- Add an autofocus element -- >
</div>

For example, you want the initial position to betop left corner, then add oneLower right cornerAuto focus elements are OK (of course, transparency needs to be set to hide)~

1. Set boundary

Now the boundary of the drag target is the screen edge. Sometimes it may be necessary to leave some spacing. This need can be easily changed in CSSleft/top/right/bottompaddingborder …Many ways


.dragbox{
  left: 10px;
  top: 10px;
  right: 10px;
  bottom: 10px;
  /*rect: 10px;*/
}
.dragbox{
  padding: 10px;
}

6、 Description and summary

I thought there was no problem with compatibility. Actually, there are many IOS problems, mainly the problem of safari rolling container. For example, some lower versions of IOS do not scroll smoothly and need to be added

-webkit-overflow-scrolling:touc hTo achieve smooth scrolling and automatic adsorption, but it will lead to hierarchy problems. Some documents describe that setting this attribute will create a native scrolling container with the highest level. There is also the first fixed layout, if set by defaultpointer-events: none staytouchstart Then set toauto , the scrolling on IOS failed, but just reverse it (IOS is compatible in the demo).

The advantages are that it inherits the flexibility of CSS, has almost zero cost, is easy to reuse, and makes use of native scrolling without jamming.

However, there are some limitations ifThe size of the drag target is not fixed, you may need to use js to get. Of course, in comparison, this is still a very cost-effective implementation.

Looking back now, in fact, there are no very rare attributes (scroll snap may be one, but it is an auxiliary function after all). It is mainly a common effect. Then, through association and divergence, according to the daily accumulation, fully tap the original ability, and finally complete the required interaction. Then there is this article.

Thank you for reading and hope to inspire future work.

References

[1]Starting point Chinese website:  https://m.qidian.com/

[2] CSS Scroll Snap:  https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Scroll_Snap

This is the end of this article about the code of pure CSS to realize the drag effect. For more information about CSS to realize the drag effect, please search the previous articles of developeppaer or continue to browse the relevant articles below. I hope you will support developeppaer in the future!

Recommended Today

The selector returned by ngrx store createselector performs one-step debugging of fetching logic

Test source code: import { Component } from ‘@angular/core’; import { createSelector } from ‘@ngrx/store’; export interface State { counter1: number; counter2: number; } export const selectCounter1 = (state: State) => state.counter1; export const selectCounter2 = (state: State) => state.counter2; export const selectTotal = createSelector( selectCounter1, selectCounter2, (counter1, counter2) => counter1 + counter2 ); // […]