When working with designers, they often are very picky about word wrap in the completed HTML page. Assuming that I'm working on a fixed layout (not-responsive), and the designer does not like the way text is wrapping, I can:
Adjust padding-right
Add manual <br> to break a line
Add manual to avoid a break (typically for orphan control)
(In my case, I'm designing for a specific mobile device, so I know the screen size, and can control the fonts. Also, making the designers happy is non-negotiable.)
The issue that I keep running into is that the text or layout will be updated later, and relics of this specific word wrap concern, which no longer apply, introduce issues we then need to fix.
So I'm wondering if anyone can suggest a strategy that:
Allows completely arbitrary control of word wrap in individual
cases; but,
Doesn't make everything so hard to maintain going forward
I'm open to procedural, algorithmic (javascript), or CSS-oriented suggestions.
Here is the strategy I chose. Time will tell how maintainable it is.
Do not edit the text content
Fix wrapping by adding CSS classes that change the way the text flows, but do not use attributes like width or padding that are already being used to control layout
Specifically:
.tighten {
letter-spacing: -0.011em;
}
.loosen {
letter-spacing: 0.011em;
}
.hyphenate {
-webkit-hyphens: auto;
-webkit-hyphenate-limit-after: 4;
-webkit-hyphenate-limit-before: 4;
}
It turns out that these imperceptible changes in spacing can make a huge difference in wrap. I actually have several variations of these classes, so I can try progressively more or less space to fix wrapping.
In severe cases, I use the hyphenate class (I'm only targeting iOS in this case).
In a future revision, when we change the text in a div, we can just remove the tighten, loosen, or hyphenate class from that div, and see if there are any wrap issues we need to correct. If there are, we go through the original trial-and-error of seeing which class gives the best look.
Use <pre> tag so you can insert preformated text.
Related
I'm trying to make a website that uses bootstrap's grid systems as a guide, but isn't ruled by it, to the point of looking too similar to other websites, and having all my elements either too close to each other, or too far apart, which tends to happen with the most basic usages of the 12 column layout.
Now, I know I could change the number of columns to 16 or 24 but with the way I have my project setup that would be difficult and would still be more restrictive than I'd like. So I was wondering, if I have code similar to this:
<div class="bean-game col-md-8">
<h2>Bean Curd Mixing Area</h2>
</div>
Without using the width: CSS property, or anything that overrides the Bootstrap CSS completely (which I'm concerned might make the code unmanageable in other ways), is there anything I can do with CSS, or perhaps even JavaScript or a JS library if need be, to make the.bean-game div resize relative to the width set in the Bootstrap code for the col-md-8 class?
In the case of the website I'm working on, I'd like the div bearing a col-md-8 class to be just a fraction wider (say 10px or so), so as to neatly align with the div above it, which, despite bearing another col-md-[foo] class is just outside the usual grid-system due to some minor trickery with a container div and some margins, which gave me a spacing effect I was after...
I realise this may be a difficult thing to be trying to do, but it really feels like the best way to approach this particular issue.
I've had a look into this and it seems the best solution for me at present will be using pseudo-classes (probably ::after though I haven't played around with them enough yet...) to add pseudo-padding and therefore get around the Bootstrap limitations on the fly, without have to customise my entire Bootstrap setup (which I prefer leaving on a CDN,) and without having to dirty the relation between form and function by having my JavaScript perform styling operations unrelated to user input. It's still not a 'perfect' solution, but I may use it as an opportunity to introduce some slightly more advanced styling, which will hopefully benefit the overall page aesthetic.
I will accept my own answer if this solution works out to my satisfaction.
I'm currently wondering about the ability to apply dynamic formatting to content in an HTML page without changing the flow rules. At face value, this might seem simple, since you can select a subset of the DOM and mass-apply. However, this would not work if you wanted to apply that formatting to a only one part of the text for a particular object.
For example, formatting:
<div>Let's start my format here <span> and here </span> and <br> here too. <br> But not here.</div>
If you wanted to exclude <br> But not here. from your formatting there is no clear way to do it for the case of an arbitrary layout, even if you did so manually. One approach is to break the div into span sections, then format them differently. Unfortunately, wrapping arbitrary HTML in inline elements causes some unfortunate side-effects (e.g., any <br> tag in a span will be treated as if it doesn't exist). Using a block element wrapper, like introduces similar issues by adding breaks that didn't exist. I cannot seem to find a way to declare a DOM group that can just plain act as if it were plain text within the parent object.
So then, I'm trying to figure out a good general workaround to introduce display-level formatting while preserving any layout formatting. This kind of formatting could include text formatting (e.g., highlighting, emphasis) or dynamic effects (e.g., hide/reveal). I can think of a few hypothetical solutions, but I am not sure what (if any) actually are possible in practice:
An existing inline layout element like span that doesn't kill your line breaks and other formatting requests.
The ability to make a custom element such as #1 using CSS. Maybe the run-in or inherit display tags might be useful for this purpose? (https://developer.mozilla.org/en-US/docs/Web/CSS/display) Neither of them seem like they solve this issue, however.
A way to prevent a span from clobbering formatting markup inside of it.
A grouping element that acts as a pass-through for layout formatting (i.e., is treated like untagged text for layout purposes) but allows display formatting.
One would think this would be a straightforward thing to do. After all, it's not hard to imagine wanting to split a div into two different sections that are text-formatted slightly differently, while retaining their layout formatting. However, I can't seem to find the right tool for this job.
After looking at this quite a while, the best that I came up with was to use span wrappers for the text nodes only, accompanied by clobbering the default CSS formats for spans. This had its drawbacks, but thankfully people often leave the basic span class alone.
However, considering it further, I think the best solution is actually to make a new type of span using webcomponents.js and then to make that span type always inherit the parent formatting. Particularly if that span type has a very arbitrary name (e.g., <span-(some guid)/>), that should be sufficient to prevent any chance of accidental conflict. I have also found that by wrapping only the text nodes, there is no chance of losing line breaks or other formatting, since those elements can never exist in a text node.
I am not necessarily saying this is the best answer, but it is the best one I've seen so far.
How do you get words to wrap inside a box in RaphaelJS? Or in browser-based SVG in general?
I found this thread on it, but it doesn't make any sense. They say to use "widthToCharNum" but as far as I can tell, this thread is the only place those words have ever been used on the internet. They suggest using a "width" attribute, but this has no effect.
Text-wrapping is not built into Raphael or the SVG spec. Period. Coming from the HTML world, I found the absence of text wrapping pretty shocking.
However, you can do it yourself without too much difficulty. See this question for details and an example. Unfortunately, you have to burn some client-side cycles to make it work dynamically.
The svg.js library has a svg.textflow.js plugin. It's not ultra fast but it does the trick. It even stores overflowing text in a data attribute so you can use it to create continuously flowing columns. Here the text flow example page.
The tspan tag can give the illusion of word wrap, but there is no built in word wrap functionality.
The tspan tag is identical to the text tag but can be nested inside text tags and inside itself. Coupled with the 'dy' attribute this allows the illusion of word wrap in SVG 1.1. Note that 'dy' is relative to the last glyph (character) drawn. There is a tutorial on how to use tspan at http://tutorials.jenkov.com/svg/text-element.html.
The article at http://www.xml.com/pub/a/2002/09/11/quint.html might also be useful.
I know it's a little belated now, but you might be interested in my Raphael-paragraph project.
It's a small library that allows you to create auto-wrapped multiline text with maximum width and height constraints, line height and text style configuration. It's still quite beta-ish and requires a lot of optimization, but it should work for your purposes.
Usage examples and documentation are provided on the GitHub page.
I have a piece of HTML which I am displaying inside a UIWebView using Webkit stylesheet attributes. I use Webkit to display the HTML in columns in order to simulate a book.
Only one column is visible at a time (one column represents one page). Now, I am trying to find the range of the visible HTML so that I can insert a span element right before the first visible word.
I managed to get the HTML element which contains the first visible word by using the JavaScript function, document.elementAtPoint(I might have the function name wrong), and changed its CSS class. but that just isn't accurate enough for me. I need it to be accurate up to the first visible word.
The idea is the create a column break at the first visible word when the fontsize is increased or decreased. I can using JavaScript to figure out in which column the element is, and programmatically scroll the user to that column, but first I need to get the element in there.
Can anyone help me?
The CSSOM View Module specification adds caretPositionFromPoint(x, y) to the Document interface, which returns a caret position for the specified x and y co-ordinates. WebKit supports caretRangeFromPoint, a close analogue from an earlier specification, which returns a Range.
It is possible that the word has been hyphenated and thus spans two columns, so rather than wrapping the first word in a span you may wish to consider the more naive approach of inserting the span directly at the cursor point. Here's an example:
var caretPos = document.caretRangeFromPoint(x, y);
if (caretPos)
caretPos.insertNode(document.createElement('span'));
Demo (WebKit only—click to insert spans): http://jsfiddle.net/Jordan/Aw9aV/
One final consideration: it is possible that WebKit will eventually stop supporting caretRangeFromPoint in lieu of caretPositionFromPoint; if so, you will need to adapt your code. Also note that the latter returns a CaretPosition which may not implement the insertNode method. The spec is still at WD, so be mindful that it is still in flux.
Ok, nog entirely sure what you are currently doing, but at the very least I should be able to give some useful tips, as I have some experience building page browsing systems in javascript.
First of all, in CSS3 you can define columns https://developer.mozilla.org/en/CSS3_Columns , which will automatically split up the content into different columns within a single element (where a single column has the full width of the uiwebview) and next add browsing controls which move the entire element containing the element (using css3 3d translations for smooth hardware accelerated motion and you know the width of the columns so you don't need to worry about what the first word on the page is). In which case you don't need to worry about splitting up the column breaks yourself. (Though, as I said, I am not sure to what extend you are already doing this).
Alternatively you may decide to wrap all your content in small inline-blocks (as older column implementations did) or even up to the point of single inline elements, each containing a single word. (Though this doesn't seem necessary anymore)
Lastly, work is being done on http://www.w3.org/TR/css3-regions/ which will make this even easier in the future, but for now it's only available in chrome and ie10
On the other hand, you might already be doing this or I might be missing the point, in which case I would need to see some code before I can give you a more specific answer. (I can think of various javascript tricks to work with letters within a text, but none seem necessary in your case)
I'm developing a web-based text editor without any contentEditable, textarea or input things. The biggest portion of my work is to measure widths of text on the left (right) side from the current caret position and moving the caret in the text.
For example when user presse the DOWN key a current left-offset of the caret must be computed and on the line below a character which's position is most similar must be found.
One very convenient way to do is to use one DOM element per character - I can just look at the offsetLeft property. Also, positioning the caret is much easier. Actually, everything is easier.
However I'm very unsure about the performance implications. I have seen this technique (or similar) used on some web-based JavaScript "IDE"s and it works just fine there.
Do you have any hints, tips?
Do you know some other fast way how to measure width of text. I want to avoid putting sections of a line to a DOM element and measuring its width each time as I think it will be much slower.
EDIT: I'm mostly asking about the main fact of EXISTENCE of many dom elements. How to do the measuring is a different thing.
I've seen this done (unfortunately can't find the link now) by using a canvas object and its measureText() method - basically you can ask a canvas "what size would this piece of text be if i rendered it in this style?" and use that to determine your caret position on the surrounding lines. This is performant, but of course it will only work in HTML5-capable browsers, and maybe not all of them.
But frankly this sounds like a big pain in the neck and probably more trouble than it's worth for an in-browser editor :)
You might be interested in this, which is a javascript implementation of the VI text editor. Unfortunately it does use a textarea, however not in the typical manner.