apply css animation to specific html element using angularjs - css

please check first the demo on plnkr.
My problem is: this animation will be applied to all elements in html,
cause in css is defined .ng-enter .ng-leave etc.
I am trying to apply it to a specific class name. In my case, it's <li class="specific">
And in CSS I've tried following:
.specific.ng-enter /*(does not work)*/
.specific-ng-enter /*(does not work)*/
With these code above, I can add and remove items but without animation.
How should the code be in css ?

Actually, there are a couple of possible issues with the code:
You are using ngRepeat on your <ul> (I cannot be 100% sure that this is not what you want but it is highly improbable). ngRepeat will "repeat" (clone" the element it is on, so in your case you are creating multiple <ul> elements (instead of multiple <li> elements, as one would expect).
Moving ngRepeat o the <li> will solve the animation problem and result in the intended HTML code (1 <ul>, multiple <li>).
Your CSS defined transition with every class, while it would suffice to define one rule:
.top.ng-enter, .top.ng-leave {
// ...define transitions here
}
In order to avoid possible CSS specificity issues (especially later on, when your CSS grows in size and complexity), you should include the .ng-enter/leave class selector in the rules with .ng-*-active:
// Instead of just:
.top.ng-enter-active {...
// You should use:
.top.ng-enter.enter-active {...
Finally, you can group identical rules together, to save space and make your code more DRY (e.g. .top.ng-enter rule === .top.ngleave.ng-leave-active rule).
Your final code should look like this:
<!-- HTML -->
<ul>
<li class="top" ng-repeat="item in items">{{item}}</li>
</ul>
/* CSS */
.top.ng-enter,
.top.ng-leave {
-webkit-transition: 1s;
transition: 1s;
}
.top.ng-enter,
.top.ng-leave.ng-leave-active {
margin-left: 100%;
}
.top.ng-enter.ng-enter-active,
.top.ng-leave {
margin-left: 0;
}
See, also, this short demo.

Just give class to your <ul> like this.
<ul class="my-anim" ng-repeat="item in items">
<li class="top">{{item}}</li>
</ul>
Working Demo

Related

Is it possible to create a CSS selector like `parent[data-selected="$val1"] > child[data-id="$val1"]`?

I have the following HTML.
<ul data-selected="foo">
<li data-id="foo">text</li>
<li data-id="bar">text</li>
<li data-id="baz">text</li>
</ul>
And the following CSS.
ul[data-selected="foo"] li[data-id="foo"],
ul[data-selected="bar"] li[data-id="bar"],
ul[data-selected="baz"] li[data-id="baz"]
{
color: red;
}
foo in this example is an infinite number of dynamic values.
Is it possible to reduce this to one pure CSS selector (without JS continuously rewriting it)?
Something like:
ul[data-selected="$val1"] li[data-id="$val1"]
It's for a closed system so experimental CSS is fine.

Select the first element of a class, but not its children

I'm working on a navigation bar. One of my navigation items has a dropdown. For this item, I want to disable the normal link behavior (I have already done this with jQuery) and just have it open a dropdown with three functioning links on hover.
All of this is working functionally, but I have some trouble with the styling.
Note that I'm using a CMS that automatically generates the navigation, so I can't use an id to target the relevant menu item.
My menu looks like this:
<ul class="header-navigation-list">
<li class="header-navigation-list-item">
<a class="header-navigation-link primary-link" href="...">Home</a>
</li>
<li class="header-navigation-list-item">
<a class="header-navigation-link primary-link" href="...">About</a>
</li>
<li class="header-navigation-list-item has-dropdown">
<a class="header-navigation-link primary-link" href="...">Products</a>
<ul class="header-navigation-list secondary-list" data-is-dropdown>
<li class="header-navigation-list-item secondary-list-item">
<a class="header-navigation-link secondary-link" href="...">Product #1</a>
</li>
<li class="header-navigation-list-item secondary-list-item">
<a class="header-navigation-link secondary-link" href="...">Product #2</a>
</li>
<li class="header-navigation-list-item secondary-list-item">
<a class="header-navigation-link secondary-link" href="...">Product #3</a>
</li>
</ul>
</li>
<li class="header-navigation-list-item">
<a class="header-navigation-link primary-link" href="...">Blog</a>
</li>
<li class="header-navigation-list-item">
<a class="header-navigation-link primary-link" href="...">Contact</a>
</li>
</ul>
The goal is to remove all link-styling from "Products", but keep the link styling for "Products #1 - #3".
I tried targeting it via several CSS rules like .header-navigation-list > .has-dropdown or .header-navigation-list > .has-dropdown:first-of-type or .header-navigation-list > .has-dropdown a:first-child. The problem is that every time I manage to target the "Products" point, I also target all the elements it contains and disable the link-styling for "Product #1 - #3" too.
The second example below might be what you're looking for (jsfiddle: https://jsfiddle.net/pk8gsh9z/):
/**
* Example 1
*
* Targets the direct links of top-most LIs when all of the following are true:
* - they have a "has-dropdown" class.
* - they don't have a "secondary-list-item" class.
*/
.header-navigation-list .has-dropdown:not(.secondary-list-item) > a {
color: brown;
text-transform: uppercase;
}
/**
* Example 2
*
* Targets the direct links of the third LI when all of the following are true:
* - it has the "has-dropdown" class
* - and it doesn't have "secondary-list-item" class
*/
.header-navigation-list .has-dropdown:not(.secondary-list-item):nth-child(3) > a {
color: green;
}
General recommendation
A general thumbrule when writing CSS selectors is to keep the amount of rules at a resonable level for several reasons:
Readability: one should be able to understand what the class does by reading its name
Unified language between team members. Everybody knows what to expect from a class.
Maintainable code: your selectors do not unexpectadly break the website at an unknown place .
A good way to do this is by using the BEM naming convention
Your case
However, since you do not seem to be in the position to decide what classes or ids you use, you have to work with what you have.
This solution is very general:
.has-dropdown > .primary-link{
/*Reset styles goes here*/
}
It selects all elments where the direct children of .has-dropdown is the .primary-link class. For more information see Mozillas documentation on relationship selectors.
More specific CSS selectors
One example using the :nth-child selector could be:
.header-navigation-list > .has-dropdown:nth-child(3) > .primary-link{
/*CSS rules*/
}
THIS IS HOWEVER BAD PRACTICE due to readability problems.
Short summary
Whenever possible, choose your own classes, preferably according to a naming convention. If working with a CMS you might want to edit any theme files, but unless you plan to provide support for a long time, I would not recommend it.
Try to fully understand how to use CSS selectors and pseudo-selectors, to know what elements the styles will be applied to.
Workaround CMS Styles by Class
Isolate and identify targets. Primary are last in line. Secondary are Primary's ancestors (i.e. parents, parent's parent (grandma), etc.)
Primary Targets
Product #1 to #3: li.header-navigation-list-item.secondary-list-item
Secondary Targets
Products: li.header-navigation-list-item.has-dropdown (Grandma)
[Secondary List]: ul.header-navigation-list.secondary-list(Mom)
Determine what classes they all have in common. Find out what the style properties they have. These classes are untouchable because they are universally shared with every <ul> and <li>.
All <ul> have .header-navigation-list
ul.header-navigation-list {background: black; color: yellow;}✱
All <li> have .header-navigation-list-item
li.header-navigation-list-item no assignment it inherits instead ✱
✱ I have no idea what the styles are I arbitrarily assigned them.
Determine unique classes or secondary classes that are not shared with every <ul> or <li>
Primary Targets
Product #1 to #3: .secondary-list-item
Secondary Targets
Products: .has-dropdown
[Secondary List]: .secondary-list
That looks like 3 hooks all ready.
Given that we have no idea what the real situation is like the surrounding layout, all of the stylesheets, plugins, etc. Remember, navigation list layouts almost always have each anchor as an only child with the exception of a dropdown anchor (i.e. li.has-dropdown > a.primary-link), so it's easier to target the <li> first then step down to the anchor's level. Because inheritance, you should always style ancestors first then specifically style the children to override inherited styles. The possible selectors could be:
li.has-dropdown > a.primary-link { color:red; font-size:48px; }
li.has-dropdown > ul > li > a { color: yellow; font-size:48px; }
If you still have problems, go back to step 2 and counter-style those universal classes:
If you find this:
ul.header-navigation-list {background: black; color: yellow;}
Counter style it:
ul.header-navigation-list.secondary-list {background:none; color:transparent; }
li.header-navigation-list-item.secondary-list-item > a { background: white; color:blue; }

SCSS/CSS Using :not selector for only certain elements

I have a common element which contains articles, and want to treat all but the first child differently as follows:
.listing{
article{
// Some styles
}
article:not(:first-child){
// Some more styles
}
}
All well and good. However on some listings they should all be treated the same, so I don't want to include the article:not(:first-child) selector, it needs to be like the following:
.listing.alt{
article{
// Some styles
// Some more styles
}
}
How can I combine these two rules without repeating everything?
Ok I think I've figured it out using Sass:
.listing{
article{
// Generic Styles
}
&.alt article,
&:not(.alt) article:not(:first-child){
// More Styles
}
}
I also see that my original code example was a bit weird so I've updated it so it's a bit more correct.
HTML
<div class="listing">
<article>1</article>
<article>2</article>
<article>3</article>
</div>
<div class="listing alt">
<article>1</article>
<article>2</article>
<article>3</article>
</div>
CSS
.listing:not(.alt) article:not(:first-child) {color:gainsboro;}
Updated demo

CSS selector based on a:target

This is my HTML:
<p class="define"><a class="term" href="#jump" name="jump">jump</a> - Some description</p>
When the browser jumps to #jump I want to highlight the .define class. If I do;
a.term:target { background-color: #ffa; -webkit-transition: all 1s linear; }
I of course only highlight the a. How do I modify this to complete p? I tried a couple of variants like the one below, but none of them work.
a.term:target .define { stuff here }
a.term:target p.define { stuff here }
a.term:target p { stuff here }
jsFiddle: http://jsfiddle.net/vVPPy/
You can't modify the parent of an element using css. You will have to use a javascript alternative.
You will not be able to determine where the user is on the page using CSS. This can be accomplished with JavaScript - If you're not trying to reinvent the wheel, I'd recommend using Bootstrap's ScrollSpy.
Your <p> tag isn't the target of anything. If it were:
<p class="define" id="something">
<a class="term" href="#something" name="jump">jump</a> - blah
</p>
You could style it like so:
a.term:target { background-color: #ffa; }
but that has nothing to do with the <a> actually being clicked on. You'll need to use an onclick handler for that, ideally adding a class to the target and styling based on that class.

Dynamic CSS with a variable parameter? (is it possible?)

I'm trying to create a menu system, which is dynamically resizes itself horizontally to fill out depending on how many "li" entries there are, I'm dynamically creating the webpages with XSLT. My thoughts are whether this is possible todo within CSS?
Here's my CSS specifically for the HTML page
nav[role="navigation"] li {
float: left;
width: 10.00%; /* I want to dynamically set this width */
}
Snippet of HTML in question
<nav role="navigation" count="2"><?xml version="1.0" encoding="utf-8"?>
<ul>
<li>
Movies
</li>
<li>
News
</li>
<ul>
</nav>
My thoughts are of whether something like this would be possible to call the CSS with a parameter, or am I going against it's declarative ways?;
nav[role="navigation"] li param {
float: left;
switch(param)
{
case : 5
{
width: 20.00%;
}
case : 3
{
width: 33.33333%;
}
}
}
CSS is not a programming language. CSS3 has a bit of logic here or there, but no switch().
For your purposes, the simplest solution by far is a touch of javascript, supplied here assuming that you use jQuery:
var $navLis = $('nav[role=navigation] > ul > *');
$navLis.addClass('count'+$navLis.length); // add a class to every li indicating
// total number of list items
Then in your CSS:
nav[role=navigation] li { /* default styling & width */ }
nav[role=navigation] li.count2 { /* your conditional styling */ }
nav[role=navigation] li.count5 { /* your conditional styling */ }
/* etc */
or just set the width directly with jQuery:
$navLis.style('width', (100/$navLis.length)+'%');
If you demand pure CSS, then get out your logic hat and look over the CSS3 selectors specification. You can construct some Byzantine and rather brittle CSS code to fake logic, such as the following selector.
nav[role=navigation] li:first-child + nav[role=navigation] li:last-child {
/* matches last of two items if a list has only two items */
}
If you're using a CMS that knows how many items it is going to be putting in the list, then you can get fancy on your server backend by adding little bits of PHP to your CSS:
<?php header('Content-type: text/css');
if (isset($_GET['navcount']) && $_GET['navcount'] != "") {
$navcount = $_GET['navcount'];
} else { $navcount = 5.0; } // Default value
?>
/* ... your css code here... */
nav[role="navigation"] li {
float: left;
width: <?php echo (100.0/$navcount); ?>%;
}
Then you request the CSS/PHP script like this from your HTML:
<link rel="stylesheet" type="text/css" href="/path/to/style.php?navcount=5" />
There's a few great tools out there for writing stylesheets that mix down nicely into CSS, and some even provide PHP implementations to do so dynamically. The strongest CSS extension right now is Sass, which has just the sort of syntax that you're looking for. I'd recommend using Sass through Compass, which is a framework for Sass that really gives it some teeth. You can parse Sass into CSS on-the-fly in PHP using phamlp
Although Compass (and Sass) are awesome tools, plugging them into an existing project could be more trouble than its worth. You might just want to do simple logic using Javascript.
have you tried LESS?
LESS extends CSS with dynamic behavior
such as variables, mixins, operations
and functions. LESS runs on both the
client-side (IE 6+, Webkit, Firefox)
and server-side, with Node.js.
It is not possible with simple CSS.
But for this specific example, you might look at the display: table-cell; property.

Resources