One way to do this, as I have on a couple of occasions, would be to hide the input element and use a label
element which is bound to the hidden file field to receive the click events. You can style the label however you see fit within reason so that ought to give sufficient flexibility to accomplish what you want?!
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
body, body *{ font-family:cursive }
input[type='file']{
width: 0px;
height: 0px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
input[type='file'] + label{
font-weight: 700;
color: black;
background-color: #E5E4E2;
display: inline-block;
border:1px solid black;
padding:0.25rem;
width:50%;
cursor:pointer;
}
.input[type='file']:focus + label,
.input[type='file'] + label:hover {
background-color: red;
}
span{
color:red
}
</style>
</head>
<body>
<form>
<input type='file' name='photo' id='photo' />
<label for='photo'>
<span>Put your Text here</span>
</label>
</form>
<script>
/* you can still assign the listeners... */
document.getElementById('photo').onchange=function(e){
console.log(this.value)
}
</script>
</body>
</html>
a less verbose version of the above to show a minimal example
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
input[type='file']{
width: 0px;
height: 0px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
</style>
</head>
<body>
<form>
<input type='file' name='photo' id='photo' />
<label for='photo'>
<span>Put your Text here</span>
</label>
</form>
</body>
</html>