"span" elements created by Angular

7,585 views
Skip to first unread message

wingy

unread,
Aug 17, 2012, 6:19:47 PM8/17/12
to ang...@googlegroups.com
I am writing own directives and I have noticed that Angular creates "span" elements in the DOM for my directives:


Have a look at the DOM for those "li" elements.

There are <span class="ng-scope"></span> as siblings.

Why does Angular creates these spans?

They interfere with my code.

Is there a way to remove them?

Wingy

Michael Bielski

unread,
Aug 17, 2012, 6:41:04 PM8/17/12
to ang...@googlegroups.com
While they could be viewed as an annoyance, if having empty spans with that class is interfering with your code then you are probably doing something incorrectly elsewhere. Empty spans should not be messing things up in your HTML as they do not display anything or figure into the layout at all. I believe that this is part of how Angular defines scope, but I could be wrong.

If it's messing up your CSS, filter it out. jQuery can filter them out quite easily with .not(".ng-scope").

wingy

unread,
Aug 25, 2012, 10:53:46 PM8/25/12
to ang...@googlegroups.com
They disturb the layout in my view.

When removing them I get back the normal layout.

All I did was doing:

<ng-switch on="filter.type">
  <text ng-switch-when="Text"></text>
  <range-slider ng-switch-when="Number"></range-slider>
</ng-switch>

And it created a an empty scope span that pushes everything to the right.

Have no clue how to solve this.

Wingy

wingy

unread,
Aug 25, 2012, 11:03:34 PM8/25/12
to ang...@googlegroups.com
I realized that it is ng-transclude in my directive templates that create these scopes.

I used a compile function instead and no empty scope span is created.

This feels like a bad thing happening breaking the layout.

Only forces people to use the compile function instead.

Wingy

Michael Bielski

unread,
Aug 27, 2012, 11:16:53 AM8/27/12
to ang...@googlegroups.com
I don't use compile and have no troubles whatsoever with the empty span tags. The tag itself has no width or height until it has content between the start and end tag, or until style is applied to it (and even then it needs at least an &nbsp; for content.) Examine your page using the Chrome developer tools (or Firebug if you prefer) and select one of those empty tags. If there are ANY style rules applied to it they came from styling that a human created and not from the element itself.

Martin Landälv

unread,
Sep 2, 2012, 3:05:44 AM9/2/12
to ang...@googlegroups.com
I agree with the OP. Angular shouldn't inject those span tags. They might not (but do in this case?) change the appearance, but it's still not valid html to have span tags under ul. Whats the reason for Angular doing this? I've seen quite a few issues reported related to these span tags.

(One could argue that you've already given up valid html documents if you use Angular, but that doesn't justify Angular breaking it even more :).)

Ramón Antonio Parada

unread,
Sep 2, 2012, 5:23:42 AM9/2/12
to ang...@googlegroups.com
This makes me to rethink switching to angular. I do many HTML editing tools and no code should be ever injected.
By now I have to migration to AngularJS to consider this issue.

:(

Pawel Kozlowski

unread,
Sep 2, 2012, 5:33:02 AM9/2/12
to ang...@googlegroups.com
Ramon,

On Sun, Sep 2, 2012 at 11:23 AM, Ramón Antonio Parada
<ramonant...@gmail.com> wrote:
> This makes me to rethink switching to angular. I do many HTML editing tools
> and no code should be ever injected.
> By now I have to migration to AngularJS to consider this issue.

Don't jump to conclusions too fast. I would suggest looking into a
series of Paul Hammant blogs where he goes into the details of using
AngularJS with different design tools. What I can gather from the blog
is that AngularJS is as designer-friendly as possible, but I will let
you form your own opinion:

http://paulhammant.com/2012/02/01/angular-and-dreamweaver/
http://paulhammant.com/2012/02/13/client-side-mvc-frameworks-compared/

and many others: http://paulhammant.com/archive/

Happy reading!

Cheers,
Pawel

Amit Mendapara

unread,
Sep 3, 2012, 1:11:18 AM9/3/12
to ang...@googlegroups.com
Hi,

The empty spans are created for text nodes to handle string interpolation. It seems that angular doesn't check whether the text is empty or plain string and always creates a span tag for a text node. It's already reported https://github.com/angular/angular.js/issues/1059

I suggested a workaround to skip empty text nodes but it should also cover plain text nodes.

--
Amit Mendapara

Michael Bielski

unread,
Sep 4, 2012, 1:29:24 PM9/4/12
to ang...@googlegroups.com
Empty span tags are NOT invalid html, and from what I have seen the placement of them isn't violating any standards. If it is for you, maybe you should re-examine where you are having angular attach the controller (as that is what I believe causes the tags to appear.) Pawel has some good points in taking the time to read those blogs. Check them out.

robf

unread,
Sep 11, 2012, 11:33:59 AM9/11/12
to ang...@googlegroups.com
I'm having a problem with the span being added when I want to use transclude in my directives when inserting rows and columns into html tables.

      <my-datalist>
        <my-datalist-item ng-repeat="x in [1,2,3,4,5]"></my-datalist-item>
      </my-datalist>

Any ideas on how I could fix this? Should I just use $compile directly instead of transclude/ng-transclude?

Thanks!

Martin Landälv

unread,
Sep 26, 2012, 12:56:16 AM9/26/12
to ang...@googlegroups.com
"Element span not allowed as child of element ul in this context."

Using the experimental HTML 5 validator at http://validator.w3.org.

Michael Bielski

unread,
Sep 26, 2012, 11:04:11 AM9/26/12
to ang...@googlegroups.com
The word "experimental" totally disqualifies any result you may get from that validator. Also, since HTML5 is still not a standard, things are liable to change. When it hits the recommendation phase, then the validators will be something to pay attention to.

Having said those things, the placement of those tags by Angular will need to be reviewed once HTML5 hits the recommendation phase. If Angular is placing them in illegal spots, that will need to be changed. Between the </li> and the next <li> isn't even valid HTML 4, let alone HTML5, and if they are being placed there then that should be changed. However, my original point to the OP still stands: a set of empty span tags (in and of themselves) are not invalid HTML and if they are messing up your page you are doing something to them in your CSS. Look to your CSS for answers, not Angular.

lorenzofox3

unread,
Sep 26, 2012, 11:40:45 AM9/26/12
to ang...@googlegroups.com
Hi all,
As mentioned before you can write your own transclusion in the compile function if you want to avoid such behavior. 
I found this video quite helpful.
Cheers,
Laurent

mpodr...@gmail.com

unread,
Dec 17, 2012, 8:09:29 AM12/17/12
to ang...@googlegroups.com, johnn...@yobistore.com
Removing all white spaces in my template fixes the problem with <span class="ng-scope"></span>  somehow...but its realy annoying... :-(

dlo...@googlemail.com

unread,
Jan 4, 2013, 7:27:05 AM1/4/13
to ang...@googlegroups.com, johnn...@yobistore.com
I'm not sure if it is a "bug/unwanted behaviour", but I get these span-elements on line-end-characters too while using ng-include for example. If I include something like that:
---
<div style="display:inline-block; width:50%">...</div>
<div style=" display:inline-block; width:50%">...</div>
---
then angularjs compile this too something like this:
--
<div style="display:inline-block; width:50%">...</div><span class="ng-scope">
</span><div style=" display:inline-block; width:50%">...</div><span class="ng-scope">
</span>
-- 

It's important to realise the single line-end-character ("\n" unix) inside these span-elements. I can only prevent them when removing anything outside these div-elements in that included file.

In the most situations these useless span-elements are no problem. But in my short example the second div would displayed below and not(!) beside that first div as the CSS describes, because the span-element gets a width (~10px).

Moreover I think that generating this _unused_ span-elements could be generated in mass in some situations, for example in any bigger included template. (only in the root level of course) The existing issue 1059 describes this only with empty span-elements. Should I report this there?

Pawel Kozlowski

unread,
Jan 4, 2013, 9:10:54 AM1/4/13
to ang...@googlegroups.com
Hi!

On Fri, Jan 4, 2013 at 1:27 PM, <dlo...@googlemail.com> wrote:
> Moreover I think that generating this _unused_ span-elements could be
> generated in mass in some situations, for example in any bigger included
> template. (only in the root level of course) The existing issue 1059
> describes this only with empty span-elements. Should I report this there?

Those span elements indicate places where a new scope is created and
are essential for tools like
http://blog.angularjs.org/2012/07/introducing-angularjs-batarang.html

Are you facing practical problems with those spans? Or is it just a
general concern?

Cheers,
Pawel

--
Question? Send a fiddle
(http://jsfiddle.net/pkozlowski_opensource/Q2NpJ/) or a plunk
(http://plnkr.co/)
Need help with jsFiddle? Check this:
http://pkozlowskios.wordpress.com/2012/08/12/using-jsfiddle-with-angularjs/

Looking for UI widget library for AngularJS? Here you go:
http://angular-ui.github.com/

dlo...@googlemail.com

unread,
Jan 4, 2013, 9:54:49 AM1/4/13
to ang...@googlegroups.com
No practical problem which can't be solved in any other way. Till now :-P

But I didn't understand the point "indicate places where a new scope is created", because these span are repeatedly created at the root level of a scope and not once at the beginning to "indicate" this. Further when they had no really affect on the "visual DOM", then they can get "display:none"-style, don't they?

Btw. I love angular, because I'm facing less practical problems than ever before when designing dynamic pages. :)

dlo...@googlemail.com

unread,
Jan 4, 2013, 12:37:43 PM1/4/13
to ang...@googlegroups.com
I took my cape and tried Batarang. ^^

There I can see the cascade of scopes as it should be. Maybe its only my curiosity, but I don't understand the need, when everything works similar with or without these extra-elements - in the browser and in Batarang. It makes no difference if i remove the end-line and whitespace characters to prevent that they are generated. Don't get me wrong, I can prevent any interaction with other inline-elements, because I know about them. This is not intuitiv. ... But in german I would say this is also "Nitpicking". :)

Greets..

(Excuse my curiosity and this bumpy english :)



Am Freitag, 4. Januar 2013 15:10:54 UTC+1 schrieb Pawel Kozlowski:

Jacob Smith

unread,
Jan 4, 2013, 3:19:25 PM1/4/13
to ang...@googlegroups.com
These span tags are causing a real problem.

I just lost several hours trying to figure out why [class*="column"] + [class*="column"]:last-child was not being applied to the last sibling of <div class="columns">. It is because these damn span tags are somehow causing browsers to consider them .column siblings (so the span Angular inserts after my last div.column is treated as the last-child), and it's breaking the hell out of my layout.

I'm using Foundation 3.2 btw.

Anyone know how I configure Angular to knock this crap off? I'm about to just write some vanilla script to remove them from the DOM.

Michael Bielski

unread,
Jan 4, 2013, 3:29:49 PM1/4/13
to ang...@googlegroups.com
I have a feeling that if you do that you'll lose all of your scopes, but good luck with it.

Jacob Smith

unread,
Jan 4, 2013, 4:35:04 PM1/4/13
to ang...@googlegroups.com
It's not what I would prefer to do; and if that is the case, I'll have to go with another MVC framework.

Joshua Miller

unread,
Jan 4, 2013, 4:54:19 PM1/4/13
to angular
Hello!

Can someone post an example on jsFiddle or Plunker where the spans are interfering?

Josh


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
 
 

Jacob Smith

unread,
Jan 4, 2013, 5:41:29 PM1/4/13
to ang...@googlegroups.com

Jacob Smith

unread,
Jan 4, 2013, 5:43:41 PM1/4/13
to ang...@googlegroups.com
And here is the exact same thing without using Angular: http://jsfiddle.net/jshado1/F5VdG/1/


On Friday, January 4, 2013 1:54:19 PM UTC-8, Joshua Miller wrote:

Joshua Miller

unread,
Jan 4, 2013, 6:02:12 PM1/4/13
to angular
Hi Jacob!

Instead of using the CSS `:last-child` pseudo-class, you could use the `:last-of-type` pseudo-class to check only the elements and classes you want (e.g. not span.ng-scope). http://jsfiddle.net/joshdmiller/F5VdG/3/

Josh


--

Jacob Smith

unread,
Jan 4, 2013, 6:08:18 PM1/4/13
to ang...@googlegroups.com
Hi Josh,

Thanks for the idea, but then you have you specify a tag (potentially a lot of tags and won't adapt if new html tags are created in the future).

Kevin James

unread,
Jan 4, 2013, 8:11:07 PM1/4/13
to ang...@googlegroups.com
Jacob,
a simple workaround is to wrap your template with another element >> Angular spans. This isn't always necessary (so I believe, anyways) but in your case it works.

Here's a nice little bit from the angular-1.0.3.js source (yeah, I read it) ::

// We can not compile top level text elements since text nodes can be merged and we will
// not be able to attach scope data to them, so we will wrap them in <span>
forEach($compileNodes, function(node, index){
  if (node.nodeType == 3 /* text node */) {
    $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
  }
});

Knowing when this happens can be tremendously useful.. In your case, $compileNodes are [article, div, div] with text nodes sprinkled around/between. Wrapping them in the template with another element takes care of that.

-Kevin James

Jacob Smith

unread,
Jan 5, 2013, 12:56:52 AM1/5/13
to ang...@googlegroups.com
Yep! That did it: http://jsfiddle.net/jshado1/F5VdG/4/

Thanks!
P.S. The spans are still annoying haha

Caleb Olin

unread,
Feb 7, 2013, 5:06:44 PM2/7/13
to ang...@googlegroups.com, johnn...@yobistore.com
The extra span tags can break layout when using the CSS table model. Fiddle: http://jsfiddle.net/Cp9eQ/

Jochen Szostek

unread,
Feb 25, 2013, 9:40:54 AM2/25/13
to ang...@googlegroups.com
Hi all,

I think I've also found a situation where the span's are blocking functionality:
http://jsfiddle.net/A969Z/131/

Can't see the textarea contents with the span wrapped around the content.
Perhaps any known work-arounds?

Thanks! 

Op vrijdag 4 januari 2013 22:54:19 UTC+1 schreef Joshua Miller het volgende:

Peter Bacon Darwin

unread,
Feb 25, 2013, 10:07:00 AM2/25/13
to ang...@googlegroups.com


To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jochen Szostek

unread,
Feb 27, 2013, 4:03:51 PM2/27/13
to ang...@googlegroups.com
Awesome! Thanks a lot for your feedback. Learned some new cool tricks from it. :)

Peter Bacon Darwin

unread,
Feb 27, 2013, 4:18:47 PM2/27/13
to ang...@googlegroups.com
You're welcome!

Andreas Heintze

unread,
Sep 9, 2013, 7:31:50 PM9/9/13
to ang...@googlegroups.com
This really annoys me!
While that may work, it's the wrong way to do it. You should not manipulate the DOM inside a controller, it should be done in the compile function.
So what is the correct solution? 

gulfraz ahmed

unread,
Oct 5, 2013, 2:47:52 PM10/5/13
to ang...@googlegroups.com, johnn...@yobistore.com
Hi, 
I have also used wordpress angular theme for my portfolio site www.websapper.com.
Just made a css hack to display none to the div containg text "Welcome! This is Angular, a very clean & super flexible WordPress portfolio theme that makes it easy to showcase your work".

css is:
.outer_callout{
    display: none;
}

Thanks

Gulfraz Ahmed

Noel da Costa

unread,
Jan 22, 2014, 10:55:41 AM1/22/14
to ang...@googlegroups.com, johnn...@yobistore.com
If you are binding models to inputs that are included via a template, then you end up with these spans inside your input fields, which will not only break any type of CMS functionality but will also be visible to your users as HTML when all they expect to see are values.

Michael Bielski says filter them out with .not(".ng-scope") but if you do this you also filter out their content, so that won't help you if you are trying to get to their content.

In my view this is a major problem. A javascript framework inserting name-spaced attributes to existing HTML is one thing, taking away your control over your HTML is quite another... that makes it disabling rather than enabling for the developer and reminds me of my (shudder) Dreamweaver days. I personally think this is an unjustifiable design flaw.


Reply all
Reply to author
Forward
0 new messages