要使用嵌套一个div实现

<div class="block">
    <div class="block-in"></div>
</div>

外层要加上 transform-style 和 perspective (视距)才能实现里层的元素3D效果

.block {
  width: 200px;
  height: 200px;
  cursor: pointer;
  /* 3D变形 */
  transform-style: preserve-3d;
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  -ms-perspective: 1000;
  perspective: 1000;
  
  &-in {
    background: brown;
    height: 100%;
    transition: 0.8s;
  }
  
  &:hover .block-in {
    transform: rotateY(180deg);
  }
}

如果需要实现在翻转后看到背面的元素,还需要将两个元素放到block-in元素里面,使两层重叠,在上面一层元素 上使用 backface-visibility: hidden 属性,使之在翻转后不面向屏幕时隐藏起来;并在里面的元素同时使用 transition: transform .5s; transform: rotateY(0deg); 动画

<div class="block">
    <div class="block-in">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
</div>

CSS提示:
翻转前:
box1:transition: transform .5s; transform: rotateY(0deg);
box2:transition: transform .5s; transform: rotateY(0deg); backface-visibility:hidden;

翻转后(box2翻转到90度以后就会隐藏掉,只显示box1了):
box1:transition: transform: rotateY(180deg);
box2:transition: transform: rotateY(180deg);

Autoprefixer是一个后处理程序,你可以同Sass,Stylus或LESS等预处理器共通使用。它适用于普通的CSS,而你无需关心要为哪些浏览器加前缀,只需全新关注于实现,并使用W3C最新的规范。配合postcss一起使用后更好.
安装 : npm install postcss autoprefixer

var autoprefixer = require('autoprefixer');
module.exports = {
    module: {
      loaders: [
        { test: /\.css$/, loader: "style!css!postcss" },
        { test: /\.scss$/, loader: "style!css!postcss!sass" }
      ]
    },
    postcss: [ autoprefixer({ browsers: ['last 2 versions'] })
]}

注: 另外webpack还有一个autoprefixer-loader,但npm官网已将其标为【deprecated】,推荐使用上面示例中通过postcss-loader的方式使用autoprefixer。

const autoprefixer=require("autoprefixer")
postcss:[require('autoprefixer')({
   browsers: [
     'last 10 Chrome versions',
     'last 5 Firefox versions',
     'Safari >= 6', 
     'ie> 8
   ] 
})]

然后,为了兼容大多数主流机型,在package.json里面找到 browserslist ,加上
"iOS >= 8","Firefox >= 20","Android > 4.4"

文档:https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/controlsList

HTMLMediaElement接口的controlsList 属性返回DOMTokenList,帮助用户在显示其自己的控件集时选择要在媒体元素上显示的控件。DOMTokenList可以设置以下三个可能值中的一个或多个:nodownload,nofullscreen和noremoteplayback(值是一组无序的空格分隔标记,这些标记是ASCII不区分大小写的)。

nodownload关键字暗示的下载控制应使用用户代理自己的一套媒体元素控件时被隐藏。
nofullscreen关键字暗示在使用用户代理自己的媒体元素控件集时,应隐藏全屏模式控件。
noremoteplayback关键字暗示当使用用户代理自己的媒体元素控件集时,应隐藏远程播放控件。
语法
var domTokenList = HTMLMediaElement.controlsList;
Value
A DOMTokenList.

示例

<video controls controlslist="nodownload" id="video" src=""></video>
<video controls controlslist="nodownload nofullscreen noremoteplayback" id="video" src=""></video>

规格

https://wicg.github.io/controls-list/html-output/multipage/embedded-content.html#attr-media-controlslist.

次元链接-标准版
HorizonJapan.net
次元链接-专业版
cylink.Pro
次元链接-文档中心
cylink.wiki

本站临时域名如下:
HorizonJapan.net
HorizonJapan.cloud
HorizonJapan.network

思路,加载一个,video 播放器,然后通过 canvas 画布drawImage 方法将video元素 生成图像

如果需要上传图片到后面保存也是可以的,如下是一个我在工作中实际写的代码,仅作为参考:


    //获取视频封面
    function getVideoImage(blobUrl, call) {
        var video = $("#video-screenshot");
        if (video.length<1) {
            video = $('<video style="height: 0; width: 0;" id="video-screenshot">').appendTo("body");
            video[0].addEventListener('loadeddata', function(e) {
                // console.log(e);
                this.width = this.videoWidth;
                this.height = this.videoHeight;
                this.currentTime = this.duration > 10 ? 10 : this.duration/2;
                // this.play();
                // this.pause();
                var _this = this;
                setTimeout(function () {
                    var canvas = document.createElement('canvas');
                    var ctx = canvas.getContext('2d');
                    canvas.width = _this.width;
                    canvas.height = _this.height;
                    ctx.drawImage(_this, 0, 0, canvas.width, canvas.height);
                    var image = {
                        width: _this.width,
                        height: _this.height,
                        currentTime: _this.currentTime,
                        duration: _this.duration
                    };
                    canvas.toBlob(function(blob) {
                        image.blob = blob;
                        image.url = URL.createObjectURL(blob);
                        typeof call == 'function' ? call.call(this, image) : '';
                    });
                }, 300);
            });
        }
        video[0].pause();
        video[0].src = blobUrl;
    }



    //选择封面图
    $("#choose-image").click(function (e) {
        var $this = $(this), image = $("#preview-image")[0], blob = image.blob, filename = image.filename;
        var filenamearr = filename.split('.');
        filenamearr.splice(-1);
        var url = '/upload';
        var formData = new FormData();
        formData.append('filedata', blob, filenamearr.join(',')+'.jpg');
        formData.append("moredata", '其他字段可添加');
        //上传图片
        $this.prop('disabled', true);
        $.ajax({
            url: url,
            type: 'POST',
            data: formData,
            dataType: 'json',
            processData: false,
            contentType: false,
            success: function (res) {
                $this.prop('disabled', false);
                //成功
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $this.prop('disabled', false);
                console.error('上传封面图出错', textStatus, errorThrown);
            }
        });
    });


    $("#files").change(function (event) {
        if (!event.target.files[0]) return;
        if (event.target.files[0].type.indexOf('video/') != 0) return simpleDialog({msg: '请选择视频文件'});

        //自动获取封面图
        var blobUrl = URL.createObjectURL(event.target.files[0]);
        getVideoImage(blobUrl, function(image) {
            $("#preview-image").attr('src', image.url);
            $("#preview-image")[0].blob = image.blob;
            $("#preview-image")[0].filename = event.target.files[0].name;
            $("#preview-video").show();
        });

    });

HTML:

    <div class="form-group">
        <label class="required">视频文件 <span class="required">*</span></label>
        <input type="file" id="files" class="form-control"/>
        <div class="pre-video" id="preview-video" style="display: none;margin-top: 10px;">
            <image id="preview-image" style="width: 240px; height: 135px; display: inline-block;" />
            <button class="btn btn-default" id="choose-image" type="button" style="vertical-align: top;">选择此封面</button>
        </div>
        <p class="help-block">请上传1920*1080视频</p>
    </div>