I’m writing a simple contenteditable-based HTML editor, one which lets the user edit a page that is styled by their own CSS (which they can live-edit) and also do basic things like insert new tags, apply classes, etc.
One feature I’d like to have is an option to toggle the display of dotted borders around divs, much like you typically find in WYSIWYG HTML editors such as Dreamweaver, Expression Web, and many others. (This helps the user see her divs even when they have no visible border.)
Is there any possible way to do this? Some ideas:
-
I can’t simply modify the CSS on the actual/existing divs, since they may already have their own borders defined, which I should not obliterate with dots. Ideally, I can show a border around the existing borders, which is how things appear in the aforementioned commercial editors. Even if I fall back to actually setting borders on elements that have no existing borders, figuring out which ones have no borders may be difficult, esp. in the face of things like
:hoverwhich dynamically change the computed style. -
I may wrap these divs inside new divs, which in turn have the dotted border. The tricky part is handling their CSS, e.g.:
-
Wrappers must be similarly styled as their children, e.g. a div that has
width:50pxmust have a wrapper that’s alsowidth:50px(roughly), so I’d either need to continually poll (as there’s no way to be notified of indirect style changes, e.g. on the class) for changes to the computed style (which is completely non-scalable), or implement my own CSS engine that runs and determines what has changed each time the user live-edits their CSS. -
Polluting the DOM with my own divs is invasive and interferes with rules such as:
/* these may or may not be divs */ .a > .b > .c { ... }or:
/* if this is wrapped, then they'll all be :first-child */ .foo:first-child { ... }or perhaps:
/* immediate children of my wrappers would inherit the dotted borders */ .foo { border: inherit; }Perhaps there’s a way to automatically rewrite these rules robustly – to take the last example:
:not(.my-dotted-border) > .foo { border: inherit; }But even if theoretically possible, there are a ton of cases to worry about and it would be quite hairy.
-
Lastly, perhaps there’s a way to collapse margins even with the dotted border, but I don’t know of it.
-
-
Another idea is to overlay the borders on top (absolutely positioned with JS based on the dimensions/offsets of the underlying elements), but this is ugly with overlapping elements that have particular z-indexes, and again I’d need to monitor all elements for style changes. Except now it’s not enough just to monitor the changes in the explicitly specified styles, as I need to react to changes even to offset and dimensions (e.g. if the user types some text, it may push down all the elements below it, so I must react to that by updating the overlays).
A related question is See the page outlines but this is from the perspective of a user who wants to see outlines – I’m asking from the perspective of a web-based editor implementation, how to provide these outlines.
Thanks in advance for any tips.
You can use the
outlineandoutline-offsetCSS properties to style the outline of your editable divs as they will not overwrite any existing borders (they will however overwrite any existing outlines if there are any).Check out this example to get an idea of how you can implement it: http://jsfiddle.net/EFJ6B/