Overriding styles in semantic ui react - css

I'm using Semantic UI React and trying to figure the best way to override default styles, so that I can change the appearance of cards and the overall theme.
Option 1 seems to be to define my CSS and put !important after every rule, which is not great.
Option 2 is the theming support, which sounds like what I want, except I cannot determine how to get started with that. My app is using CRA, and I'm a bit lost in documentation between changing my webpack configuration file (I don't have one), out of date blog posts from 2017 advising me to install a bunch of modules whose purpose is unclear, and the theming site itself which is advising me to define flexible variable files (an approach I like).
I can't determine why my theme files aren't getting picked up though, and it appears some sort of build fix is necessary that isn't covered by the theming guide.
What's the best way to get theming working while using a CRA build process? (./node_modules/.bin/react-scripts build)

Specificity is king. Only time would need to use !important would be when inline style is present and the library does not expose a way to toggle the property off in some way (poor architecture choice).
The following list of selector types increases by specificity:
Type selectors (e.g., h1) and pseudo-elements (e.g., ::before).
Class selectors (e.g., .example), attributes selectors (e.g.,
[type="radio"]) and pseudo-classes (e.g., :hover).
ID selectors (e.g.,
#example).
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
Take a look at the first UI Button for Semantic UI here, is comprised of the following HTML:
<button class="ui button">Click Here</button>
CSS is attached via semantic.min.css:
.ui.button {
cursor: pointer;
display: inline-block;
min-height: 1em;
outline: 0;
border: none;
vertical-align: baseline;
background: #e0e1e2 none;
color: rgba(0,0,0,.6);
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
margin: 0 .25em 0 0;
padding: .78571429em 1.5em .78571429em;
text-transform: none;
text-shadow: none;
font-weight: 700;
line-height: 1em;
font-style: normal;
text-align: center;
text-decoration: none;
border-radius: .28571429rem;
-webkit-box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
will-change: '';
-webkit-tap-highlight-color: transparent;
}
To override say, the font color, all we have to do is write a selector that is more specific than this selector. We can achieve this by combining their two class selectors (equally specific) with a type selector (additional specificity).
This would look like:
button.ui.button {
color: red;
}
Now since button.ui.button is more specific in describing the location of the element in the page (DOM), than say just .ui.button, this signals to the browser that this style should override the previous declaration. This is a common way to customize a theme.
Great docs here:
https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS
.ui.button {
cursor: pointer;
display: inline-block;
min-height: 1em;
outline: 0;
border: none;
vertical-align: baseline;
background: #e0e1e2 none;
color: rgba(0,0,0,.6);
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
margin: 0 .25em 0 0;
padding: .78571429em 1.5em .78571429em;
text-transform: none;
text-shadow: none;
font-weight: 700;
line-height: 1em;
font-style: normal;
text-align: center;
text-decoration: none;
border-radius: .28571429rem;
-webkit-box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
box-shadow: 0 0 0 1px transparent inset, 0 0 0 0 rgba(34,36,38,.15) inset;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;
transition: opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease,-webkit-box-shadow .1s ease;
will-change: '';
-webkit-tap-highlight-color: transparent;
}
button.ui.button {
color: red;
}
<button class="ui button">Click Here</button>

Actually you should never use !important unless you really REALY have too. Apart from making you styles look very ugly, its a very bad practice to make all your styles !important
Since you mentioned CRA, which supports SCSS Modules, I can tell you that there is a third option which in my opinion is a bit nicer.
Here it goes in 3 easy steps:
1. Set an id somewhere high in the hierarchy. I do it in the public/index.html on the body tag:
// public/index.html
...
<body id='app'>
...
2. Create a SCSS module file and wrap all your classes in a :global(#app)
// src/page.module.scss
:global(#app) {
.container {
padding: 2rem;
}
.button {
font-size: 3em;
}
}
3. Import the styles and pass them to the semantic components
// src/page.jsx
import React from 'react';
import { Button, Container } from 'semantic-ui-react';
import styles from './page.module.scss'
const Page = () => (
<Container className={styles.container}>
<Button className={styles.button} />
</Container>
)
The reason this works is because the output from the page.module.scss SCSS Module will be compiled to this:
#app .page_container_2oYQ {
padding: 2rem;
}
#app .page_button_2oYQ {
font-size: 3em;
}
As you can see it will add the #app id selector before the modularised class name, which will increase the specificity of your selectors, which in turn will override the semantic-ui ones.

When you have CSS file from semantic ui, bootstrap, angular material ui, etc, just to name a few. When you want to override the css for any element, the order in which you render or place your css file in your html determines the precedence.
For your css file to override some other css file, list yours at the bottom.
Of course ensure your css selector targets the element your want to override.
An picture is worth a 1000 words
Assuming you want to override this below from semantic ui
<!-- from semantic-ui.min.css file or cdn -->
#media only screen and (min-width: 1200px) {
.ui.container {
max-width: 768px !important;
margin-left: auto !important;
margin-right: auto !important;
}
}
<!--override in my-custom-ui.css file --->
#media only screen and (min-width: 1200px) {
.ui.container {
max-width: 360px !important;
margin-left: 10px !important;
margin-right: 10px !important;
}
}
<!--this is where precedence is set, the last css file has the highest precedence-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>my title</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui/dist/semantic.min.css"
/>
<!-- place your css file containing css overridden for semantic ui elements or other css at the bottom -->
<link rel="stylesheet" href="my-custom-ui.css" />
</head>
<body>
<header>
My header
</header>
<content>
My content
</content>
<footer>
My footer
</footer>
</body
<script/>
</html>

Related

CSS one element reverting on page change

I'm getting this weird css bug. It almost seems like a caching issue or something with chrome as I can't replicate locally.
I send the user an invite and if they go to the invite page and then return to any other page that shows the banner, it's displayed wrong as one line of text is in times new roman.
The bug only happens if you've not been to the site before and you go to invite page then click back to any other page that has the banner.
2 things I've noted that are really unusual and I'm struggling to understand are:
The text that is displaying incorrectly is one word in an <a>
element, but parts of the text are fine.
When I open inspector and toggle any part of the css for the element.
It resets to how it should look immediately.
Here are some pictures:
How the banner looks
How it usually/should look
The <a> tag containing the button
As a sidenote I'm using chrome and rails 4 without turbolinks. Here is the code for the button:
.childminder-banner .btn {
padding: 3px 1em;
}
.btn-blue {
background: #34A9CD;
color: white;
}
.btn {
color: white;
-webkit-transition: none .1s ease-out 0s;
transition: none .1s ease-out 0s;
-webkit-transition-property: color,background,border;
transition-property: color,background,border;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
position: relative;
display: inline-block;
line-height: 1.5;
font-family: "Gordita";
font-weight: 500;
border-radius: 3px;
cursor: pointer;
text-align: center;
-webkit-transition: border-color .1s ease-out,background-color .1s ease-out,color .1s ease-out;
transition: border-color .1s ease-out,background-color .1s ease-out,color .1s ease-out;
background-color: #FF8027;
border-color: #FF8027;
}
Give style to the anchor tag display:inline-block
a{
display:inline-block;
}

Scale :before when hovering

I'm trying to scale the :before content of my <span> when hovering over it. So far the style gets applied when hovering but there are no visual changes, the :before remains the same scale.
What I've got so far:
<div class="comment-actions">
<span class="comment-likes icon-ico-heart">
12
</span>
</div>
SASS (CSS):
.comment-likes
transition: all 100ms ease-in-out
color: #92a3b9
cursor: pointer
&:hover::before
transform: scale(1.5)
Icomoon:
.icon-ico-heart:before {
content: "\e914";
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
Increase the font-size on hover and add transition property to it.
.icon-ico-heart:before {
font-size: 10px;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
-ms-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.icon-ico-heart:hover:before {
font-size: 15px;
}
You can use just transition: font 0.3s ease; to apply transition only for font instead of all
Don't transform it with the scale property but use the font-size. So:
.icon-ico-heart:hover:before {
font-size: 20px;
}
You may not able to use the scale property for fonts or icon fonts,
Instead of this you can use font size property.
You can't transform the ::before element because it's display type is: display: inline,
you have to change it to display: inline-block or another.
.icon-ico-heart:before {
content: "\e914";
display:inline-block;
}

Navbar coloring links

I am having trouble with my navbar, and been stuck at this for some hours now.
My navbar looks like this:
<div id="pages">
<?php wp_nav_menu();?>
</div>
Very simple wordpress navbar. Wordpress gives every page on this menu automaticly a class name like .page-item-30 also wordpress gives them all the class .page-item.
What I want to achieve is so when i hover 1 Page the background turns red (#ff0000) and the font-color turns white; My css looks like this
#pages li{
display: inline;
float: left;
height: 20px;
padding: 5px;
margin: 0px;
margin-top: -17px;
transition: all 0.2s ease-in-out;
}
#pages li:hover{
background-color: #ff0000;
}
/**
.page-item-27:hover a{
color: white;
transition: all 0.2s ease-in-out;
}
.page-item-2:hover a{
color: white;
transition: all 0.2s ease-in-out;
}
.page-item-21:hover a {
color: white;
transition: all 0.2s ease-in-out;
}
**/
.page-item:hover a {
color: white;
transition: all 0.2s ease-in-out;
}
.current_page_item {
background-color: #ff0000;
}
.current_page_item a{
color: white;
}
Now i tried using .page-item-27 or so do define when the font-color has to change but that is very unreliable since it relies on the right ID of the page. So If i have a new page with a ID not in my CSS my navigation doesnt work right.
Is there a way of changing the color of the font?
In my current css there is this
.page-item:hover a {
color: white;
transition: all 0.2s ease-in-out;
}
which in my Mind should work, but it doesn't.
If you don't understand it completly under danielps1.de you can check out my live-page. Just hover my navigation on the left
Thanks for the help
I think your problem is just a little mistake.
Your CSS selector should be:
.page_item a:hover{
color: white;
transition: all 0.2s ease-in-out;
}
Instead of:
.page-item:hover a {
color: white;
transition: all 0.2s ease-in-out;
}
Hope I could help.
Try using
li.page_item a:hover {
color: white;
}
as the CSS selector!

css transitions with print styles

/* Content */
#content {
border-bottom-left-radius: 0 !important;
border-top-left-radius: 0 !important;
margin-top:0;
float:left;
display:block !important;
width:100%;
margin-left:0 !important;
padding-top:70px;
padding-left:205px;
transition: padding 0.25s ease;
-moz-transition: padding 0.25s ease;
-webkit-transition: padding 0.25s ease;
}
#media print {
#content {
margin: 0 !important;
padding: 0 !important;
}
}
If I remove the transition the stylesheet works as expected, otherwise when printing I have about 70px gap at the top.
It appears that the padding property is not applied in the #print style because of the transition. If I remove the css transition, the print styles get applied. Why is this happening so?
Bizarre! In absence of any insight, how about setting the transition properties in a separate rule wrapped in a #media screen query?
I solved it by doing this for print styles:
transition: none;
-moz-transition: none;
-webkit-transition: none;

CSS hover transition cross-browser compatibility

I have a simple language select page with pure CSS animated transitions. I've made a jsFiddle here.
How it's supposed to behave is as follows:
User mouses over one of two (or more) language selectors.
That language selector transitions upward and comes to full opacity. The relevant language text (e.g., English, Español) appears as well.
The user either clicks on the link or mouses out, in which case the transition reverses.
In Chrome, it behaves as expected.
In Firefox, when I mouse over one image, both move up.
In Opera, it behaves mostly as expected, but the text jumps back down after moving up.
I'm trying to understand why this would happen in these browsers, and how I can fix it, if possible.
In the case that jsFiddle is down, the relevant code is:
HTML
<div id="container"><div id="cell">
<div class="langcell"><a href="en/index.html">
<img src="http://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/200px-Flag_of_the_United_States.svg.png" /><br/><p>English</p></a>
</div>
<div class="langcell"><a href="es/index.html">
<img src="http://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Flag_of_Spain.svg/200px-Flag_of_Spain.svg.png" /><br/><p>Español</p></a>
</div>
</div></div>
CSS
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#container {
width: 100%;
height: 100%;
display: table;
}
#cell {
display: table-cell; vertical-align: middle; text-align: center;
}
.langcell {
display: inline-block;
margin: auto 1em;
}
a {
position: relative;
top: 0;
-webkit-transition: top 0.25s;
-moz-transition: top 0.25s;
-o-transition: top 0.25s;
transition: top 0.25s;
color: black;
text-decoration: none;
}
a:hover {
top: -16pt;
}
a p {
font-size: 14pt;
font-weight: bold;
text-transform: uppercase;
font-family: Verdana, Geneva, sans-serif;
letter-spacing: 0.05em;
opacity: 0;
-webkit-transition: opacity 0.25s;
-moz-transition: opacity 0.25s;
-o-transition: opacity 0.25s;
transition: opacity 0.25s;
}
a:hover p {
opacity: 1;
}
a img {
opacity: 0.65;
-webkit-transition: opacity 0.25s;
-moz-transition: opacity 0.25s;
-o-transition: opacity 0.25s;
transition: opacity 0.25s;
}
a:hover img {
opacity: 1;
}
I got weird problems on firefox(v12) as well, where it was moving both elements up on hover. Later versions (19v), it seemed resolved.
I think there was something going on with your selectors and how mozilla interprets things versus webkit. See if this jsfiddle works for you.
All I really did was change a lot of the selectors of a to .langcell and it seem to work. I had to re-adjust a bit of css to achieve the same style, like the nested .langcell a selector. I have a suspicion that it may be due to a being inline by default while p is block and img is inline-block.
I won't lie and say I understand fully why that was happening to begin with, but just in general, giving styles to classes over elements is not just a preference, it is more efficient at render time as well.
CSS Selector Performance
Code:
.langcell {
display: inline-block;
margin: auto 1em;
position: relative;
top: 0;
-webkit-transition: top 0.25s;
-moz-transition: top 0.25s;
-o-transition: top 0.25s;
transition: top 0.25s;
}
.langcell a {
color: black;
text-decoration: none;
}
.langcell:hover {
top: -16pt;
}
.langcell p {
font-size: 14pt;
font-weight: bold;
text-transform: uppercase;
font-family: Verdana, Geneva, sans-serif;
letter-spacing: 0.05em;
opacity: 0;
-webkit-transition: opacity 0.25s;
-moz-transition: opacity 0.25s;
-o-transition: opacity 0.25s;
transition: opacity 0.25s;
}
.langcell:hover p {
opacity: 1;
}
.langcell img {
opacity: 0.65;
-webkit-transition: opacity 0.25s;
-moz-transition: opacity 0.25s;
-o-transition: opacity 0.25s;
transition: opacity 0.25s;
}
langcell:hover img {
opacity: 1;
}
CSS3 is pretty new. And many of the features are still not compatible in many browsers. Compatibility Chart
So it is kind of off-putting if your clients have a bit older browsers (even if they have a year old version), in which case CSS3 transition wont work.
Your safest bet to make the transition is to do it using javascript or some javascript library such as jQuery

Resources