JSFiddle - React, Tailwind, and code Playground
HTML
<div class="demo-upload-container">
<div class="custom-file-container" data-upload-id="myFirstImage">
<label>画像を選択してください <a href="javascript:void(0)" class="custom-file-container__image-clear" title="Clear Image"> xキャンセル</a></label>
<label class="custom-file-container__custom-file" >
<input type="file" class="custom-file-container__custom-file__custom-file-input" accept="image/*">
<input type="hidden" name="MAX_FILE_SIZE" value="10485760" />
<span class="custom-file-container__custom-file__custom-file-control"></span>
</label>
<div class="custom-file-container__image-preview"></div>
</div>
</div>
CSS
.custom-file-container {
box-sizing: border-box;
position: relative;
display: block;
}
.custom-file-container__custom-file {
box-sizing: border-box;
position: relative;
display: inline-block;
width: 100%;
height: calc(2.25rem + 2px);
margin-bottom: 0;
margin-top: 5px;
}
.custom-file-container__custom-file:hover {
cursor: pointer;
}
.custom-file-container__custom-file__custom-file-input {
box-sizing: border-box;
min-width: 14rem;
max-width: 100%;
height: calc(2.25rem + 2px);
margin: 0;
opacity: 0;
}
.custom-file-container__custom-file__custom-file-control {
box-sizing: border-box;
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 5;
height: calc(2.25rem + 2px);
padding: .5rem .75rem;
overflow: hidden;
line-height: 1.5;
color: #333;
user-select: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #c0c0af;
border-radius: .25rem;
}
.custom-file-container__custom-file__custom-file-control:empty::after {
box-sizing: border-box;
content: "選択されていません";
}
.custom-file-container__custom-file__custom-file-control::before {
box-sizing: border-box;
position: absolute;
top: 0;
right: 0;
z-index: 6;
display: block;
height: calc(2.25rem + 2px);
padding: .5rem .75rem;
line-height: 1.25;
color: #333;
background-color: #EDEDE8;
border-left: 1px solid #c0c0af;
}
.custom-file-container__custom-file__custom-file-control::before {
box-sizing: border-box;
content: "ファイルを選択";
}
.custom-file-container__image-preview {
box-sizing: border-box;
transition: all 0.6s ease;
margin-top: 20px;
margin-bottom: 40px;
height: 250px;
width: 100%;
border-radius: 4px;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
html {
position: relative;
min-height:...
JavaScript
// by https://github.com/promosis/file-upload-with-preview
//
(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.FileUploadWithPreview = factory());
}(this, (function() {
'use strict';
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var FileUploadWithPreview = function() {
function FileUploadWithPreview(uploadId) {
_classCallCheck(this, FileUploadWithPreview);
if (!uploadId) {
throw new Error('No uploadId found. You must initialize file-upload-with-preview with a unique uploadId.');
}
//Set initial variables
this.uploadId = uploadId;
this.cachedFileArray = [];
//Grab the custom file container elements
this.el = document.querySelector('.custom-file-container[data-upload-id="' + this.uploadId + '"]');
if (!this.el) {
throw new Error('Could not find a `custom-file-container` with the id of: '...