How to manipulate styles of directive in AngularJS?

85,343

Solution 1

This should do the trick.

var MyApp = angular.module('MyApp', []);

MyApp.directive('myTag', function() {
    return { 
      link: function(scope, element, attributes){
        element.addClass('MyClass');
      }
    }
});

Solution 2

This is how AngularJS adds core CSS styles:

angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>');

You can find this code in angular.js v1.2.0-rc.2.

EDIT

In a custom directive, I use this solution to bundle CSS stylesheets in the directive:

  var outputColorCSS = {
    selector: 'span.ouput-color',
    rules: [
        'display: inline-block',
        'height: 1em',
        'width: 5em',
        'background: transparent',
        'border: 3px solid black',
        'text-align: center',
        'font-weight: bold',
        'font-size: 0.8em'
    ]
  };
  var outputColorStyleSheet = outputColorCSS.selector + outputColorCSS.rules.join(';');
  angular.element(document).find('head').prepend('<style type="text/css">' + outputColorStyleSheet + '</style>');

Then you can use class="ouput-color" in your directive templates.

I found it very clean and useful.

Solution 3

I'm a little late to the party, but why aren't you all using the built in .css() method?

just use:

link: function(scope, elem, attr, ctrl)
{
    elem.css({'display': 'block', 'height': '100%', 'width': '100%'});

}

or whatever css you desire.

Solution 4

You can put custom styles in a directive's declaration with a parameter, just like you exemplified.

In order to declare a style like that, you have to define a variable to hold the custom styles:

scope: {
    myClass: '@myClass'
  },

And then set that parameter in the directive's template, like this:

<my-tag my-class="CustomClass"></my-tag>

Finally, in the template of the directive itself, reference that class:

<h1 class="{{myClass}}">{{myContent}}</h1>

I made a plunker that shows how you can customize styles in a directive, check it out here .

Solution 5

Plunker

To manipulate the css style through an attribute directive, you could do something like this:

var app = angular.module('colorSwap', []);

app.directive('styleChanger', function() {
  return {
    'scope': false,
    'link': function(scope, element, attrs) {
      var someFunc = function(data)
      {
        /* does some logic */
        return 'background-color:' + data;
      }
      var newStyle = attrs.styleChanger;
      scope.$watch(newStyle, function (style) {
        if (!style) {
          return ;
        }
        attrs.$set('style', someFunc(style));
      });
    }
  };
});

Some html:

<div ng-app="colorSwap">
  <input type="txt" ng-init="colorName= 'yellow'" ng-model="colorName" />
  <div style-changer="colorName">this is the div content</div>
</div>

To make an element directive, change it's own style, something like this:

app.directive('elementWithStyle', function() {
  return {
    'restrict' : 'E',
    'scope': {},
    'controller': function($scope) {
      $scope.someStyle = 'Cyan';
      $scope.someFunc = function() { $scope.someStyle = 'purple' };
    },
    'template': '<div style="background: {{someStyle}}" ng-click="someFunc()"> click me to change colors </div>'
  }
});

And the html:

<div ng-app="colorSwap">
  <element-with-style>123</element-with-style>
</div>

I hope this helps. The rest of the answers cover class manipulation more or less.

Share:
85,343
Roman Dryndik
Author by

Roman Dryndik

Updated on July 27, 2022

Comments

  • Roman Dryndik
    Roman Dryndik almost 2 years

    I'm writing a component using AngularJS and AngularJS directives.

    I'm doing something like this:

    var MyApp = angular.module('MyApp', []);
    
    MyApp.directive('myTag', function() {
        return { /* Some logic here*/ }
    });
    

    I want to be able to change style of my component (using CSS), something like this:

    <my-tag class="MyClass"></my-tag>
    

    Besides this I want to be able to manipulate all elements style inside my component (HTML markup inside of my-tag).

    Do you have any advice or useful examples how to manipulate the style properties of custom tags using AngularJS?

  • Roman Dryndik
    Roman Dryndik over 10 years
    So, I have to put a name of class inside of my directive, right? If so, I think it is not a good solution...
  • Roman Dryndik
    Roman Dryndik over 10 years
    Ok. But the questions is still open - do I need to put the name "MyClass" of my custom class inside the directive declaration? This is not good solution, I try to avoid it. How to do the same, but via some parameter?
  • francisco.preller
    francisco.preller over 10 years
    You can still put the class outside. Directives only replace content if replace: true is declared.
  • Ben
    Ben over 10 years
    perhaps this is what you are after docs.angularjs.org/api/ng.directive:ngStyle
  • Ingó Vals
    Ingó Vals over 9 years
    Could I make a default value if the attribute isn't set?
  • Dunc
    Dunc over 8 years
    Great job, I had to add braces though: ... outputColorCSS.selector + '{' + outputColorCSS.rules.join(';') + '}';
  • Esteve
    Esteve over 8 years
    Just to clarify: this code is plain javascript, must not be placed in your link() function, or a <style> block will be added to <head> on every use of your directive!
  • EdL
    EdL over 8 years
    Where's the link to the plnkr?
  • dmr07
    dmr07 almost 8 years
    Why is this upvoted at all?? The question does not ask how to manipulate class of a directive element.
  • Porlune
    Porlune almost 8 years
    Could you give me some more details and maybe I can help you figure out why it's not working? jQlite is available by default on angular. It includes the .css() function. docs.angularjs.org/api/ng/function/angular.element api.jquery.com/css
  • dmr07
    dmr07 almost 8 years
    It's working now. I had a ng-binding on an inline style of the element. The css I had during the initial linking got overwritten by that later bind. Thanks for the reply.
  • B001ᛦ
    B001ᛦ almost 8 years
    Thanks for your answe. Please edit. A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
  • Bernardo Dal Corno
    Bernardo Dal Corno over 7 years
    that gave me an idea: would it be too bad to put an id on the style tag and check if it already exists??
  • aruno
    aruno about 6 years
    @dmr07 I'm upvoting it to encourage the author to make his question clearer in future - and since this answer worked for me based on his title :-)
  • Soldeplata Saketos
    Soldeplata Saketos almost 6 years
    needs to be $(elem[0]).css({...})
  • Porlune
    Porlune almost 6 years
    @SoldeplataSaketos I think you are mistaken, I just double checked and the "css" method is indeed on elem without having to wrap it in a jquery element. Elem is already a jquery-lite element.