Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling contentEditable lists (<li>) with font-family, font-size, and color

I'm looking for a way to style lists so that they will use formatting set by the user while editing within a contentEditable element. Specifically, I want to be able to style the number/bullet in the same manner as the rest of the <li> content.

From the testing I've done, the browser never styles <li> tags directly (which actually controls the style of the number/bullet) but always places a <font> tag (or <span> if StyleWithCSS) as the first child node, using it for the formatting. I've tried a few ideas already to get around this, but have not found success:

1. Apply styles to the <li> programmatically

Here I tried listening for 'DOMNodeInserted' and when an <li> tag was inserted into the DOM, I queried the current fontName, fontSize, and foreColor commands and applied them as an inline style on the <li>.

textarea.addEventListener('DOMNodeInserted', function (evt) {
    if (evt.target.nodeName === 'LI') {
        evt.target.style.color = queryCommandValue('foreColor');
        evt.target.style.fontFamily = queryCommandValue('fontName');
        evt.target.style.fontSize = queryCommandValue('fontSize');
    }
}, false);

Even when doing this, as soon as you begin typing in the list item, the browser tries to be "smart" and strips the styles from the <li>, placing them into a <font> (or <span>) tag. :(

2. Create a rule for the styles to be inserted into the StyleSheet

Based off the attempt above, instead of writing the styles inline, I created a rule for them, gave the <li> node an ID, and inserted the rule into the stylesheet. Now the rule would govern the style of the <li>, and I could use the CSSOM to continually update any particular <li>'s styles.

This seemed to work very well (with a few bugs to solve for), however, it completely breaks the contentEditable undo stack. Since the undo command is only tied to textContent and other formatting commands, there is no way to "undo" the styles you are setting in the stylesheet. (At least not very intuitively, I've thought about how this might be done...)

3. Watch for changes in the <li>'s attributes and retain them

For this attempt, I made use of the newly-available MutationObserver http://www.w3.org/TR/dom/#mutationobserver available in DOM level 4. This observer can watch for changes in a node's attributes, which will be passed back in a MutationRecord. It can even hold the previous attribute values, including style values, so I could find out what was being removed and re-apply it.

var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.target.nodeName === 'LI') {
            ...
        }
    })
});

observer.observe(document, {
    attributes: true,
    subtree: true,
    attributeOldValue: true
});

This still suffers from lack of undo support. You will undo other formatting changes but the <li>s will keep their styles.

Any novel ideas out there? Modern-browser only solutions welcomed as well. I'm aware that I could format my own HTML to use for lists but I'm trying to see if this can be done using the standard insertOrderedList and insertUnorderedList commands which use real list tags.

** Update Nov 7 2012 **

Doesn't look like anyone has solved this yet, here is an example JSFiddle to see what I'm describing: http://jsfiddle.net/8LyZR/. Just try to change the styles of bulleted or numbered lists.

For the project I am working on, we are using our own build of WebKit so we were able to fix this with a native change but I'm hoping there is a way (or will be a way) to do this directly with HTML/CSS/JS.

like image 214
skyline3000 Avatar asked May 10 '12 19:05

skyline3000


People also ask

How do you change the font style of a list in HTML?

To change font type purely with HTML, use the CSS font-family property. Set it to the value you want and place it inside a style attribute. Then add this style attribute to an HTML element, like a paragraph, heading, button, or span tag.

How do I change the font color and size in HTML?

You can change the color and size of your text right inside its tag with the color and font-size properties. This is known as inline CSS. You do it with the style attribute in HTML.

How do I change the font-size on my UL tag?

So, type the Size attribute within the starting <font> tag. And, then we have to give the size which we want to use on the text. We can give the value of size from 1 to 7. So, type the number in the Size attribute as described in the following block.

Which HTML tag is used to define font style and font color?

HTML <font> tag is used to define the font style for the text contained within it. It defines the font size, color, and face or the text in an HTML document.


1 Answers

Here's some interesting CSS trickery. http://jsfiddle.net/GZ3cv/

It basically relies on placing a psuedo-element :before on the inline tags, (which will inhereit the styles), and then attempting to position it on top of the original list bullets/numbers.

I can't decide if I would call this a solution, as it could grow impractical with all the different combinations of nested/inline tags (font,u,b,span,i).

But just playing around with font, size, color, and the list-type controls it seems like it could mimic what you are looking for with some obvious thorough tweaking involved.

I'm curious if this technique is plausible or just ridiculous :) Just throwin it out there..

like image 169
brains911 Avatar answered Nov 15 '22 00:11

brains911