I’m in the process of building an input in a form that contains a profile picture that, when clicked, will allow a user to select a new image. It looks like the common practice is to use an input with the type of "file" and then hide it through various means. Setting opacity:0
seems to be the only legitimate option to me, as this will keep the element in the DOM and it will still detect clicks or focus.
However, an input with no opacity will also not have a visible focus ring, even though the element is technically in focus. What are the options I have at my disposal in order to have a focus ring show when focused? Thank you in advance.
.profile-pic {
width: 156px;
height: 156px;
border-radius: 50%;
position: relative;
/* overflow: hidden; */
}
.profile-pic input[type='file'] {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0;
border: none;
border-radius: 50%;
cursor: pointer;
z-index: 10;
}
.profile-pic__img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
z-index: 1;
}
.profile-pic__img img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
filter: brightness(0.65);
transition: filter 0.2s ease-in-out;
cursor: pointer;
}
.profile-pic__img img:hover {
filter: brightness(0.5);
}
.profile-pic__text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
display: flex;
flex-direction: column;
align-items: center;
z-index: 5;
}
.profile-pic__text .fa-camera {
color: #fff;
}
.profile-pic span {
color: #fff;
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: normal;
width: 90%;
}
<div class="profile-pic">
<input type="file" />
<div class="profile-pic__img">
<img src="[TEST_URL]" alt="" />
</div>
<div class="profile-pic__text">
<i class="fas fa-camera"></i>
<span>Click to change photo</span>
</div>
</div>
3
Answers
Apply the
:focus-within
pseudo-class to the.profile-pic
and give it distinctive styling when the transparent input has the focus.Basically the same answer as Quentin’s, except I wanted to keep the pseudo-class applied to the
input
, so I used abox-shadow
rather than aoutline
. Six of one, half-dozen of another.I’m not sure if you need an invisible element to have a focus ring, if it’s invisible.
You could add a focus ring to your
.profile-pic
element instead, because it’s actually visible and visually interactive.You can make your
.profile-pic
element focusable by adding atabindex="0"
attribute to it. Then just select it in CSS via.profile-pic:focus
and design a focus ring.I know I haven’t really answered your question, but I hope this helps.