Inheritance of animation keyframes of element - css

I've got an element .shake and when it's :hover an animation starts. I need to inherit the shake element properties and its animation :hover effect.
I've got
.inherit-shake {
.shake;
}
It doesn't work because .inherit-shake just inherits the primary .shake properties but its :hover animation.
Is there a way to do that using Less?

If the rules for .shake and .shake:hover were written like in the below snippet then your current code should work as-is.
.inherit-shake {.shake;}
.shake{
a:a;
&:hover{b:b;}
}
However, I think they are written like below and that is the reason why the :hover rules don't get applied to .inherit-shape selector.
.inherit-shake {.shake;}
.shake{a:a;}
.shake:hover{b:b;}
The best solution would be to use the model mentioned in the first snippet. However, if you can't change the source mixin's for whatever reason then the best would be to make use of extend function with all keyword like in the below snippet:
.inherit-shake {&:extend(.shake all);}
.shake{a:a;}
.shake:hover{b:b;}
The all keyword within extend function would make sure that .inherit-shake:hover gets the same properties as applicable for .shake:hover. The compiled CSS output would be like below:
.shake, .inherit-shake {a: a;}
.shake:hover, .inherit-shake:hover {b: b;}
Added advantage of using extend function is that it would automatically group selectors (like in the output shown above).

Related

How to use :host-context selector in an ngClass condition?

I want to set a class active on a div (part of a component) if a variable is true (workspace.active here) AND an ancestor element has class .home.
Something like:
<div [ngClass]="{'active': workspace.active && ':host-context(.home)', }">
Can I use somehow this pseudo selector :host-context in such an conditional expression for ngClass ?
Details:
I want to use same component in two use cases. Only some css properties should be different on the two cases. So I want to customize a css class set on a div on my component based on decision: "there is an ancestor home in the dom tree or not" - this should differentiate the two use cases.
I could do things like this in css:
:host-context(.home) .active {
background-color: #405976;
}
but then all selector combinations containing .active class should be combined also with :host-context and I I don't want to grow the complexity in css as it is already complex.
I would prefer to just set the class .active based on the condition. In css file !, not in code. (This is why :host-context exists in the end.)
In angular you should not make any logical decisions in the code based on the html content properties such as classes or attributes, but vice versa - you should render classes and attributes in html based on data bindings. That's the main idea of angular - rendering view based on data bindings. Component's code should not really care too much about view structure.
So, in this case if your class should be based on some external information you need to #Import() that data through data bindings into your component and then use component properties in the ngClass directive. Yes, it moves logic into the component instead of html/css, but that's where it's supposed to be anyway: in the model/controller code, not in the view markup. Also, this way it will be much more convenient to test such a component.

Remove some base class CSS on hover

I have 2 icons - a filled thumbs-down (reject) and an unfilled thumbs-up (approve). I need to have both a thumbs up and down image which fills in on hover.
I am trying to use FontAwesome's flip CSS to achieve this. The icons themselves are from an iconfont generated using ico-moon and relate to classes .icon-approve and .icon-reject.
.icon-approve-hover-fill {
#extend .icon-approve;
}
.icon-approve-hover-fill:hover {
#extend .icon-reject;
#extend .fa-flip-vertical;
}
.icon-reject-hover-fill {
#extend .icon-approve;
#extend .fa-flip-vertical;
}
.icon-reject-hover-fill:hover {
#extend .icon-reject;
}
My issue is that for the reject-hover-fill case that the .icon-reject-hover-fill:hover is still flipping due to the .fa-flip-vertical; in the .icon-reject-hover-fill base class.
I need .icon-reject-hover-fill:hover to effectively be it's own class and not inherit the useless extra flip from .icon-reject-hover-fill. I assume there's a way to achieve this without me needing to re-create my font with flipped icons? I need it to work down to IE 8 and can be either basic CSS or SASS (though it needs to work with Sencha's flavour of SASS in ExtJS 6).
The .icon-reject-hover-fill:hover selector is stronger than .icon-reject-hover-fill. If .icon-reject-hover-fill has CSS properties you don't want when the element is hovered, just specify the desired value inside .icon-reject-hover-fill:hover{}, in your custom CSS.
However, instead of adding a class that has properties you want to unset, just create another class, of your own, that contains only the stuff you want from the class you are importing. Trying to unset properties that have been set is the fastest path to CSS mess-up, quickly escalating into code that is almost impossible to maintain.
The usual way to reset an already set property in CSS is {property-name: initial;}. Please note that not all CSS properties can take initial as value.

Using BEM CSS with Angular Directives

I've been using BEM style CSS to style my angular directives and usually use replace: true to so that my Block level class can be on the "root" of the custom element. This makes it so that I can write all my CSS primarily with classes.
However, replace: true sometimes causes issues (having two ng-if, etc...) and is now marked as deprecated. So I'm starting to try to stay away from replace completely.
But now I'm having trouble applying BEM to these elements that have an actual custom tag the DOM -- now I have to use a tag name instead of a class name, which means I can't really use BEM anymore (since I'll have to use the tag name since I can't apply classes directly to my element in my template). Additionally, using modifiers on my custom element now seems impossible, as does using sibling CSS selectors.
Here's an example that hopefully will illustrate what I mean:
The directive:
angular.module('my.module')
.directive('customElement', function() {
return {
restrict: 'E',
scope: {
isSpecial: '='
},
template: '<div class="custom-element" ng-class="{\'custom-element--special\': isSpecial"></div>'
};
});
The CSS:
.custom-element {
background-color: white;
}
.custom-element--special {
background-color: red;
}
.custom-element--special + .custom-element--special { // this won't work without replace: true
background-color: blue;
}
If I use replace: true everything works as expected (but then it comes with its own headaches).
If I don't use replace, the classes are not applied to the root custom element so the child selector doesn't work.
I could always add classes to the element in the postLink function, but that makes the template much less clear.
Does anyone have any experience using BEM with angular and using classes instead of tag names in your custom directives? What did you do to solve this problem?
i known it's a problem having replace:false for readability purpose.
The actual problem is that we need our OOCSS but you are handling Angular Components with custom tags has CSS Objects, and is not the case.
There is no practical solution for this, i won't recommend you to start adding classes on postLink function.
However what we are use to do is treat the custom tag as is own CSS Object besides the inner object structure. Forcing us to implement an extra CSS class for the custom tag.
block-context
block-context__element
custom-element
Why doing this when block-context__element is a redundant' class?
Because the rest of your BEM structure is the one you will maintain, the custom-element block should have meaning by it self and the block-context__element element is no expected to, you should abstract the CSS Objects from the directive's implementation, if you in some point start changing your html components your classes should still apply.
I hope this answer helps you

React on DOM changes caused by Data Binding in Polymer

while exploring the pure awesomeness of Polymer and Dart I struggle to get some things animated right after they get inserted to the DOM by Data Binding.
Example:
<template repeat="{{item in items}}">
<my-item item="{{item}}"></my-item>
</template>
Everytime a new item is inserted or an old one is removed I would like to animate these changes.
Currently I am doing something like this, which works but isn't really nice:
<style>
[item] { transition: 300ms ease-in-out; transform: translateX(0); ]
[require-start-animation] { transform: translateX(-100%); }
</style>
<template repeat="{{item in items}}">
<my-item item="{{item}}" require-start-animation></my-item>
</template>
and before removing it, I add 'require-end-animation' to the elements which will be removed.
The solution works but isn't really that great since I have to keep track of a lot of stuff such as adding the correct attributes at the correct time and removing it. React to transition ending and so on.
Thus I am asking you, is there a cleaner way to react on changes to the DOM which are caused by Data Binding?
You could create a mixin which overrides attached and detached and does the attribute setting/removal before forwarding the call to super (the element itself) and then apply this mixin on elements you want to animate.
I haven't used mixins a lot myself yet. If mixins don't work well for this you could create an implementation in a normal class and then forward the calls to attached and detached to this implementation.
It could also work to create a wrapper element that just wraps the element you want to animate and implements the animation on attach/detach.

Using css in svg

I'm trying to figure out how to make svgs without giving every element a style attribute.
Two problems:
When referencing an external css file, the style appears correctly in a browser, but not in an image viewer. Is this normal/avoidable?
Most of my elements have class and id attributes, and the following css doesnt provide the desired effect, i.e., county 21015 doesnt have its fill overridden
.county
{
font-size:12px;
fill:#d0d0d0;
fill-rule:nonzero;
stroke:#000000;
stroke-opacity:1;
stroke-width:0.1;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-linecap:butt;
marker-start:none;
stroke-linejoin:bevel;
}
path#21015
{
fill:red;
}
If the fill isn't the one you want then there probably is something with higher specificity overriding the stylerule you want, such as an inline style attribute on that element, or some other rule affecting that element. You can also admit defeat by writing "fill: red !important" - that will work in the majority of cases.
Anyway, this is more of a css question than an svg question.
This is an alternative syntax...
Within the definition tags..
.fil0 {fill:#96989A}
Within the path tag(s) class="fil0"
Direct class references from the path to the definitions will override all others in my experience.

Resources