Semantic layout can fail unexpectedly

Skip to first unread message

Richard Klancer

Sep 4, 2014, 11:28:32 AM9/4/14
hi all,

Recently, I was working on fixing the strange layout of DNA interactives as previously discussed at!topic/lab-models/LwJejYnUyJ0

To make a long story short, the logical solution involved setting "width: interactive-width" for the container that has the buttons and associated text. But this caused the resulting layout to look very strange. (Actually, a number of layouts I tried failed in strange ways I didn't understand; it's just that this was the simplest case and the one I debugged.)

What was happening was the layout algorithm just stopped when it reached the max number of iterations, rather than because the constraints were met. The problem is that padding is added to the container, in one part of semantic-layout.js, but the padding is not accounted for when the stopping condition is checked for. That meant that the stop condition was guaranteed never to be met at all; see for details.

I worked around the issue when fixing the DNA interactives, rather than fixing the bug in semantic-layout. This is partly because I see a few things I don't fully understand the intent of, and because testing semantic layout is a little bit tricky; since there's no formal spec for how semantic layout should behave, it seems that changes could unexpectedly change the layout of interactives. (Fortunately, of course, we do have a service for grabbing snapshots of interactives, making it practical to test in a semi-automated way. Of course, it would be nice to have a formal spec and tests that check against the spec, but that's not really practical right now.)


Scott Cytacki

Mar 17, 2015, 11:14:29 PM3/17/15
to lab-models
I just wrestled with the semantic layout myself.
In my case I was trying to get two containers on top of the model. After a while looking at the layout code I figured out how to make it work.
The order of the container definitions matters (at least for putting stuff above the model). This is because the top of the model is only really adjusted on the first iteration. That is probably not the intention, but it is how it is currently working.

The gory detail is:
In the first pass at positioning of the containers the 'top' of the topmost container needs to be a negative number that is equal to the amount you want the modelTop to shift down.
This can be done by defining the container closest to the model (lower-container) first and specifying it's bottom to be ''. Then define the container above that one (upper-container) and specify it's bottom to be  This will result in a computed top for the upper-container that is the negative of the totalHeight of the two containers.  This then causes the modelTop to be shifted down by that much.  

If you specify these definitions in the order which you want to them appear, then it doesn't work.  When the 'top' of the upper-container is computed the top of the lower-container won't be known yet, so it will default to 0.  This will make the computed top of the upper-container to be 0 - upper-container.outerHeight.  Then the top of the lower-container  0 - lower-container.outerHeight. At this point the modelHeight is shifted only by the minimum of those two values and it is unlikely it will be shifted again on the second pass. Sorry it is too hard to describe why that happens, but if you put a debugger statement in you can see it happening.

When I first looked at the code, I couldn't see how any container above the model would actually shift it down, but after some debugging then I saw how it only happened during the first pass/iteration.

You received this message because you are subscribed to the Google Groups "lab-models" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
For more options, visit

Scott Cytacki
The Concord Consortium

Reply all
Reply to author
0 new messages