I have created an element where when you hover within the area of the element a hover effect is applied (change background colour), on top of this element is a button.
When I hover over the button it causing the other hover effect to disappear, I want to be able to keep the hover for the whole time that the mouse is within the area of the first element.
Example Code Here
So when I hover over the button in the example, I still want the background of the a tag to be black. At the moment when I hover over the button it causes the black background to disappear. I also still want to be able to click on the button.
To achieve what I want to achieve would I need to use js? Or can it be done in CSS?
#button1 {
position: absolute;
z-index: 100;
top: 10%;
left: 15%;
}
#label {
position: absolute;
z-index: -10;
border: 1px solid red;
width: 200px;
height: 200px;
text-align: center;
}
#label span {
color: white;
}
#label:hover {
background-color: black;
}
#label button:hover{
color:white;
<a id="label"><span>Hidden Until Hover</span>
<button id="button1">Test Button</button>
</a>
you need to wrap your button inside the #label !
this is how its work !
Put #label in front, and use + select next slibing dom
#button1 {
position: absolute;
z-index: 100;
top: 10%;
left: 15%;
}
#label {
position: absolute;
z-index: -10;
border: 1px solid red;
width: 200px;
height: 200px;
text-align: center;
}
#label span {
color: white;
}
#label:hover {
background-color: black;
}
#button1:hover + #label {
background-color: black;
}
<button id="button1">Test Button</button>
<a id="label"><span>Hidden Until Hover</span></a>
Related
I have this buttons which have a hover effect that renders a span on top of the hovered button.
It works fine, but, when the width of the screen changes, it looks very bad:
These are the elements:
<div className='buttons'>
<button
className={editor.isActive('bold') ? 'is-active' : 'is-inactive'}
>
<strong>N</strong>
<span className='popup'>Negrita (Ctrl+B)</span>
</button>
<button
className={editor.isActive('italic') ? 'is-active' : 'is-inactive'}
>
<em>C</em>
<span className='popup'>Cursiva (Ctrl+I)</span>
</button>
<button
className={editor.isActive('strike') ? 'is-active' : 'is-inactive'}
>
<s>T</s>
<span className='popup'>Tachado (Ctrl+Shift+X)</span>
</button>
... (you get the idea)
</div>
This is the scss:
.buttons button {
position: relative;
height: 29.19px;
color: #000;
border: 1px solid black;
border-radius: 0.3rem;
margin: 0.2rem !important;
padding: 0.1rem 0.4rem !important;
background: white;
accent-color: black;
font-weight: 500;
}
button .popup {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 100%;
left: 50%;
margin-bottom: 5px;
margin-left: -60px;
}
button .popup::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: black transparent transparent transparent;
}
button:hover .popup {
visibility: visible;
}
What im looking for
I decided that the best solution would be a horizontal scroll. The problem is that the span is absolute positioned based on the button so i cant figure it out a way to keep the span on top of the hovered button while having an horizontal scroll.
Update 1
Ok, i tried to add a scroll, this is whats happening now:
As you can see, the scroll is working fine but the spans are 'covered', is there a way to fix this?
I added this to the code:
.buttons {
position: relative;
overflow-x: scroll;
white-space: nowrap;
}
Have a look at the definition of the absolute here
The element is removed from the normal document flow, and no space is
created for the element in the page layout. It is positioned relative
to its closest positioned ancestor, if any; otherwise, it is placed
relative to the initial containing block.
And positioned ancestor:
A positioned element is an element whose computed position value is
either relative, absolute, fixed, or sticky. (In other words, it's
anything except static.)
So, it should work even while having an horizontal scroll if you set position:relative for .buttons.
From my understanding, ::before should appear below the element, and ::after should appear above of the element (in terms of z-index).
In the following example I am trying to make just the background color darker (not the foreground color) when one hovers over the button. Even though I used ::before it still appears in front. Why? I know I could fix it with z-index, but according to this comment which has 6 upvotes:
I think it's better to use :before so you get the right stacking order without playing with z-index.
I should not have to, and the order should be correct?
.parent {
--my-color: red;
}
button {
color: blue;
background-color: var(--my-color);
padding: 8px 16px;
position: relative;
}
button:hover {
background-color: transparent;
}
button:hover::before {
display: block;
content: "";
position: absolute;
top: 0; left: 0; width: 50%; height: 100%; /* width is 50% for debugging (can see whats below) */
background-color: var(--my-color);
filter: brightness(80%);
}
<div class="parent">
<button type="button">CLICK ME</button>
</div>
There's no difference between ::before and ::after regarding the z-index or z-axis order. By default both will be placed in front of their parent, covering it (if their position is defined accordingly). To achieve z-axis layering beyond that, you need to actually use a z-index (besides a combination of relative and absolute position).
Addition after comment:
In the snippet below there are two variations of the situation. The only difference if that once ::after is used, once ::before, both times without a z-index, and both time with the same result, i.e. the pseudo element covering its parent:
.parent {
--my-color: red;
}
button {
color: blue;
background-color: var(--my-color);
padding: 8px 16px;
position: relative;
}
button:hover {
background-color: transparent;
}
.parent:nth-child(1) button:hover::before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--my-color);
filter: brightness(80%);
}
.parent:nth-child(2) button:hover::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--my-color);
filter: brightness(80%);
}
<div class="parent">
<button type="button">CLICK ME</button>
</div>
<div class="parent">
<button type="button">CLICK ME</button>
</div>
So, to come back to your question in your second comment: Yes, they are wrong - you need to use a z-index to move the pseudo element behind the parent.
So your actual solution should look like this, using a negative z-index: -1; for the pseudo element (and you could as well use ::after here, it doesn't matter...).
.parent {
--my-color: red;
}
button {
color: blue;
background-color: var(--my-color);
padding: 8px 16px;
position: relative;
}
button:hover {
background-color: transparent;
}
button:hover::before {
content: '';
position: absolute;
z-index: -1;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--my-color);
filter: brightness(80%);
}
<div class="parent">
<button type="button">CLICK ME</button>
</div>
<span id="priority-dot-open-menu">
<span id="priority-menu">
<span class="tooltip-top"></span>
<span id="priority-dot-blue"></span>
<span id="priority-dot-yellow"></span>
<span id="priority-dot-red"></span>
</span>
</span>
/* The popup menu - hidden by default */
#priority-menu {
display: none;
position: absolute;
top: 150%;
left: -50%;
border: 3px solid #f1f1f1;
z-index: 9;
max-width: 300px;
padding: 10px;
background-color: white;
}
#priority-dot-open-menu {
position: relative;
height: 25px;
width: 25px;
background-color: blue;
border-radius: 50%;
display: inline-block;
opacity: 0.8;
cursor: pointer;
}
#priority-dot-open-menu:hover {
opacity: 1;
}
My #priority-menu (column with the 3 dots) is a child of the dot above (#priority-dot-open-menu). I need it to be so I can use absolute positioning. However it's also inheriting certain properties/values, like opacity and hovering which I don't want to. What would be the ideal solution?
https://jsfiddle.net/moq2bwLj/ (the menu doesn't open on js fiddle, it's just for code-viewing purposes. Thanks!
Child elements in CSS automatically inherit the rules applied to their parents; there is nothing you can do to prevent this. What you can do, however, is to override this behaviour by crafting a rule that targets the child, changing it to the initial value:
#priority-menu {
cursor: initial;
opacity: initial;
}
I'm trying to add an icon inside a button. The problem is that whenever I add the icon, it changes the shape of the button (it makes it taller, and sometimes wider depending on how big the icon is), and it mis-aligns the text of the button so that it is no longer centered, rather the text has been pushed down.
<button>
<i class="material-icons">weekend</i>
Test
</button>
And the CSS:
i {
color: #669FAB;
font-size: 24px !important;
}
button {
min-width: 100px;
}
https://jsfiddle.net/uxs71ymz/1/
I would like the icon to shift to the left, while having the text remain centered inside the button.
hi here is the css code
CSS
i {
color: #669FAB;
font-size: 24px !important;
vertical-align:middle;
}
button {
min-width: 100px;
}
hope this helps..
https://jsfiddle.net/hq9t8rk4/
button i.material-icons {
color: #669FAB;
font-size: 24px;
// Add the below
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
}
button {
min-width: 100px;
// Add the below
position: relative;
padding: 3px 50px;
line-height: 24px;
text-align: center;
}
I know it is possible to create a custom "tooltip" with the :hover:after selectors and to align this tooltip relative to the original element by marking the original element as position:relative and the tooltip as absolute.
HTML:
test
<span custom-tooltip="testing a custom tooltip" class="tooltip">
test
</span>
test
CSS:
.tooltip {
position: relative;
}
.tooltip:hover:after {
content: attr(custom-tooltip);
position: absolute;
background: black;
color: white;
}
However, I must use absolute values to position or size this :after element
top: 30px;
left: -30px;
width: 300px;
What if I want to make the element as wide as it needs to be (Percentages are relative to the parent element creating a large vertical box so I can't tell it to go width: 100%)
And centered under the parent (left: -50% results in it being moved 50% of the parent to the left, not centered)
Is this possible without javascript? (If not, are there some magic selectors or functions to get the width of this or that and calc() the correct values?
You can force the tooltip onto a single line by using white-space:nowrap. I don't know of any way to center the tooltip without forcing a specific width on both the tooltip and the item the tooltip applies to. Here's a general-purpose example (without centering):
<p>Lorem <span tooltip="Lorem ipsum">ipsum</span> dolor sit amet.</p>
And the CSS:
*[tooltip] {
position: relative;
border-bottom: dotted 1px #000;
}
*[tooltip]:hover:before {
content: attr(tooltip);
background-color: #000;
color: #fff;
top: 1em;
position: absolute;
white-space: nowrap;
}
Note that I'm using :before instead of :after. If you want to center the tooltip and are able to define a fixed width, you can use this CSS instead:
*[tooltip] {
position: relative;
display: inline-block;
text-align: center;
width: 200px;
margin: 0 -75px;
}
*[tooltip]:hover:before {
content: attr(tooltip);
background-color: #000;
color: #fff;
top: 1em;
position: absolute;
white-space: nowrap;
width: 200px;
}
Here, the item is given a fixed width equal to the width of the tooltip then negative left/right margins to collapse it back down to the desired size. Note the addition of display:inline-block and text-align:center.
This technique isn't practical for inline tooltips, but works well for buttons and "call to action" links.
.tooltip
{
display: inline;
position: relative;
}
.tooltip:hover:after
{
background: #333;
background: rgba(0,0,0,.8);
border-radius: 5px;
bottom: 26px;
color: #fff;
content: attr(title);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
width: 220px;
}
code from TalkersCode complete code here Create CSS3 Tooltip