This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.
In pretty much any visual application dealing with multiple objects on the screen, you have to take in to consideration the arrangement of those objects; arrangement here meaning the relations of overlapping these objects have with each other, and when I say objects here, or pretty much anywhere else, I mean visual screen objects or instances such as movieclips, buttons and textfields. While working in Flash, you can control the overlapping through such methods as appropriately arranging layers in your timeline or taking advantage of arrangement options available in the Modify menu such as Send Backward or Bring to Front etc. This can be done with any symbol, text field or group allowing you to manipulate just how they appear on the screen in terms of overlapping - something which can be very important in your movie design.
Arrangement isn't restricted to the Flash authoring environment though. With actionscript you have similar control, being able to have direct control of how objects on the screen overlap by changing their arrangement or depth, as its commonly refereed to, from commands given in your code. In terms of actionscript, however, you only have control over MovieClip objects, Button objects and non-static TextField objects since those are the only screen elements which can be given instance names and therefore be referenced by actionscript. Groups and static text blocks will always remain at whatever depth they were when they were placed and arranged on the timeline (supposing you don't accidentally replace them, but we'll get to that later on).
Before getting into how exactly you adjust and control the depths of such screen instances, its important to understand their relation to Flash and multiple timelines. All movieclips in Flash, as you probably already know, have their own timelines. These timelines are kept separate from other timelines and run independently of those other timelines including the one in which the movieclip (or current timeline) exists. This means that if a movieclip lives within a movieclip who's timeline stops, the original movieclip's timeline would not also stop. Well, not unless explicitly told to.
Along with this kind of movie play separation, you have a separation of visual objects within timelines as well. By this I mean that all objects within any one timeline are kept separate from objects within other timelines. These visual objects themselves are pretty much separate from each other to begin with, though the separation here, as you might have surmised, is in terms of depths. The depths of objects can only be changed in respect to other objects within that same timeline. This applies to both actionscript and when working in the Flash authoring environment. What this means is that if you have two movieclips, clipA and clipB and they each have their own clips within, then those interior clips depths can not be changed or rearranged in relation to each other. The only way to rearrange their depth positioning is if you rearranged clipA's and clipB's depths directly which would then of course rearrange everything within those clips either above or below the other. All of this is from the design of the timelines and their self-containment.
You can think of movieclips and their timelines in this respect as boxes. Lets say you are packing your things up because you're moving to a new home. First you put your shoes in a box, then put that box in a larger box for clothes. Then lets say you pack a box for your many toothbrushes and then stick that box in a larger box for bathroom items. So, when you get to packing the moving van, you stick the clothes box in first and then, on top of that, you put the bathroom box. If for whatever reason or another, if you wanted the shoe box in the lower clothes box to be above the toothbrush box (maybe you have a fear of loose bristles falling into your sandals), then you would have to either a) take the shoe box out of the clothes box and put it on top of the bathroom box, or b) just put the clothes box on top of the bathroom box instead. Since the boxes represent timelines, in Flash, solution (a) won't work since there's no real practical way to change the timeline in which a movie exists - something to be conscious of if you didn't already know it. Solution (b) would have to be the solution to pursue in terms of Flash and relates to the clipA/clipB example above. If for some reason that solution is not suitable, then it may be necessary to rearrange your clips so that they exist within the same timeline and can be properly arranged.
That brings us to what a depth really is to Flash in its internal workings and understanding. What that is, is a number. Depths in Flash are all handled through a simple number which indicates to the Flash player whether a visual object on the screen has a high depth or a low depth - whether its above or below other objects based on their depths. The higher the number, the higher the depth and the more likely that object is going to be above another. The lower the number the lower the depth and the more likely the object is going to be below another. Any object who's depth is greater than another object's depth will overlap that object. The reverse applies if the depth is lower. So, going back to clipA and clipB, if clipA has a depth of 10 and clipB has a depth of 11, then clipB will overlap clipA because clipB's depth is greater. Each object in a timeline has their own depth and no two depths in the same timeline share the same value. This way there is always a known depth relation between all objects in any one timeline at any given time. Basically, the depth of any object is just its stacking order - a number representative of how objects are positioned on the screen.
Flash determines the initial depths of objects by two means, you and you. The first method is through evaluating your layout in Flash authoring - how you arranged your clips and what layers they are in etc. Granted, you aren't given strict control of an actual numerical value here, but that arrangement does reflect the depth given to an object as its rendered in the Flash player. Secondly, if you use any dynamic instance creation methods, such as attachMovie or duplicateMovieClip, Flash will know the depths of those objects because it is required by you to specify those depths when those methods are called.
When Flash determines the depth of objects from the your layout in the Flash authoring environment, it does so for each timeline considering current overlapping arrangement along with layer positioning. Layers, however, are not referenceable through actionscript. For all events and purposes in regards to actionscript, layers are nonexistent in a swf. Where they were and how they were set up is completely oblivious aside from one simple number assigned to each and every instance that existed on those layers. This number, of course, being the individual depths of those instances. Flash in playing the timeline reads each layer and its contents interpreting them to a physical depth position and giving it a depth number based on its position relative to other objects in that timeline. Object instances in higher layers receive higher depths and those in lower layers receive lower depths. What layers were these objects in? We wont know - they're as good as dead to actionscript, but this of little consequence as anything we would need to reference has an instance name (providing one was given) and therefore is accessible to you. As Flash reads the timeline to assign these depths, it works from the lowest objects up, first drawing the lowest objects on the screen with the lowest depths then continues to the higher objects which are positioned on top of that. The starting depth in this procedure (the depth the lowest clip gets) is very low and will be touched upon later.
The functions in Flash which pertain to depth, in some way or another, are:
| Methods | Works on |
| duplicateMovieClip | MovieClip |
| attachMovie | MovieClip |
| createEmptyMovieClip | MovieClip |
| createTextField | MovieClip |
| swapDepths | MovieClip |
| getDepth | MovieClip, Button, TextField |
| removeMovieClip | MovieClip |
| removeTextField | TextField |
The first 4, duplicateMovieClip, attachMovie, createEmptyMovieClip and createTextField involve dynamically creating new instances of screen objects on in a timeline in Flash during runtime. Using these methods requires that a depth be set for the new instance created, thus allowing you to order and arrange your new clips in the timeline as you see fit. If, however, you attempt to create a new object with one of these methods in a depth which is currently occupied by another instance, the new clip will remove that original instance to make room for itself. Because of this, you may need to be careful when specifying which depth you place new instances with these methods or you might lose other movieclips.
Following those is swapDepths which is used to change the depth of an object on the screen. This can be done in two ways, either exchanging the depth of the current clip with the depth of another clip or by specifying a number directly shifting the depth of the current clip to that numeric depth. In this manner swapDepths acts not only as a swapDepths but also a type of setDepth function as well. Unlike the previous methods, however, if you try to set the depth of an object to a depth currently occupied by another object with swapDepths, swapDepths will act less like a depth setter and more like the other form of depth swapper. The new clip will occupy the desired depth, but since depths cannot be the same value, the object at the lower depth is sent back to the depth which the original clip first existed effectively swapping the two depths. SwapDepths can also be used on levels, but only in the swapping sense and only for visual arrangement (in other words, you can't use number values for swapDepths when dealing with _levels, you need another actual level to swap with). What I mean by that is that if you swap level 1 and level 2, even though level 1 may now be on top of level 2, it is still known as _level1 and not _level2. Though, initially, levels are referenced in a manner which may relate to their arrangement, using swapDepths on levels will not change their naming.
The next in the list is getDepth, which, obviously enough, retrieves the depth of any movieclip, button or textfield object. Then there is removeMovieClip and removeTextField which is used to remove movieclips and textfields from the screen. These pertain to depths because there are certain depths, as you will see later, where these methods will not function properly.
As you can see, most of these methods work on movieclips. This makes sense, as it is the movieclips which have the timelines we need to be concerned about, but for something like swapDepths and even removeMovieClip, you may want these to be accessible to your TextField and Button objects as well. Truth is, they are, just not by default. What I mean by that is that those methods, which are contained within the MovieClip.prototype, can be just as well used for a Button or TextField object so long as that instance has access to the function, which, by default, they do not. Here's how to change that by adding those functions to be accessible to the TextField and Button objects by adding them to those prototypes:
Button.prototype.swapDepths = MovieClip.prototype.swapDepths;
TextField.prototype.swapDepths = MovieClip.prototype.swapDepths;
Button.prototype.removeButton = MovieClip.prototype.removeMovieClip;
// TextField already has removeTextField
Now these methods can be used in Button and TextField instances just as they can with MovieClip instances. Actually, you can even use other methods in these objects this way, like attachMovie. Want to attach a clip to a button? How about a textfield?
In specifying depths for your objects, you need to be aware of the three "zones" in the ranges of valid depth values in Flash. Depths themselves, for visual objects, cannot be less than -16,384 or greater than 2,130,690,045 (there is an exception for createEmptyMovieClip). Indeed, unusual numbers, but those are the acceptable values for an object's depth. No depth will be outside of this range and, as you can see, Flash starts with the lowest part of that range when adding objects to the screen when reading the timeline. Now, within that range there are more or less 3 other ranges. One is the range that Flash uses to handle the timeline, that being from depths -16,384 to -1. Following that is the range, 0 to 1,048,575, the range that specifies the depths at which a movieclip or textfield can be removed with removeMovieClip() or removeTextField(), something not possible within the depths of the previous range. After that range, and going to the end, 1,048,576 to 2,130,690,04, is a kind of reserve range where movieclips can be placed by you, but can't be removed. Respectively I call these ranges, or zones, timeline, dynamic and reserve:
| Zone | Range | Note |
| Timeline | -16,384 to -1 | handled by timeline with Flash, dynamic removal disabled |
| Dynamic | 0 to 1,048,575 | most dynamically accessible, allows dynamic removal |
| Reserve | 1,048,576 to 2,130,690,045 | overflow - ignored by timeline, dynamic removal disabled |
The timeline zone of depths is where Flash handles timeline placed instances, working from around -16384 up giving plenty of depths before reaching the dynamic zone at depth 0. These are all based on arrangement specified in the Flash authoring environment. The very low starting depth mentioned before, where the lowest clips in the Flash authoring environment are first placed, starts at around this lowest depth of -16,384 (usually -16,383). From there it places objects in sequentially higher depths until all of the objects on the timeline are accounted for. Since there are only 16,000 instances allowed on the screen at one time in Flash, that gives plenty of depths for Flash to handle those timeline instances. Now, there's a little more involved here, but we'll touch upon that a bit later.
Next is the dynamic zone. This represents the range in which most dynamic instances would be, ideally, created. After all, intuitively, if Flash asks you to give a depth for an attached movieclip, you would consider some reasonable positive number value and nothing negative or anything too terribly high such as anything above 1,048,575. This doesn't mean that any object created dynamically on the screen has to be within this range. It's just the supposed range for these clips to exists since it is only within this range, and this is the important part, that you are allowed to remove instances with actionscript. Dynamically created instances, however, can be initially attached within any valid depth within any of the 3 zones. Should you want to remove them, however, you would want to place them here. And if not, then you would have to use swapDepths to place them within this zone to remove them. Note, this is valid for instances placed on the timeline as well. Though you may not initially be able to remove any movieclip you place on the timeline in the Flash authoring environment, should you use swapDepths to place that clip in the Dynamic zone, you are then able to remove it with removeMovieClip.
The reserve zone kind of makes up what's left. Its basically just an extension of the dynamic zone with removal disabled. Objects can be created there or swapped to a depth within that zone using swapDepths, but it deems itself unorthodox in that there is no ability for removal and that the simple value of the depth seems ridiculously high. Nevertheless, this allows 2,129,641,470 more values of depths to work with when arranging your objects on the screen through actionscript giving you a lot of room for playing around.
The exception to this set of ranges is for the createEmptyMovieClip method. There is no real limit for the depth when creating an empty movieclip. You can very well define it with a depth below -99999999999 or above 999999999999 and Flash will still create the empty clip despite the fact its out of the 3 valid zone's ranges. The depth of such an empty clip, however, when set beyond 2147483647 on the positive side and -2147483648 on the negative, it will start to fluctuate from what you truly set it, sometimes even being negative if set at positive and vise versa. You never can tell. It seems as though this is the absolute range for timeline instances, -2147483647 to -2147483648, though really only fully attainable through empty movieclips. Other clips, such as those within the timeline or created with something like attachMovie are restricted to the depths of -16,384 to 2,130,690,045 as laid out in the 3 zones.
Lets go back to the timeline zone for a moment. There is something that happens within that range that can cause a lot of confusion when toying with the depths of clips there, both dynamic and those placed in the timeline. What happens is, whenever the timeline is "refreshed" and all of the instances are redrawn, Flash actually goes through the depths in the timeline zone and removes all of the clips which exist within those depths, whether they were created there through their existence on the timeline or dynamically with actionscript. Flash then redraws the screen for those depths based on the information within the timeline disregarding any movieclips that might have been placed in those depths through dynamic means. An example of this kind of refreshing is caused by using gotoAndPlay to go to a frame which has already passed; going to frame 5 from frame 10 for example. When this happens, Flash does this refresh allowing it to correctly display the screen at this new frame as the progression of the timeline has diverted from normal playback and therefore must be completely re-conceived by Flash.
Obviously, this can cause several problems. One being the obvious of you losing any dynamically place instances within that range during a refresh of this sort, placed there either during their creation or as a result of swapDepths. What can you do? Well, you can not put dynamic instances in that range for one. Alternatively, if you know that you wont run into a situation where something like that will occur, say a controlled movieclip consisting of only one stopped frame, then it can be pretty safe to have clips within the range of the timeline zone with minimal worry.
Another problem, which may not be so obvious, is that concerning depth-swapped timeline instances. If you use swapDepths to bring a movieclip which was placed on the timeline in Flash out of the timeline zone and into a depth above 0, then in a timeline refresh, that clip will not be removed in Flash's clearing of the timeline instances and a new instance of that clip will be placed on the screen at its original depth, effectively duplicating it. Similarly, to avoid this, don't do it. Again, its safe in controlled timelines, but otherwise, its risky. Something to be aware of nonetheless.
Kind of along those same lines is the progression of the Flash timeline from one scene to another. This does not constitute a timeline refresh, nor, really, any other particularly special event. Scenes themselves are only slices of the main timeline which, when the Flash movie is published, get added on to one another as one big, single main timeline. Because of this, any dynamic instance you create (or any instance swapped above 0 depth) in one scene will be present in any other scene as the timeline plays through them. If you would not like this to happen, then you would need to use removeMovieClip/removeTextField to get rid of them at the end of the scene which they were placed.
Another somewhat overlooked role in depths is their influence in determining execution order of ActionScript. Actually, the depths themselves don't necessarily affect execution order but rather the order in which instances are created does. However, since movieclips are created in the order relating to their arrangement (depth) on the screen, there is that connection, at least in terms of the timeline. In regards to actionscript, its more a matter of the order in which you create any of those instances that you decide to make. Those you create first (these in the same timeline) will have their script run before those you create afterwards. Otherwise, the Flash authoring environment decides the order of execution based on arrangement or order created. Oddly enough, for instances on the timeline, those created last are those who's enterFrame event scripts get run first.
By default, instances are created from the timeline starting with the lowest layer upward. This is at the Bottom Up load order setting in you Publish Settings options. You have two options for load order, Bottom Up and Top Down, both which control the order in which layers are created within Flash. Frame scripts in these layers are run in the order they are created, so in a Bottom Up situation, any scripts on lower layers would be technically run first. However, as mentioned, enterFrame events are opposite that -and this includes both onEnterFrame and onClipEvent(enterFrame). In a Top Down situation, the opposite is true. So, with the default Bottom Up setting, assuming you have two movieclips on your timeline, one in a high layer 1 and the other in a lower layer 2, if both contain an onEnterFrame event as well as some script in the first frame of their timeline, then the movieclip in the lower layer will first have its timeline script run followed by the timeline script of the movieclip on the higher layer. Then the enterFrame event of the clip in the higher layer will run followed by that corresponding to the lower layer. Note, however, that script order within the frames of the layers themselves are always run from top to bottom, so the scripts in higher layers are always run before the scripts in lower layers. What this concerns is the execution of scripts within movieclips themselves as separate objects.
Depths can be a tricky subject. You may be one of those people who never have any trouble in using them, and then again, you may be one of those people who have all the trouble in using them. It all depends on what you try to do and how accepting Flash is of that. What's been discussed here pretty much covers all that can and will go wrong when attempting manipulate depths in Flash. I think the biggest consideration is the timeline zone and how it can influence your handling of clips, both timeline and dynamic. Many of the more common and unusual troubles experienced with Flash and depths deals with that range of depths and the repercussions of putting or removing clips from that zone.
Some depth related scripts:
/* removes any movieclip */
MovieClip.prototype.killMovieClip = function(){
this.swapDepths(1048000);
this.removeMovieClip();
}
/* gets the highest or lowest depth in a movieclip */
MovieClip.prototype.highestDepth = function(){
var curr, high = undefined;
for (var clip in this){
if (!isNaN(curr = this[clip].getDepth()) && this[clip]._parent == this){
if (curr > high || high == undefined) high = curr;
}
}
return high;
}
MovieClip.prototype.lowestDepth = function(){
var curr, low = undefined;
for (var clip in this){
if (!isNaN(curr = this[clip].getDepth()) && this[clip]._parent == this){
if (curr < low || low == undefined) low = curr;
}
}
return low;
}
/* returns an instance which occupies the passed depth (if exists) */
MovieClip.prototype.instanceAtDepth = function(depth){
for (var clip in this) if (this[clip]._parent == this && this[clip].getDepth() === depth) return this[clip];
return undefined;
}
That wraps up this tutorial. A huge thank you to all of you who buy kirupa's books, became a paid subscriber, watch the videos, and/or interact on the forums. Your support is what keeps writing like this online! 😇
This tutorial was written by senocular, also known as Trevor McCauley. He has been one of this community's most generous teachers since the early Flash days, and he is still around: find him on senocular.com and on the forums.
:: Copyright KIRUPA 2026 //--