CSS - Extending class properties - css

I'm pretty new to CSS and have been finding my way around so far.
I am creating these button like links with shadows and stuff. Now there are several such buttons required on the site - everything about the buttons is same - except few properties change like width and font size.
Now instead of copying the same code - over and over for each button - is there a way of extending the button and adding just the properties that change.
Example of two buttons - css
.ask-button-display {
background: #8BAF3B;
border-radius: 4px;
display: block;
letter-spacing: 0.5px;
position: relative;
border-color: #293829;
border-width: 2px 1px;
border-style: solid;
text-align:center;
color: #FFF;
width:350px;
font-size: 20px;
font-weight: bold;
padding:10px;
}
.ask-button-submit {
background: #8BAF3B;
border-radius: 4px;
display: block;
letter-spacing: 0.5px;
position: relative;
border-color: #293829;
border-width: 2px 1px;
border-style: solid;
text-align:center;
color: #FFF;
font-weight: bold;
width:75px;
font-size: 12px;
padding: 1px;
}
And this is how I'm currently using it in my html
Ask a Question Submit
So I'm wondering if there is a cleaner way to do this - like
.button {
/* PUT ALL THE COMMON PROPERTIES HERE */
}
AND THEN SOMEHOW EXTEND IT LIKE
.button #display {
/* THE DIFFERENT PROPERTIES OF Display BUTTON */
}
.button #ask {
/* THE DIFFERENT PROPERTIES OF Ask BUTTON */
}
But I'm not sure how to do this.
Thanks for your inputs

You can add multiple classes to one element, so have one .button class which covers everything, then a .button-submit class, which adds things in.
For example:
.button {
padding: 10px;
margin: 10px;
background-color: red;
}
.button-submit {
background-color: green;
}​
See a live jsFiddle here
In your case, the following should work:
.button {
background: #8BAF3B;
border-radius: 4px;
display: block;
letter-spacing: 0.5px;
position: relative;
border-color: #293829;
border-width: 2px 1px;
border-style: solid;
text-align:center;
color: #FFF;
width:350px;
font-size: 20px;
font-weight: bold;
padding:10px;
}
.button-submit {
width:75px;
font-size: 12px;
padding: 1px;
}​
See a live jsFiddle here

You might want to try this:
.button {
padding: 10px;
margin: 10px;
background-color: red;
}
.button.submit {
background-color: green;
}
.button.submit:hover {
background-color: #ffff00;
}
This way you avoid repeating the word and will able to use the classes in the elements like this:
Ask a Question
Submit
See the example in JSFiddle (http://goo.gl/6HwroM)

Rather than repeat the common "Add a button class to the element" answer I'm going to show you something new in the weird and whacky world of new age CSS, or better known as SCSS!
This reuse of code in stylesheets can be achieved with something called a 'Mixin'. What this allows us to do is reuse certain styles by using the '#include' attribute.
Let me give you an example.
#mixin button($button-color) {
background: #fff;
margin: 10px;
color: $color;
}
and then whenever we have a button we say
#unique-button {
#include button(#333);
...(additional styles)
}
Read more here: http://sass-lang.com/tutorial.html.
Spread the word!!!

You can do this since you can apply more than one class to an element. Create your master class and and other smaller classes and then just apply them as needed. For example:
Ask a Question Submit
This would apply the button and submit classes you would create while allowing you to also apply those classes separately.
Modify your code example along the lines of:
.master_button {
/* PUT ALL THE COMMON PROPERTIES HERE */
}
AND THEN SOMEHOW EXTEND IT LIKE
.button_display {
/* THE DIFFERENT PROPERTIES OF Display BUTTON */
}
.button_ask {
/* THE DIFFERENT PROPERTIES OF Ask BUTTON */
}
And apply like:
Ask a Question
Submit

.ask-button-display,
.ask-button-submit {
/* COMMON RULES */
}
.ask-button-display {
}
.ask-button-submit {
}

You may want to look into Sass. With Sass you can basically create variables in your css file and then re-use them over and over. http://sass-lang.com/
The following example was taken from Sass official website:
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}

Add a button class to both links for the common parts
.button {
background: #8BAF3B;
border-radius: 4px;
display: block;
letter-spacing: 0.5px;
position: relative;
border-color: #293829;
border-width: 2px 1px;
border-style: solid;
text-align:center;
color: #FFF;
}
Keep in your other classes the rules that aren't common.
And your HTML will be
Ask a Question
Submit

Without changing/ adding new classes you can add styles to all elements with a class name starting with "ask-button"... (whatever the elements with the class are; button, anchor, div etc.) let's say your buttons are divs then:
div[class^="ask-button"] {
// common css properties
}
You can also list all classes that will have common properties like this:
.ask-button-display,
.ask-button-submit {
// common css properties here
}
And then you add the separate styling for each button:
.ask-button-display{
// properties only for this button
}
.ask-button-submit {
// properties only for this button
}

Related

How would I use Sass to give something a default but optionally overridable value?

I'd like to use Sass to create a reusable HTML snippet with default values, but then make those values optionally customizable. Let's say I'm making a button and I set up some base SCSS to make the button red by default like so:
%button-shared {
$button-color: red;
td {
border-color: $button-color;
color: $button-color;
background-color: white;
text-decoration: none;
width: 50px;
height: 15px;
border-radius: 6px;
}
}
I use a variable because I want it set in two different places. In this example, I want a white button with a colored outline that matches colored text like so:
Now let's say I give my two buttons in HTML different classes, button-one and button-two. Now I'd like to assign that SCSS to my two buttons, so I extend %button-shared to those two HTML classes. Except, I'd also like button-one to be a different color from the default red:
.button-one {
$button-color: green;
#extend %cta-shared;
}
.button-two {
#extend %cta-shared;
}
Unfortunately, this implementation ends up with them both being red. How can I setup my SCSS to allow for easy overriding of of a variable?
Use mix-ins: https://sass-lang.com/documentation/at-rules/mixin
#mixin button-shared($button-color: red) {
td {
background-color: white;
border-color: $button-color;
color: $button-color;
text-decoration: none;
width: 50px;
height: 15px;
border-radius: 6px;
}
}
.button-one {
#include button-shared(green);
}
.button-two {
#include button-shared();
}

How to style the input type "time"

I'm trying to find a source explaining how to fully style the input type "time". I cannot find a single example explaining all of the style attributes!
Only one I've found is:
input[type="time"]{
/**style goes here **/
}
Which doesn't help much..
Tried this:
input[type="time"]::-webkit-inner-spin-button {
-webkit-appearance: none;
cursor:pointer;
display: block;
width:20px;
color: red;
text-align:center;
position:relative;
}
Spinner does not turn red for example.
I made some progress styling the input in Chrome/webkit, but I can't figure out how to style anything in Firefox. Here's a demo that I put together on Codepen.
input[type=time] {
border: none;
color: #2a2c2d;
font-size: 14px;
font-family: helvetica;
width: 180px;
}
/* Wrapper around the hour, minute, second, and am/pm fields as well as
the up and down buttons and the 'X' button */
input[type=time]::-webkit-datetime-edit-fields-wrapper {
display: flex;
}
/* The space between the fields - between hour and minute, the minute and
second, second and am/pm */
input[type=time]::-webkit-datetime-edit-text {
padding: 19px 4px;
}
/* The naming convention for the hour, minute, second, and am/pm field is
`-webkit-datetime-edit-{field}-field` */
/* Hour */
input[type=time]::-webkit-datetime-edit-hour-field {
background-color: #f2f4f5;
border-radius: 15%;
padding: 19px 13px;
}
/* Minute */
input[type=time]::-webkit-datetime-edit-minute-field {
background-color: #f2f4f5;
border-radius: 15%;
padding: 19px 13px;
}
/* AM/PM */
input[type=time]::-webkit-datetime-edit-ampm-field {
background-color: #7155d3;
border-radius: 15%;
color: #fff;
padding: 19px 13px;
}
/* 'X' button for resetting/clearing time */
input[type=time]::-webkit-clear-button {
display: none;
}
/* Up/Down arrows for incrementing/decrementing the value */
input[type=time]::-webkit-inner-spin-button {
display: none;
}
<input type="time" value="13:30"/>
I wasn't able to find documentation anywhere. I got this far by inspecting the input's internal DOM, hovering over each element in devTools to see what portion of the UI it corresponded to, then grabbed its pseudo attribute.
If you can't currently see the internal DOM, you'll have to expose it by going into Chrome's DevTools Settings, Preferences, Elements and make sure the "Show user agent shadow DOM" option is enabled.
There's another pseudo element: -webkit-calendar-picker-indicator - the clock that shows up in chrome to allow you picking time using a mouse.
input[type="time"]::-webkit-calendar-picker-indicator {
filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg);
}
<input type="time">
To style the input type date and time - use the following css -
[type="date"] {
background:transparent url(/assets/images/calendar.png) 97% 50% no-repeat !important;
}
[type="date"]::-webkit-inner-spin-button {
display: none;
}
[type="date"]::-webkit-calendar-picker-indicator {
opacity: 0;
}
[type="time"] {
background:transparent url(/assets/images/clock.png) 97% 50% no-repeat !important;
}
[type="time"]::-webkit-inner-spin-button {
display: none;
}
[type="time"]::-webkit-calendar-picker-indicator {
opacity: 0;
}

replacing global css with local css

I am trying to edit the style of a popover. In this case I want to edit the width of the display. However, I have a global popover style sheet that applies to all popovers in the application.
/* ========================================================================
Component: popovers
========================================================================== */
.popover {
border-radius: 0;
border: none;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
.arrow {
margin-left: -7px !important;
}
.popover-header {
padding: 1rem 0.75rem 0.5rem;
display: block;
background-color: $secondary;
border-bottom: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.popover-body {
padding: 0.5rem 1rem;
color: $body-color;
}
.popover-close {
position: absolute;
top: -2px;
right: 0;
padding: 0 0.5rem;
color: $gray-lighter;
font-size: 2rem;
font-weight: 400;
line-height: 1;
text-shadow: 0 1px 0 #fff;
&:hover {
cursor: pointer;
color: $body-color;
}
}
I would like to know how in my local css file I can overwrite/add to these inherited styles.
Local Style Sheet:
.team-activity-container {
.icon {
background-image:
background-repeat: no-repeat;
display: inline-block
}
.icon .icon-team {
background-position: -5px -5px;
width: 25px;
height: 25px
}
}
.popover {
background-color: aqua !important;
width: 500px;
}
Edit: The local stylesheet is in the container that displays the popover, and the classes in the html are all related to the contents that fill the popover. While the popover and it's stylesheets are at the global level. how can I edit the popover at the local level without having to touch the global style sheet.
Also, The popover is from ng-bootstrap and I believe the problem is I can't overwrite the default width that bootstrap sets
I don't know all the context you are in, but there are 3 main ways to overwrite existing CSS rules:
add a new stylesheet with the new rules after the existing ones;
if you have control over the new popover HTML, adding a class (for instance version2 so you can edit your variant in a meaningful way as .popover.version2 inheriting what is already sets and changing just what you need);
add "!important" to the rules you add and are intended to overwrite the others, but notice that if the existing rules have already that, it's not going to work.
Depends on the context there could be other solutions like leverage on HTML tags or HTML tags properties if your new popover has some difference with the previous for examples.
I hope this helps.
EDIT: I saw you have edited your question adding stuff.
Looking at the global CSS, if your popover is in a particular container just bind the new rules to the container like this:
.team-activity-container .popover {...rules};

Navigation link changing colors randomly

I have built a navigation list for a client and they opted to use the [Oswald]() font-face.
Now when the user scrolls over the link a navigation arrow will pop up to the side indicating which link is currently click, it is NOT supposed to turn orange upon hovering. I have removed any javascript and the fontface entirely and still can not remove the problem.
Here is a screenshot of the issue http://cl.ly/043a0q0o0Q392q2m1k20
My CSS (SASS) is as follows:
#leftnav {
width: 205px;
float: left;
ul {
li {
border: 1px solid #fff;
border-top: 0px;
background: #cc5816;
padding: 3px 10px;
#include gradient($top_color: #d86c07, $bottom_color: #bb5e06);
a {
position: relative;
font-family: $main_bold_font;
font-size: 16pt;
color: #fff;
text-decoration: none;
text-shadow: $text_shadow;
}
a:hover { #extend a; }
a:visited { #extend a; }
}
}
}
Any Ideas?
I dont know for sure if this solves the problem. But, as stated here, I would recommend to change the order of :hover and :visited to be :visited and :hover. Maybe it helps to analyse the compiled css.

SASS, when to extend?

I'm currently working on a team that uses SASS. I see that we are extending styles that are very simple and to me I don't see the benefit of doing this. Am I missing something?
Here are some examples of a _Common.scss that is imported and used throughout other sass files:
.visibility-hidden{visibility: hidden;}
.display-inline { display: inline; }
.display-inline-block { display: inline-block; }
.display-block { display: block; }
.display-none { display: none; }
.display-box { display: box; }
.float-left { float: left; }
.float-right { float: right; }
.clear-both { clear: both; }
.width-percent-100 { width: 100%; }
.width-percent-65 { width: 65%; }
.width-percent-50 { width: 50%; }
.width-percent-45 { width: 45%; }
.width-percent-40 { width: 40%; }
.width-percent-33 { width: 33%; }
.width-percent-30 { width: 30%; }
.width-percent-20 { width: 20%; }
.height-percent-100 { height: 100%; }
.cursor-pointer { cursor: pointer; }
.underline { text-decoration: underline; }
.text-decoration-none { text-decoration: none; }
.bold { font-weight: bold; }
.font-weight-normal { font-weight: normal; }
.text-align-center { text-align: center; }
.text-align-left { text-align: left; }
.text-align-right { text-align: right; }
.font-10 { font-size: 10px; }
.font-11 { font-size: 11px; }
.font-12 { font-size: 12px; }
.font-13 { font-size: 13px; }
.font-14 { font-size: 14px; }
.font-15 { font-size: 15px; }
.font-16 { font-size: 16px; }
.font-17 { font-size: 17px; }
.font-18 { font-size: 18px; }
.font-percent-65 { font-size: 65%; }
.font-percent-80 { font-size: 80%; }
.font-percent-90 { font-size: 90%; }
.font-percent-100 { font-size: 100%; }
.font-percent-110 { font-size: 110%; }
.font-percent-120 { font-size: 120%; }
.font-percent-130 { font-size: 130%; }
.font-percent-140 { font-size: 140%; }
.font-percent-150 { font-size: 150%; }
.font-percent-160 { font-size: 160%; }
.font-percent-170 { font-size: 170%; }
.font-percent-180 { font-size: 180%; }
Example:
#CategoriesContainer
{
ul{
li{
&:first-child{
#extend .font-11;
}
a
{
#extend .font-11;
#extend .text-decoration-none;
}
}
}
}
You should only use extend when you have a certain attribute set that will be used multiple times. The sheer stupidy of extending a class with a class with one attribute that has the unit value worked into the name of it is incomprehensible.
A better example for a reason to extend can be found in the reference guide
Say we have 2 classes
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
.error is a general no interesting style but a serious error should be really clear.
.seriousError is created to thicken the line, the only problem is that now we have to use both classes in the html to combine the styles.
Because we're lazy and just want to use one class and not duplicate code that might be changed in the future we can extend .seriousError with .error
.seriousError {
#extend .error;
border-width: 3px;
}
Now we didn't duplicate the code in our sass file but did get the right styles on the page.
Check out the reference guide for more/better examples.
Just please for the sake of kittens stop extending classes with one attribute classes. And don't implicitly state the value/attributes in the selector, thats not very semantic.
You, and your team, should read this post which explains a few problems with the aproach you take here vs semantic code. Couldn't find a better tuned post this quick.
You aren't missing anything, this is just bloated code in poor form and not a great way to extend classes.
There is maybe one (bad) reason I can imagine why this would be used. If for example .font-10 needs to be .7em instead of 10px, it can be easily changed - but then you've just defeated the point of naming the class "font10". Something like small-font would even make more sense in that case (and I'm not suggesting you use that either).
I won't discuss the merits of semantic class names and the folly of presentational ones (especially as literal as these are), but I will suggest that this is a very narrow use of extending classes. With a 1:1 mapping of class name to property/value, you've practically defeated the purpose of #extend, which is supposed to make you write less CSS.
Better example of what to use #extend for:
.media {
padding:1em;
border-color:blue;
background-color:red;
clear:left;
}
.my-media {
#extend .media;
background-color:green;
}
Atomic CSS
The technique of very simple CSS rules does have a bit of precedent - at Yahoo! they call it Atomic CSS. Thierry Koblentz argues in this Smashing Magazine article for using the simple classes directly in your markup, similar to inline styling. This can be helpful on very large projects across multiple web properties, where styles are not consistent. Base styles for OOCSS components can't be reused as much in such a situation, causing you to have to write many more lines of extension classes or overrides.
The downside is, of course, as Wesley mentioned, that it is much more difficult to make changes across your entire project's styles, such as updating the text size of a specific selector.
I've been playing around with a variant of this technique recently in a fairly large project, where styles can often be one-off. In an effort to avoid the I try to avoid putting hard values directly in the selectors. For instance, the following css (example fiddle):
_colors.scss
.text-white {
color: $white;
}
.blue {
#extend .text-white;
background: $blue;
}
_effects.scss
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
text-align: center;
line-height: 50px;
font-size: 40px;
}
.matted {
border: 4px solid $white;
}
.shadow {
#include box-shadow(0 1px 4px 1px rgba($black, 0.25));
}
HTML:
<div class="blue matted circle shadow">?</div>
Specificity issues
One last thing to keep in mind if you decide to use this technique - it can cause specificity problems if you're extending base-level classes that use the same CSS properties. For instance, in the following example (fiddle), how would your border-radius appear? You wanted the top to be squared off (no border-radius) but this isn't happening, because the .circle class is further down in your css and just as specific (single class) as the other effects. This is a bit of a contrived example, but if you reuse CSS properties across your atomic selectors, this can be a real problem.
_colors.scss
.text-white {
color: white;
}
.blue {
#extend .text-white;
background: royalblue;
}
_effects.scss
.squared-top {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.rounded {
border-radius: 10px;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50%;
}
HTML:
<span class="circle blue rounded squared-top"></span>
If you do it that way you can also use it directly in the HTML - so it looks like they took the OOCSS path and because it's already in the CSS you can now also extend to it. Very flexible but it could also turn very messy.
Extend option is used poorly here. It should be used for extending classes with more content and in that case extend can be very helpful.You can find more about extend and its options here.

Resources