Posts Tagged ‘html’

a wishlist for contenteditable

Wednesday, January 5th, 2011

For the past month, off and on, I’ve been working on this text editor. It’s basically functional now, and I stand by my assertion that building bespoke text editors with contenteditable is a worthwhile consideration for sites that need minimal editing options. I even managed to add spell-check. That feature’s only available in IE (I’ll get to why), but that’s fine since built-in spell checking is now the norm and most other browsers include it. However, working this closely with contenteditable has given me a real clear picture of its shortcomings as implemented now, what things I really wish were standard, and what standards I wish browsers were currently equipped to support.

wrap a selection with arbitrary HTML

Initially, formatBlock sounds very promising. Mozilla’s excellent designMode command documentation says developers can use this command to wrap a selection in almost any block-level element. Sadly, those block-level elements, in practice, wrap the entire line that contains the selection instead of separating it out and moving the selection and its parent to a new line. This is in keeping with the behavior of insertUnorderedList, for example, but is annoying because this command doesn’t work any other way. The MDC docs offer em and button as examples of tags you could potentially insert, but in my tests those failed and execCommand returns false. Read a little further in Mozilla’s documentation and you’ll find that IE supports an even smaller subset of HTML tags, which barely even matters because wrapping HTML around a selection is already only useful in such a small number of cases. This pretty much rules out advanced editing or truly being able to use contenteditable to edit a webpage.

wrap a selection with a CSS class

With the exception of IE, browsers carry out commands like bold or italic by wrapping the selection being acted upon in a span with inline CSS specifying the formatting. Wrapping selections in spans (or fonts *cough-IE-cough*) with a class assigned instead of that inline CSS should be pretty easy, but the option just doesn’t seem to be there. I’ve looked. Again, even if you’re of the school that believes contenteditable is just for editing webpages and not for rich text editors or other vulgar uses, this seems like a necessity. It’s not reasonable to expect to offer enough diverse HTML tags that editors will be able to produce whatever functionality and styling they need without having that class for JavaScript and CSS to use as a hook, especially when the tags contenteditable produces differ between browsers.

a designMode command to create a selection

So we don’t beat up on IE too much, I’ll mention right away that IE does have this, and it works pretty well. This, as a matter of fact, is the secondary reason that my text editor ended up only supporting spell check for IE. IE has a command, findText, that takes a string and looks for it in the contenteditable area. This came up prior to the spell check when I was trying to help our automation engineer figure out how to programmatically mimic selecting some text and clicking text editor buttons to format it, so I had to find a solution for Firefox as well. It’s super elegant. You ready? We wrapped the text to be selected in an <i> and used range.selectNode to highlight it. Had this not been automated, that wouldn’t have worked, cause you can’t just type HTML into a contenteditable area, we would’ve had to calculate the offset and length of the selection within it’s containing node or textnode. FYI, once you talk about selections spanning one or more nodes, that ceases to be any fun. It would be great if other browsers would support findText.

my cursor? please?

There’s some strange intialization most browsers seem to require in a contenteditable area. Firefox, for example, will allow you to click into the area and type normally, but you don’t get a cursor until it’s added the <br> that I guess lets it know the area has changes. I’ve been experimenting with various kinds of placeholder text – because putting so much as a space inside the editor allows any browser to click into it normally – but everything I’ve tried is a little screwy. It would be much nicer if offering to let the user create a new text node were a browser’s default behavior in an empty contenteditable area.

for mobile webkit to support it

Or, at least, if mobile webkit is not going to support contenteditable, for it to quit pretending that it does (feature sniffing for execCommand doesn’t work – webkit claims everything is peachy). Clicking into a contenteditable area doesn’t bring up the user’s keyboard. Links within the area continue to function as links, no matter what kind of JavaScript I’ve applied (this may be because I suck). It appears that in mobile webkit all child nodes of the contenteditable area inherit the same bizarre implementation of contenteditable the parent has and become useless buttons. Which is to say, you can attempt to move your cursor into the middle of a text node and instead the text node will be highlighted and you will not get a cursor of any sort. From what I’ve read online, this is a very vexing problem for the developers of these browsers, but I really hope they’re able to figure it out.

for more consistent results

Guess what fontName, fontColor, and fontSize produce in IE? A span with its style attribute filled with font-family:'Comic Sans MS';font-size:70px;font-color:#f0f;? Nope! Give up? It’s font tags! Just like 19-fucking-96. I have not yet installed IE9 because for a long time I didn’t have Windows7, and then I did but I’d stopped caring. Maybe IE9 fixes this. But we all know it’s going to be another decade before IE9′s older siblings go back to the primordial tar pit they crawled out of and until then, using built-in designMode formatting commands means that your user generated content has motherfucking font tags in it. There’s not a lot that can be done about the other browsers and their inline CSS, but my personal wish is that browsers will implement some reserved classes (e.g., .agent-format-italic or something) and attach those instead. Probably best to just be happy that most browsers are using spans, though. But, IE? That font bullshit? Not cool, buddy.

You may feel like this is awfully complainy for someone who started this blog post declaring her modest triumph over this same technology. Like I said, I still think this is loads better than having to download and customize someone else’s editor. But to get my very simple one working, I’ve had to employ some dirty tricks, and that’s the only thing that frustrates me. To wit:

  • Browser-sniffing to get around mobile webkit
  • Wrapping misspelled words in font tags because I can’t use classes or arbitrary HTML
  • That nasty business with selecting text in Firefox I mentioned
  • Having to go through the hidden textarea to strip out HTML comments because either innerHTML or contenteditable won’t admit they’re there
  • Having to insert hrs before and after pasted text so that I can find it and clean up the markup
  • Generally bringing shame upon my family

So I guess let that serve as a warning to you if you decide to go down this path. Although I wish contenteditable were more mature and more standardized, I’ve also had fun working with it. Since we all got JavaScript frameworks and HTML5 and CSS3 support, it’s getting rarer and rarer that it’s necessary to hack something. Dirty and shameful though it’s been, it’s also been interesting.

5 ways to not write html in your backend code

Sunday, July 11th, 2010

At work right now I’m involved in a minor turf war over HTML. I write it in the .aspx and then other people sometimes move it into the C#, which aggravates me. The reason given for this is Don’t Repeat Yourself, but I’m trying to make the case that there are other ways to respect DRY in this situation. I can think of at least five methods that would be both more maintainable and less code the server needs to interpret.

1. Provide additional properties

I admit it’s not the cleanest thing to do, but adding boolean properties on the objects being rendered that say things like whether a user is the same one who’s logged in or whether some object has an image attached to it offers a lot of flexibility on the UI. It’s a simple way to get around writing backend logic in the page itself while offering the possibility of later reuse. It’s messy, though, because there’s a temptation to just misuse existing properties instead of asking for a new property, and conversely, you can end up with a lot of duplicate information. A good example is the length of an array. You could end up repeatedly asking the array for its size to render things differently for 0 objects or some minimum number of objects that you want users to be able to page through. You could get this information instead in properties like hasObjects and doPaging or something, but that’s just adding to an API things you could infer from what you have already. And neither alleviates the need for backend loops and conditionals mixed in with your HTML.

2. Put repeated logic in user controls

Forgive me for not knowing how this concept works in other frameworks, but I’m guessing they all natively have something similar or can be abused into offering it. Instead of adding helper properties to your API, you could create those properties based on a single object passed into a control. This is less flexible than having the extra properties available to everything on the page, but it feels much cleaner and object oriented. In .NET MVC, there seems to be a movement against having code behinds for anything, which I think is unfortunate, since creating helpers for use within the context of a specific user control based on one large, self-contained object makes much more sense from an MVC perspective than having the server try to figure out beforehand everything the page will need.

3. Use JSON and render everything client-side

This is not a solution that works for all situations, obviously, since it requires Javascript. However, if you’ve got a client-based application that just has to have Javascript anyway, it works very well. I know this is not a popular approach with some people because of the extra rendering time when the page/application first loads and you have to parse and insert your data only after that happens, instead of doing it all beforehand. But if we’re assuming this is a client-based application, we can also assume it runs on AJAX and you’re only going to be loading the page once. So sometimes the tradeoff seems acceptable.

4. Server side Javascript

Since I haven’t actually played with this technology, I will sound like a dumbass if I try to go into why this would be good and therefore I won’t. But from what I think I understand of it, it would fix the problems in the method above (reliance on Javascript, needing to parse everything when the page first loads). I take the proposal to include templates in jQuery as a sign that, if templates don’t already work with these server side JS technologies, they soon will. If I’m correct about not needing duplicate files, it seems like it could be really easy and fly as hell.

5. User controls + templates

This is my favorite. When the page first renders, you pass an object from the server side into the control, it plugs in the values, and all the HTML is rendered and ready when the client downloads it. Say there’s an existing list of Things, and the user adds a new Thing. The markup from the same user control that rendered the other Things has been added to the page inside a script tag (or a convenient external URL) and now, when the server responds with the confirmed data about the newly added Thing, it’s applied to the template and that gets rendered without refreshing the page. I think that’s fucking elegant. My boss thinks I’m high and that we should put the markup in user controls and use those both the first time the page renders and to respond to XHRs with the markup pre-populated.

If you’re reading this, what do you think? Am I betting on the wrong horse here? Did I miss something?

defending terrible things

Saturday, June 19th, 2010

I’m sure all this has been said before, but it’s a minor obsession of mine. Ignore HTML5 for a second, and all the interesting things happening with Javascript and CSS. I’d like to discuss the kids in leather jackets smoking cigarettes behind the gymnasium of web development: <b> and <i>.

And WordPress is going to make my first point for me. I’m typing this in their WYSIWYG and the buttons for bold and italic are a little b and a little i. When I toggle one on, it becomes /b or /i. And yet the HTML that gets inserted is <strong> or <em>. Why?

Point 1: The bold and italic tags do exactly what the fuck it says on the tin.

If you want something in a division on a page, there’s a tag for that. If you want something to be a heading, there’s a tag for that, too. These tags, like all others, accomplish what they do only through conventions of browser manufacturers, but can nonetheless be relied upon to get you some semblance of what you want even if your CSS should be mysteriously and tragically abducted in the middle of the night. Like the bold and italic tags, they tell you very little about text they contain. But nothing in HTML tells you about the text it contains. It does, however, sort of tell you what it’s going to look like in a webpage and describe the role it will play in the page’s structure.

Point 2: If you want semantic markup, use XML.

XML is a very handy little language that will let you describe your precious digitized text as precisely as you want. You can style it and present it on the web and get exactly the same thing you would from a document full of non-semantic <div>s and <span>s. Or, hey, put even more <span>s in and give them all seventeen class names and call it a microformat. I hope you have a really, really fun time doing that. If, on the other hand, you’re willing to consider that your consumable data and your pretty website need not be the same beast, you could just keep the XML somewhere else and if anyone ever actually wants to scrape all the air dates and titles of the Buffy the Vampire Slayer episodes you recorded on VHS, let ‘em just grab that.

Point 3: Why this webpage is shouting at me!!

You know what strong and emphasis refer to? They refer to verbal inflections. You know what most peoples’ web browsers don’t do? Talk to them. You know what would annoy the shit out of me if I were using a screen reader to read a bibliography on the internet? Listening to a goofy-sounding computer voice try to emphasize every single word of Journal of the Study of Obscure and Mostly-in-Latin Canine Diseases Affecting Generally the Respiratory System but Also Sometimes the Lymph Nodes or something. I don’t know that this is still a problem, but the idea is ridiculous in and of itself. Italic does not always mean emphasis, nor does bold always mean MAKE THIS LOUD. Certain conventions of formatting require the use of bold or italics, but actual writing rarely does. If you need to place emphasis on something, you can do that with word choice. (Or anyway I hear it’s possible..)

Point 4: Character count

When I first started doing professional web development, lots of things weren’t digitized. Therefore I spent a lot of time marking things up, enough that I began to have those horrible almost-nightmares where you’re doing the same task over and over and you can’t stop doing it or thinking about it. If semantic markup had been a buzzword back then and every <b> had to be a <span style="font-weight:bold;">, I probably would have gone back to working at Chevron. The bold and italic tags are short. The emphasis tag isn’t bad, but the strong tag is way too long to be a good value per keystroke. This is to say nothing of what you should actually be doing if you want to keep your presentation and your tags altogether separate, using a span with a CSS class describing the content and not merely the fact that you want it extra heavy. I mean, sure, I will always use CSS to bold or italicize something if there’s already a tag around it. Nine times out of ten a bold or italic tag would be inappropriate there anyway as the font weight or style is purely decorative. On the other hand, if something needs to be weighted or styled differently and has no containing HTML element, fuck it, I’m using <b> and <i>. They’re shorter.

Point 5: Dirty tricks

I add <b> and <i> to things I don’t necessarily want bolded or italicized. I do it because they’re some of the shortest elements available and they provide a hook to style child elements in larger repeated widgets with very precise, complex layouts. If I have to wrap every word of text in a tag just to accomplish some goofy layout, I’m using the smallest thing available. Especially if the widget in question is something I’m inserting dynamically and I want to keep it in a string without spaces and still be able to sort of recognize what’s in it without needing four monitors just to view the whole thing at once. Again, if Something Better exists, I always do that first. But there are times when nothing you can do is going to be semantic, screen-reader friendly, or anything you’d want your mother finding out you’d done.

One of the most beautiful things about the web is its imperfections. We don’t write firmware for missile guidance systems, we write applications that let you pretend to steal your friends’ cartoon cows. There are places for flawlessness and obsessive semantic control, but this isn’t one. When you can write elegant code, it’s awesome, and I think most of the time everyone tries to. But it’s important to realize that at the end of the day, this is all kind a series of epic hacks, and sometimes the most sane thing to do is just embrace it.

forms without lists

Wednesday, October 8th, 2008

This is the most recent product in a continuing attempt at making a flexible form that doesn’t require lists:

<fieldset id="floatlabel">
	<legend>Floated Labels</legend>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label>Lorem ipsum</label>
			<div class="optionGroup">
				<label for="Radio1">
				<input type="radio" name="radMenut" id="Radio1" value="1" /> Omnivorous</label>
				<label for="Radio2">
				<input type="radio" name="radMenut" id="Radio2" value="2" /> Vegetarian</label>
				<label for="Radio3">
				<input type="radio" name="radMenut" id="Radio3" value="3" /> Vegan</label>
			</div><hr /><!-- if div not needed for styling, etc., h-rule can be used here to create structure without css, fix for ie6 -->
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="txtMiddle0">dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Why the absurdly long label? Good to test in case of dynamic or translated text.</label>
			<p><b>Note:</b> Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.</p>
			<input type="text" id="txtMiddle0" />
			<i>ex: Typi non habent claritatem insitam;</i><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, </label>
			<div class="optionStack">
				<label for="Checkbox1">
				<input type="checkbox" name="chkSeatingt" id="Checkbox1" value="1" /> Stage</label>
				<label for="Checkbox2">
				<input type="checkbox" name="chkSeatingt" id="Checkbox2" value="2" /> Dancefloor</label>
				<label for="Checkbox3">
				<input type="checkbox" name="chkSeatingt" id="Checkbox3" value="3" /> Balcony</label>
			</div><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="txtFirst">First Name</label>
			<input type="text" id="Text1" /><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="txtMiddle">Middle Name</label>
			<input type="text" id="Text2" /><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="txtLast">Last Name</label>
			<input type="text" id="Text3" /><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="selSuffix0">vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</label>
			<select id="Select1"><option>(none)</option><option>Sr.</option><option>Jr.</option></select>
			<i>ex: Typi non habent claritatem insitam;</i><hr /></div>
	<div onmouseover="this.className='hilite';" onmouseout="this.className='';">
		<label for="btnSubmit" class="buttonLabel">Submit this:</label>
			<input type="button" id="btnSubmit" value="Go Ahead" />
			<input type="button" id="btnCancel" value="Nevermind" /><hr /></div>

It’s heavier than it needs to be because it has both a div wrapping each item and a horizontal rule after. One or the other does the trick. I’m pleased that it manages, even with both tags, to have fewer tags than you’d need for a form with the same elements nestled in a list, which seems to be the cool thing to do these days (myself, I’m in the not every collection is a list camp). I’m curious what a list would offer it that it doesn’t have now. I think this looks better with the CSS stripped out than it would if everything had excess bullets next to it, as well.

The CSS is like so:

.example, .note, i, p { color: #999; font-style: italic; line-height: 1em; }
.example, i { white-space: nowrap; }
.note, p { background-color: #f6f6f6; padding: 10px; }
input, select { line-height: 1em; font-size: inherit; margin-bottom: .8em; position: relative; }
hr { display: none; }
.hilite { clear: both; position: relative; overflow: hidden; height: 100%; }
.buttonLabel { visibility: hidden; }
.optionStack *, .optionStack label *, .optionGroup label *, .optionGroup * , .optionLabel * { vertical-align: middle; }
#floatlabel { position: relative; border: 1px solid #999; padding: 10px; margin: 10px 0px; font-family: Garamond; font-size: 1.1em; }
#floatlabel div { margin: 5px 0px 0px; padding: 0px; clear: both; position: relative; overflow: hidden; height: 100%; }
#floatlabel .hilite { background-color: #f3f3ee; border: none; padding: 0px; margin: 5px 0px 0px; }
#floatlabel label { margin-bottom: .8em; border-bottom: solid #999 1px; position: relative; float: left; width: 300px; clear: both; display: block; line-height: 1.5em !important; margin-right: 10px; }
#floatlabel input, #floatlabel select, #floatlabel .optionGroup, #floatlabel .optionStack {
	float: left; display: block; position: relative; top: 0px; margin-bottom: .8em; margin-right: 10px; font-family: Garamond; font-size: 1em; }
#floatlabel input, #floatlabel select { border: double #999 3px; }
#floatlabel .hilite input, #floatlabel .hilite select { border: double #cc8 3px; }
#floatlabel i, #floatlabel p { position: relative; float: left; }
#floatlabel i { width: 200px; white-space: normal; left: 0px; }
#floatlabel p { background: transparent url(/newsletters/img/flourish.jpg) center 95% no-repeat; padding-bottom: 20px; width: 200px; float: right; display: inline; margin: 0px; border: double #999 3px; }
#floatlabel .optionGroup, #floatlabel .optionStack { overflow: hidden; margin: 0px 0px .8em; clear: none; }
#floatlabel .optionGroup label, #floatlabel .optionStack label { border: none; width: auto; margin-bottom: 0px !important; vertical-align: center; }
#floatlabel .optionGroup, #floatlabel .optionGroup label { clear: none; }

I’m still working on it – the CSS could be cleaned up – but it’s nice to know that it can be done. The important things, to me, are that it allows for infinitely expanding labels, as well as notes and examples.

Screenshot of the finished product

Screenshot of the finished product