How To Add Cursor Pointer To Button Overlay on File Input - html

https://codepen.io/adambene/pen/xRWrXN
<div class="upload-btn-wrapper">
<button class="btn">Upload a file</button>
<input type="file" name="myfile" />
</div>
.upload-btn-wrapper {
position: relative;
overflow: hidden;
display: inline-block;
cursor: pointer;
}
.btn {
border: 2px solid gray;
color: gray;
background-color: white;
padding: 8px 20px;
border-radius: 8px;
font-size: 20px;
font-weight: bold;
cursor: pointer;
}
.upload-btn-wrapper input[type=file] {
font-size: 100px;
position: absolute;
left: 0;
top: 0;
opacity: 0;
cursor: pointer;
}
In this example, I want to add cursor:pointer css property, which turns the mouse pointer to hand symbol when hovering over it. However, I am not able to achieve the same. I tried adding the property to all three css elements in all combinations, but that does not work.

You could add font-size to your input and it should work. Pay attention to font-size: 20px;
.upload-btn-wrapper input[type=file] {
position: absolute;
left: 0;
top: 0;
opacity: 0;
font-size: 20px;
cursor: pointer;
}

Related

Hover on child without changing parent

Hover on child element <button> without hover effect on parent <h2>
.parent {
display: block;
text-align: center;
font-weight: 700;
font-size: 31px;
letter-spacing: normal;
position: relative;
}
.parent:hover {
color: orange;
}
span {
line-height: unset;
vertical-align: baseline;
top: 0;
left: 0;
position: absolute;
color: transparent;
box-shadow: none;
z-index: 5;
}
span button {
position: absolute;
left: 0;
top: -20px;
color: #fff;
width: 30px;
height: 30px;
min-width: 30px;
min-height: 30px;
z-index: 5;
background: #0085ba !important;
border-radius: 50%;
border: 2px solid #fff;
box-sizing: border-box;
padding: 3px;
display: inline-block;
overflow: hidden;
}
<h2 class="parent">
Title
<span class="child">
<button>+</button>
</span>
</h2>
This can be helpful
example
.html
<div class="parent1">
<div class="child1">
/*.....*/
.css
.parent1:hover{
cursor: pointer;
}
.parent1:hover .child1{
/*......*/
}
snippet
.parent:hover .child {
/* ... */
}
Add the below:
parent:hover {
cursor:pointer
}
It's a little tricky.
First you need to get the parent from the child :
const _parent = document.querySelector('selectorOfParentFromChild')
After you have to add the class on child and remove on parent. You need to do it one child event : 'onMouseOver'.
SO:
[child, parent].forEach(node=>node.addEvenListener('onmouseover', (event)=>{
event.stopPropagation();
const _parent = document.querySelector('selectorOfParentFromChild')
node.classlist.add(wanted)
_parent.classlist.remove(wanted)
})
This has been asked before, and answers seem to come within the span of: "css can't do that", "you should probably restructure your divs" and "here's a trick".
hover on child without hover effect on parent
Now I don't have the experience to say if a structure that neccesitates this is actually bad, but in either case, there is now a straight-forward solution with :has()
.parent {
display: block;
text-align: center;
font-weight: 700;
font-size: 31px;
letter-spacing: normal;
position: relative;
}
.parent:not(:has(.child:hover)):hover {
color: orange;
}
span {
line-height: unset;
vertical-align: baseline;
top: 0;
left: 0;
position: absolute;
color: transparent;
box-shadow: none;
z-index: 5;
}
span button {
position: absolute;
left: 0;
top: -20px;
color: #fff;
width: 30px;
height: 30px;
min-width: 30px;
min-height: 30px;
z-index: 5;
background: #0085ba !important;
border-radius: 50%;
border: 2px solid #fff;
box-sizing: border-box;
padding: 3px;
display: inline-block;
overflow: hidden;
}
<h2 class="parent">
Title
<span class="child">
<button>+</button>
</span>
</h2>
This is what that selector is saying in English:
Select all elements ".parent" - except the ones who have any child elements ".child" being hovered on - when they are hovered on.
You will have to delete the CSS for parent:hover and if you only want the hover effect on the button then the parent shouldn't have a hover effect in your CSS.
.parent {
display: block;
text-align: center;
font-weight: 700;
font-size: 31px;
letter-spacing: normal;
position: relative;
}
span {
line-height: unset;
vertical-align: baseline;
top: 0;
left: 0;
position: absolute;
color: transparent;
box-shadow: none;
z-index: 5;
}
span button {
position: absolute;
left: 0;
top: -20px;
color: #fff;
width: 30px;
height: 30px;
min-width: 30px;
min-height: 30px;
z-index: 5;
background: #0085ba !important;
border-radius: 50%;
border: 2px solid #fff;
box-sizing: border-box;
padding: 3px;
display: inline-block;
overflow: hidden;
}
button:hover {
color: orange;
}

Custom select box

I am trying to style a select drop down box. The custom select box has rounded corners and a dropdown list (a box that drops down with the options) that shows on focus. I used the css below to style the select box. I have also substituted the html select with DIV elements.
Here is the code I have used so far:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
The styles I have applied to the select tag are coming into effect, but the problem is that the dropdown box top border does not blend with the select box itself on focus. Is it only possible to change the SELECT input style on focus from a round border to a square border?
Would someone with some more knowledge in this regard please take a few minutes to suggest a solution?
It depends on what you mean by "blending", but if you want to achieve a more harmonious look, you can do the following:
Set the border-bottom-left-radius and border-bottom-right-radius of the trigger element to 0px when the dropdown is open, so that the select trigger visually continues to the dropdown that is visible
Remove the top border of the dropdown, so that you don't have a doubly-thick border separating the trigger and the dropdown
See proof-of-concept below:
document.querySelector('.custom-select-wrapper').addEventListener('click', function() {
this.querySelector('.custom-select').classList.toggle('open');
for (const option of document.querySelectorAll(".custom-option")) {
option.addEventListener('click', function() {
if (!this.classList.contains('selected')) {
this.parentNode.querySelector('.custom-option.selected').classList.remove('selected');
this.classList.add('selected');
this.closest('.custom-select').querySelector('.custom-select__trigger span').textContent = this.textContent;
}
})
}
})
.custom-select-wrapper {
position: relative;
user-select: none;
width: 188px;
z-index: 30000000000;
}
.custom-select {
position: relative;
display: flex;
flex-direction: column;
}
.custom-select__trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
height: 27px;
background: #ffffff;
cursor: pointer;
border: 1px solid #707070;
border-radius: 8px;
transition: all 0.5s;
}
.custom-options {
position: absolute;
display: block;
top: 100%;
left: 0;
right: 0;
border: 1px solid #707070;
border-top: none;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
background: #fff;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom-select.open .custom-select__trigger {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.custom-select.open .custom-options {
opacity: 1;
visibility: visible;
pointer-events: all;
}
.custom-option {
position: relative;
display: block;
padding: 0 10px 0 10px;
line-height: 25px;
cursor: pointer;
transition: all 0.5s;
}
.arrow {
position: relative;
top: 15px;
right: 15px;
}
.arrow::before,
.arrow::after {
content: "\f0d7";
font-family: "Font Awesome 5 Free";
font-size: 20px;
font-weight: 700;
color: #394a6d;
position: absolute;
bottom: 0px;
}
<div class="custom-select-wrapper">
<div class="custom-select">
<div class="custom-select__trigger">
<span>Option 1</span>
<div class="arrow"></div>
</div>
<div class="custom-options">
<span class="custom-option selected" data-value="tesla">Option 2</span>
<span class="custom-option" data-value="volvo">Option 3</span>
</div>
</div>
</div>
The above code is a solution strictly from a styling point of view. But as per #CBroe remarks, from a usability point of view (for example using the select via keyboard is impossible), the code is not optimal.
This is why I came up with a solution that uses the jQuery plugin Select2
If anyone is interested here is a link to the code
https://www.codeply.com/p/Z999PpuSOK

Event on input within div acting differently to event on input within a label

This is an odd one but I'm sure there's a simple explanation. Can someone explain to me why an event on an input within a div acts differently to an event on input within a label. Please see the following fiddle as an example:
https://jsfiddle.net/anthill/h8v106o7
$('#container .switch input[type="checkbox"]').change(function(e) {
alert($(this).data('message'));
})
body {
font-family: Helvetica, Arial, sans-serif;
padding: 10px;
}
h5 {
margin-bottom: 0.5em;
}
.switch {
background-color: #fff;
border: 1px solid #999;
border-radius: 2px;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: 0;
height: 34px;
overflow: hidden;
margin: 0;
padding: 0;
position: relative;
width: 80px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.switch:after, .switch:before {
background-color: #9bca3e;
color: #fff;
content: "On";
display: block;
font-size: 13px;
line-height: 1.5;
height: 100%;
left: 0;
padding: 7px 0;
position: absolute;
text-align: center;
top: 0;
width: 51%;
/* This is so the darker color doesn't show through the rounded corners of the knob */
}
.switch:before {
background-color: #999;
content: "Off";
left: auto;
right: 0;
width: 50%;
}
.switch .knob {
background: #f7f7f7;
border: 1px solid #999;
border-bottom: none;
border-top: none;
border-radius: 2px;
display: block;
font-size: 13px;
height: 100%;
left: -1px;
position: relative;
top: 0;
width: 40px;
z-index: 2;
-webkit-transition: all 0.15s ease;
-moz-transition: all 0.15s ease;
-ms-transition: all 0.15s ease;
transition: all 0.15s ease;
}
.switch .knob:before, .switch .knob:after {
border: 4px solid transparent;
border-left-color: inherit;
content: "";
display: block;
height: 0;
left: 50%;
margin-left: 2px;
margin-top: -3px;
position: absolute;
top: 50%;
width: 0;
}
.switch .knob:before {
border-left-color: transparent;
border-right-color: inherit;
margin-left: -10px;
}
.switch input {
position: absolute;
visibility: hidden;
}
.switch input:checked + .knob {
left: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<label class="switch">
<input type="checkbox" checked data-message="Checkbox 1"/>
<span class="knob"></span>
</label>
<div class="switch">
<input type="checkbox" checked data-message="Checkbox 2" />
<span class="knob"></span>
</div>
</div>
The change event fires fine on the first checkbox but not at all on the second. Is it something to do with the label sharing the event on the hidden input, whereas the div does not do this?
Testing here: https://jsfiddle.net/Twisty/947vsjpa/5/
You can see that Click events are happening on the Switch & Knob, yet not on the Input. The label element has a relationship with input. The click event upon the Label can effect the state of the Input. div does not have this relationship; therefore, the click event does not reach the invisible element.
How do you want to fix this? Use Label element for both? Capture the click event on the .switch and then trigger a click of the Input.
Consider the following: https://jsfiddle.net/Twisty/947vsjpa/18/
JavaScript
$(function() {
$('#container .switch').click(function(event) {
console.log(event.type, event.target);
event.preventDefault();
var $input = $("input[type='checkbox']", this)
$input.prop("checked", !$input.prop("checked"));
alert($input.data("message"));
});
});
This changes the property even if it's not visible and can't be clicked upon.

add image into input tag

I am trying to make a search bar using an input and to add to it a svg.
this is how it should look like
this is my code
.search-input-btn {
background: transparent;
border: none;
cursor: pointer;
display: inline-block;
font-size: 20px;
position: absolute;
top: 0;
right: 0;
padding: 18px 20px;
z-index: 2;
}
<div class="col-4">
<input type="text" class="form-control" placeholder="Search">
<button type="submit" class="search-input-btn"><img src="assets/images/search-input-btn.svg"></button>
</div>
and this is how it looks like so far
You can use transform property to align it vertically.
.search-input-btn {
background: transparent;
border: none;
cursor: pointer;
display: inline-block;
font-size: 20px;
position: absolute;
top: 0;
right: 0;
padding: 18px 20px;
z-index: 2;
transform:translateY(-50%);
}

Styled css do not appear in firefox

I have a checkbox that I have styled accordingly. Like this :
input[type=checkbox] {
transform: scale(1.3);
}
input[type=checkbox] {
width: 30px;
height: 30px;
margin-right: 15px;
cursor: pointer;
font-size: 17px;
visibility: hidden;
}
input[type=checkbox]:after {
content: " ";
background-color: rgba(224, 214, 214, 0.877);
display: inline-block;
margin-left: 10px;
padding-bottom: 5px;
color: #fff;
width: 22px;
height: 25px;
visibility: visible;
border: 1px solid transparent;
padding-left: 3px;
border-radius: 5px;
}
input[type=checkbox]:checked:after {
content: "\2714";
padding: -5px;
background: red;
font-weight: bold;
}
<input type="checkbox" [(ngModel)]="Option1" />
<p>Option1</p>
I tested this and it worked in Chrome and Opera, but I forgot to check Firefox.
Now I see that the checkboxes don't appear there at all.
I understand it is an issue of using :after for checkbox, but how do I fix this ?
So that the same checkbox appears styled on the browsers?.
I am uncertain of what to do so that I keep the design.
Thank you.
Read these specifications
:before and :after should only work on the element which can act as a
container of content. cannot contain any content so it should
not support those pseudo-elements. Chrome supports because it does not
follow the spec
However you can use <span> tag next to input tag to achieve this like below. It will work on firefox as well
body {
font: 13px Verdana;
}
label {
position: relative;
display: inline-block;
text-align: center;
}
label span {
display: block;
margin-top: 10px;
cursor: pointer;
}
input[type=checkbox] {
width: 30px;
height: 30px;
cursor: pointer;
margin: 0;
opacity: 0;
}
input[type=checkbox]+span:after {
content: "";
background-color: rgba(224, 214, 214, 0.877);
color: #fff;
width: 30px;
height: 30px;
border-radius: 5px;
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
line-height: 30px;
}
input[type=checkbox]:checked+span:after {
content: "\2714";
background: red;
}
<label>
<input type="checkbox" [(ngModel)]="Option1" />
<span>Option1</span>
</label>