Add Underline When Hover in React and CSS - css

How do I add a underline in text-decoration when hovering the text?
Seems this is correct but it still doesn't work
CLICK HERE
<span
style={{
color: "red",
cursor: "pointer",
"& :hover": {
textDecoration: "underline"
}
}}
>
Click this.
</span>

The style property doesn't support selectors.
You need to move your logic into a <style> element or a <link>ed stylesheet.
There are plenty of React-friendly libraries for generating them on-the-fly for you. Styled Components is a popular tool for this which supports the SCSS syntax you are (almost — you have a rogue space after the &) using.
import { styled } from 'styled-components';
const MySpan = styled.span`
color: red;
cursor: pointer;
&:hover {
text-decoration: underline;
}
`;
and then
<MySpan>Click this.</MySpan>
However, span elements are not designed to be interactive. They are not announced as clickable by screen readers and you can't tab to them if you aren't using a mouse. This is a major accessibility barrier. If you want something for the user to click on, use a link (if you are linking somewhere) or a button (otherwise).

According to here:
There has been plenty of valid points made that react inline style is not a good idea. No support for CSS selectors like “:hover”, “:active” “:focus”, “:before” and “:after”, media queries, nor for SCSS syntax, to name a few.
Just use a css file and implement it there with class:hover

try this, I Tried it and it works.
App.js:
import "./styles.css";
export default function App() {
return (
<div className="App">
<span
style={{
color: "red",
cursor: "pointer"
}}
>
Click this.
</span>
</div>
);
}
style.css:
.App {
font-family: sans-serif;
text-align: center;
}
span:hover {
text-decoration: underline !important;
color: "red";
}

Related

How to change the text color of the material radio button

I need your help. I have a small piece of code. I use Material UI together with Angular. I have a group with a radio button. The fact is that the text in the radio button does not change, although I set the scss value to change to this color: # 262D34.
<mat-radio-group aria-label="Select an option" style="display: flex; flex-direction: column">
<mat-radio-button value="1" class="radio_button">
Roman Dyshko
</mat-radio-button>
<mat-radio-button value="2" class="radio_button">
Roman Dyshko
</mat-radio-button>
</mat-radio-group>
.radio_button {
font-family: 'Work Sans', serif;
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 150%;
text-decoration-line: underline;
color: #556EE6;
}
mat-radio-group mat-radio-button .radio_button {
color: #556EE6;
}
You must use ::ng-deep if you want to have fully access to the styling of those components. Like this:
::ng-deep mat-radio-group mat-radio-button .radio_button {
color: #556EE6;
}
Above code would work generally, in case you want to go through a component styling.
Updated answer
In case you want to restyle your radio buttons, it should be something like this:
::ng-deep
.mat-radio-button.mat-accent.mat-radio-checked
.mat-radio-outer-circle {
border-color: blue; /*change radio button color when selected*/
}
::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle {
background-color: red; /*change radio button inner circle color */
}
::ng-deep .mat-radio-outer-circle {
border: 1px solid black; /*change radio button not checked border */
}
::ng-deep .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element {
background-color: rgba(0, 0, 0, 0.1) !important; /* change click effect color */
}
Note: I used !important, because as said, only in a few cases you must use force the style to change.
You need to override the default style with ::ng-deep. It is deprecated feature and it might change the color application wide. So use with caution like this.
::ng-deep mat-radio-group mat-radio-button .radio_button {
color: #556EE6 !important; //<--- not necessary but needed in some cases
}
You need to add !important (in some cases) and kill your terminal if you have an active one. Re-compile the app again it should solve your problem.
Material Radio Buttons
Text Color
Angular's API states that the ng-deep psuedo-class is deprecated and completely disables view-encapsulation for that rule.
If we use it without the :host pseudo-class, it will make the style-rule global, not a good thing. Which is what Angular will suggest you to do if there is no other way. (There is not atm.)
You can just use this in styles.scss, if you are sure you want them to bee applied globally.
.mat-radio-button {
color: pink;
}
Or if you want to use a color from your palette:
.mat-radio-button {
color: mat.get-color-from-palette($primary-light, 400);
}
If however you want it applied just to a specific radio-button in some.component.scss, you can use ::ng-deep, but make sure to use the :host pseudo class to prevent the rule from bleeding out of the component:
:host ::ng-deep .mat-radio-button {
color: #556EE6;
}
In short, you just need to know the right class names to override. In some cases like the ripple, the !important is needed to override the default.
What about !important ?
Some people also like to override the ripple to be in a secondary or off-color. So I'll use that as an example:
.mat-radio-ripple .mat-ripple-element {
background-color: mat.get-color-from-palette(
$accent-palette,
A400
) !important;
}
For this, or other styles you have already overwritten in your styles.scss, you do need to add !important.
Only Select Tags
Another example for when you want only select groups/radio-buttons to gain the styling. You can add your own class to it as an extra selector.
Template:
<li>
<mat-radio-group
class="pink"
aria-label="Select an option"
formControlName="gender"
>
<mat-radio-button color="primary" value="male">Male</mat-radio-button>
<mat-radio-button value="female">Female</mat-radio-button>
</mat-radio-group>
</li>
Css:
.pink .mat-radio-button {
color: pink;
}
Or for just one of the radio buttons:
<div class="pink">
<mat-radio-button value="female">Female</mat-radio-button>
</div>
Dynamically Add them on a Condition
Or here's another example if you want a style to be applied dynamically.
Template:
<div [ngClass]"getClass()">
<mat-radio-button value="female">Female</mat-radio-button>
</div>
Script:
getClass(event: Event) {
if(/* Your conditions */)
return ['pink']
return []
}
Stackblitz
Here's a Material Form Example on my Stackblitz account I edited to show everything you can find above (and more), including a Matial Theme etc. In it I'm overriding the mat-radio-button globally in styles.scss and also in app.component.scss.

scss wrong selector being matched

I have two components called GroceryItem and BasketItem. Since these components share quite a few styles and I didn't want to write the same properties in different stylesheets, I set up a stylesheet called _item-layout.scss that has all the common styles and then imported this in both BasketItem.scss and GroceryItem.scss.
The core difference between these components is that the BasketItem icon is meant to switch from white to red when the enclosing div is hovered upon, whereas the GroceryItem icon is meant to switch to green. To enable this functionality, I set the hover property to change colour in the BasketItem and the GroceryItem stylesheets.
The thing is, both components change icon colour to red when hovered on. This is especially confusing for me because in my GroceryItem.js file, I've only imported GroceryItem.scss. So how can it match a selector that isn't even present in the stylesheet that has been imported?
item-layout.scss:
.root {
background-color: rgba(230, 230, 230, 1);
margin: 10px 0px;
user-select: none; //standard syntax
-webkit-user-select: none; //webkit (safari, chrome) browsers
-moz-user-select: none; //mozilla browser
-khtml-user-select: none; //webkit (konqueror) browser
-ms-user-select: none; //IE10+
.p {
font-weight: 500;
}
}
.icon {
margin-right: 10px;
color: whitesmoke;
}
.row-content {
display: flex;
padding: 15px;
}
GroceryItem.scss:
#import "./../../styles/_item-layout";
.root:hover .icon {
color: green;
}
BasketItem.scss:
#import "./../../styles/item-layout";
.root:hover .icon {
color: red;
}
GroceryItem.js:
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faPlusSquare } from "#fortawesome/free-solid-svg-icons";
import "./GroceryItem.scss";
import React from "react";
function GroceryItem(props) {
return (
<div className="root" onClick={props.onClick} >
<div className="row-content">
<FontAwesomeIcon icon={faPlusSquare} className="icon"/>
<p>{props.title}</p>
</div>
</div>
)
}
export default GroceryItem;
I think the problem is that you have hover styles for the root class and you're using this class in both components.
If you import BasketItem.js or GroceryItem.js, their respective scss files will also be imported. Each of these scss files sets the color of elements with class root on hover to either red or green. So whichever js file is imported last will indirectly decide the root class hover color.
Since you say both components have a red hover color BasketItem.js is probably imported after GroceryItem.js based on the code in your question. If you switch the import order around you will probably see both components turn green.
The simple solution here is to just use separate classes for GroceryItem and BasketItem so there is no collision / involuntary overwriting of styles.
Both declarations of icon styles are in the same scope so the last loaded scss file overwrites the first one.
You could add an additional classname in both components and use them as a kind of color flag. Lets say in first component you add the css classname green next to your icon classname and in the second one add red next to your icon classname. So you have:
... className="icon green" ... and
... className="icon red"
In you main scss file you do
.root {
.icon {
&:hover {
&.green {
color: green;
}
&.red {
color: red;
}
}
}
}
Of course add the other styles you have set for your root class

How to override materialize css in React

I am using react to build simple app, and using Materilize css. In my UserProfile Component class importing UserProfile.css import "./UserProfile.css.
/* UserProfile.css */
.custom-class {
margin-top: 30 !important;
color: pink;
}
UserProfile in render method have
<h1 className="custom-class">Title</h1> // Margin is not applyed, but color is pink
I have an option to
<h1 style={{ marginTop: 30, color: "pink" }}>Title</h1>
this works fine, but I prefer style code in css files.
I am not sure maybe that issue has no relation to overriding.
you should use px in css files, change your code to margin-top: 30px !important; and it should work.
And if you want to check overriding issues in css, you can inspect your code(with right click your browser and choose inspect) and check if its crossed or not.
You'll need to use camelCase for your classname, so .customClass instead of .custom-class.
Then your import statement should look like:
import css from './UserProfile.css`;
and in your component:
<h1 className={css.customClass}>Title</h1>
Read up on CSS Modules for more information.
You don't have a unit for margin-top in your css class
.custom-class {
margin-top: 30px !important;
color: pink;
}

target first-child css styled-components

I am using styled-components and want to target the first child of Text, but am unable to do so.
const Text = styled.p`
font-size: 12px;
&:first-child {
margin-bottom: 20px;
}
`;
... component
return(
<div>
<p>I am just regular text</p>
<p>Me too</p>
<Text>Hello Joe</Text> // this should have the margin bottom
<Text>Goodbye</Text >
</div>
)
Finally, I got your issue. The styled component confuses with the first two native p tag (from my perspective) and that's the reason why the CSS is not applied.
I will use a workaround like this:
const Text = styled.p`
font-size: 12px;
color: blue;
&:nth-child(3) {
margin-bottom: 20px;
color: red !important;
}
`;
By doing this, you are selecting the third child (which include the first two p tag) for the CSS
OR, you can do something like this: Adding a class name for the tag and giving CSS for that class.
const Text = styled.p`
font-size: 12px;
color: blue;
&.colors {
margin-bottom: 20px;
color: red !important;
}
`;
<div>
<p>I am just regular text</p>
<p>Me too</p>
<Text className="colors">Hello Joe</Text>
<Text>Goodbye</Text>
</div>
Here is the demo
Hope it helps :)
Use like this
const Text = styled.p`
font-size: 12px;
> * {
&:first-child {
margin-bottom: 20px;
}
}
`;
There shouldn't be a space between the & and the :first-child
&:first-child {
margin-bottom: 20px;
}
it's better to use :last-of-type on certain styled component instead of using :nth-child and it works perfectly
export default styled.div`
:last-of-type {
background: red;
}`
const Text = styled.p`
font-size: 12px;
color: blue;
&:nth-child(3) {
margin-bottom: 20px;
color: red !important;
}
`;
This is possible, but probably not correct
This totally is possible, as we see with the other answers. The issue is that with first-child or nth-child solutions you tend to end up reaching down the DOM hierarchy, creating all sorts of specificity issues that can be difficult to untangle later.
The beauty of Styled Components is you typically apply styles to the element itself, meaning your styles stay tightly coupled to your components. Components become portable, and it's easy to find the line of CSS that might be causing an issue in a complex app.
for example, if I were to style the first <a> in a list item in a ul differently, I'd need to put :first-child further up the hierarchy, breaking encapsulation.
Treat your styles as a function
The simple solution to this is to recognise that the styled component is a function that can receive parameters:
<StyledListItem index={index} />
Then receive that parameter in the component:
export const StyledListItem = styled.li<{index?: number}>`
${
({index}) => {
if (index === 3) return `
color: red;
border: 2px dotted pink;
`
if (index === 0) return `
border-left: none
`
}
}
`
CSS in JS facilitates these kinds of programmatic solutions, and your life will be easier if you leverage them.

Set font size of Angular Material Tooltip

I am very new to web development, and I cannot figure out how to solve the following issue, although it may be very easy.
I am using Angular 4 and Angular Material to implement tooltips like this:
<div mdTooltip="tooltip text" mdTooltipPosition="above">
<span>Show tooltip</span>
</div>
I would like to make the font size of the tooltip text bigger. However, I did not manage to find how to do this in the Angular Material documentation, neither searching in the web. Does anyone have any idea on how to do this? Thanks.
You can fix this by adding a .mat-tooltip css declaration in you main styles file and change the font size there. You need to set !important on the font size otherwise it won't show up.
Per the documentation here: https://material.angular.io/components/tooltip/api
And the spec: https://github.com/angular/material2/blob/master/src/lib/tooltip/tooltip.spec.ts
You can set the property 'matTooltipClass', as follows:
<div matTooltip="tooltip text" matTooltipPosition="above" matTooltipClass="tooltip">
<span>Show tooltip</span>
</div>
Then in your CSS (global - not for the component):
.mat-tooltip.tooltip {
background-color: darkblue;
font-size: 12px;
}
Also see their demo here: https://github.com/angular/material2/tree/master/src/demo-app/tooltip
Also keep in mind if you are using SASS, that the container for the tooltip is at the bottom and nowhere near where you are placing it in your component's HTML, so do not nest it in that component. Make sure it is standalone, otherwise it will not work. This note applies as well obviously to the comment above if you just choose to override .mat-tooltip
To see the changes, in developer tools, find the div at the bottom with the class "cdk-overlay-container". Then hover over the element. You can use your arrow keys to navigate into the element while you are hovered over to confirm whether your class is being added.
You can use css /deep/ selector.
For example:
/deep/ .mat-tooltip {
font-size: 14px;
}
Then you do not have to use !important
Add ng-deep before class name
Try this
::ng-deep .mat-tooltip {
background: red!important;
}
My problem was that using a globally defined css class-name such as .customname-toolip for matTooltipClass was NOT working. My solution below, and the !important was needed; set in the global styles.css file:
.mat-tooltip {
font-size: 16px !important;
}
add following code in your styles.css to increase its font size i.e. 12px
CSS
.mat-tooltip {
font-size: 14px !important;
}
and use matTooltip in your tag's as.
<p matTooltip="My Tooltip">...<p>
Try this way. It should work.
test.component.html
<div mdTooltip="tooltip text" mdTooltipPosition="above" matTooltipClass="myTest-tooltip">
<span>Show tooltip</span>
</div>
test.component.ts
#Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
encapsulation: ViewEncapsulation.None,
/*
styles: [`
.myTest-tooltip {
min-width: 300px;
background-color: #FC5558;
font-size: 16px;
}
`]*/
})
test.component.scss
.myTest-tooltip {
min-width: 300px;
background-color: #FC5558;
font-size: 16px;
}
Use matTooltipClass to apply your custom class on tooltips
<button mat-raised-button
matTooltip="Adding a class to the tooltip container"
matTooltipClass="custom-tooltip">
Custom tooltip
</button>
Add your style in your component style.scss file
.custom-tooltip {
font-size: 20px !important;
}
You can set custom style only for your component by adding a custom class + using /deep/, which will apply the css changes only for your custom class and not globally.
for example adding a custom tooltip for an image tag :
<img
matTooltip="text"
matTooltipClass="my-custom-class"<----
src=""/>
and in the css file :
/deep/ .mat-tooltip.my-custom-class {<---
background: #FFFFFF;
}
I dont have an experience with angular but you may add a class or id for div. Then you may control with this class or id with css file.
<div class="sth" mdTooltip="tooltip text" mdTooltipPosition="above"> <span>Show tooltip</span> </div>
And
.sth{
font-size:20px;
}
in css file.
In v15, you can change css variables
body{
.mat-mdc-tooltip{
--mdc-plain-tooltip-container-color: #616161;
--mdc-plain-tooltip-supporting-text-color: white;
--mdc-plain-tooltip-supporting-text-font: Roboto, sans-serif;
--mdc-plain-tooltip-supporting-text-size: 12px;
--mdc-plain-tooltip-supporting-text-weight: 400;
--mdc-plain-tooltip-supporting-text-tracking: 0.0333333333em;
line-height: 12px;
}
}
Put this in your component css (or home component css if you want to apply it globally. note that putting this in your global css file won't work, and you have to put it in the home component css to apply it globally).
::ng-deep .mat-tooltip {
font-size: 16px;
}

Resources