Using no combinator (better said: the Descendant Combinator) like this .element1 .element2
will make CSS look for any element that fits the .element2
-selector that is a descendant of .element1
. This means, .element2
can either be a direct or indirect child of .element1
.
For your case you should use a sibling combinator, ~
(General Sibling Combinator) or +
(Adjacent Sibling Combinator) to select .tooltiptext
for when input
can be selected using the :invalid
-selector.
.tooltip input:invalid ~ .tooltiptext {
/* Your CSS-rule to make `.tooltiptext` visible */
}
Another solution
Just for this question I created a CSS tool-class .tooltipped
. Simply format your <input>
like the following to incorporate the tooltip (the classes in the brackets are options one of which needs to be chosen):
<div class="tooltipped (top | bottom | left | right)">
<input />
<div class="(on-invalid | always)">
<div>
<div>
(Place your content here)
</div>
</div>
</div>
</div>
The content you place in (Place your content here)
can be a simple message up to more HTML-code. When simply inserting a message, you might want to set white-space: pre
to retain its formatting, as it would otherwise try to keep the tooltip as narrow as possible.
Since the tooltip is placed using position: absolute
, you should make sure yourself that the tooltip to be shown has enough space to be read when being displayed.
Changing the side on which the tooltip should be shown is as easy as changing the directional class of .tooltipped
. This can even be done easily with JavaScript.
For example, you could change the directional-class when the phone might be too small to display the tooltip in its initial direction.
Obviously, you can make the input-element be of any type. If you want to invalidate it yourself (e.g. when :invalid
wouldn't trigger), you can give it the class .invalid
with JS for the same effect regarding this tooltip's features.
Here is an example showing basically all the available features:
/* For this example */
html, body {
margin: 0;
width: 100%;
height: 100%;
}
body {
display: grid;
grid-template-areas:
". ."
". .";
align-items: center;
justify-items: center;
}
input:invalid {
border-color: red;
outline-color: red;
background: pink;
}
/* Tool-class: Tooltip */
.tooltipped * {margin: 0}
.tooltipped {
--tt-bg: #3f3f3f;
display: flex;
align-items: center;
}
.tooltipped > div {
position: relative;
display: flex;
justify-content: center;
align-items: center;
visibility: hidden;
}
.tooltipped > div > div {
position: absolute;
display: flex;
align-items: center;
}
.tooltipped > div > div::before {
content: "";
border: 4px solid transparent;
}
.tooltipped > div > div > div {
padding: 0.1rem 0.4rem;
border-radius: 2px;
color: white;
background: var(--tt-bg);
}
/* Directional-classes */
.tooltipped.right > div > div {transform: translateX(50%)}
.tooltipped.right > div > div::before {border-right-color: var(--tt-bg)}
.tooltipped.left {flex-flow: row-reverse}
.tooltipped.left > div {justify-content: flex-end}
.tooltipped.left > div > div {flex-flow: row-reverse}
.tooltipped.left > div > div::before {border-left-color: var(--tt-bg)}
.tooltipped.top {flex-flow: column-reverse}
.tooltipped.top > div > div {
flex-flow: column-reverse;
transform: translateY(-50%);
}
.tooltipped.top > div > div::before {border-top-color: var(--tt-bg)}
.tooltipped.bottom {flex-flow: column}
.tooltipped.bottom > div > div {
flex-flow: column;
transform: translateY(50%);
}
.tooltipped.bottom > div > div::before {border-bottom-color: var(--tt-bg)}
/* "Listener"-classes */
.tooltipped input:invalid + .on-invalid,
.tooltipped input.invalid + .on-invalid {visibility: visible}
.tooltipped > .always {visibility: visible}
<div class="tooltipped top">
<input type="number" min="0" max="4"/>
<div class="on-invalid">
<div>
<div>
<p>I am a tooltip!</p>
</div>
</div>
</div>
</div>
<div class="tooltipped right">
<input type="number" min="0" max="4"/>
<div class="always">
<div>
<div>
<p>I am a tooltip!</p>
</div>
</div>
</div>
</div>
<div class="tooltipped bottom">
<input type="number" min="0" max="4"/>
<div class="on-invalid">
<div>
<div>
<p>I am a tooltip!</p>
</div>
</div>
</div>
</div>
<div class="tooltipped left">
<input type="number" min="0" max="4"/>
<div class="always">
<div>
<div>
<p>I am a tooltip!</p>
</div>
</div>
</div>
</div>