Ticket #657 (closed enhancement: fixed)

Opened 4 years ago

Last modified 8 months ago

allows tabs to wrap

Reported by: EricShulman Owned by: EricShulman
Priority: minor Milestone: 2.6
Component: core Version:
Severity: low Keywords:
Cc:

Description (last modified by EricShulman) (diff)

Add a "hidden wordbreak" space element between tabs to allow them to wrap onto multiple lines if needed.

config.macros.tabs.handler = function(place,macroName,params)
{
	...
	var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,"tab tabUnselected");
	createTiddlyElement(tab,"span",null,null," ",{style:"font-size:0pt;line-height:0px"}); // hidden word-break
	...
};

Attachments

ticket657.patch Download (0.9 KB) - added by PhilHawksworth 3 years ago.
Patch to StyleSheetLayout? for fix to ticket 657

Change History

  Changed 4 years ago by EricShulman

  • description modified (diff)

  Changed 4 years ago by MartinBudden

  • milestone set to 2.4.1

  Changed 4 years ago by MartinBudden

  • status changed from new to closed
  • resolution set to fixed

Fixed in changeset:5891

  Changed 4 years ago by MartinBudden

  • status changed from closed to reopened
  • resolution fixed deleted
  • milestone changed from 2.4.1 to 2.5

Reopened (changeset:5911) since this causes unnecessary wrapping of tabs in some themes.

  Changed 3 years ago by FND

  • owner changed from JeremyRuston to PhilHawksworth
  • status changed from reopened to new
  • milestone changed from 2.5 to 2.4.2

  Changed 3 years ago by EricShulman

When "unnecessary wrapping of tabs in some themes" occurs, it is most typically in the #sidebarTabs area, where the width is already very limited.

The problem is that, although the default CSS styles for the sidebar currently allow the browser to perform word wrapping, the sidebar tabs don't appear to be wrapped because each tab's text is immediately adjacent to it's neighbors, providing no intervening word breaks on which the browser can operate. In order to correct this, this ticket adds an invisible, zero-width space element in-between each tab, so that the browser's normal word-wrapping can actually occur.

Unfortunately, this exposes a flaw in the layout of the sidebar for some themes: the width of the sidebar was never wide enough to fit the tabs... but no one noticed, because the tabs couldn't wrap before, due to the aforementioned whitespace issue.

Fortunately, the effect of this code change on the sidebar tabs can be easily neutralized by adding just one extra line of CSS to core's shadow StyleSheetLayout?:

#sidebarTabs .tabContent { white-space:nowrap; }

When people upgrade to the new core release, this CSS change will be applied alongside any custom-defined CSS they may be using, which is unlikely to have been changing the white-space attribute of the sidebar, so it should be a painless upgrade (at least for this feature).

Although there might be an occasional instance where this CSS tweak isn't sufficient, the ability to allow tabs to wrap should take precedence, so that authors who need the flexibility to control the layout of their own tab content are able to do so.

Changed 3 years ago by PhilHawksworth

Patch to StyleSheetLayout? for fix to ticket 657

  Changed 3 years ago by PhilHawksworth

  • status changed from new to assigned

CSS only fix applied. Changes to StyleSheetLayout?. Tested OK in FF3, Safari3.2, IE7, IE6

  Changed 3 years ago by MartinBudden

  • status changed from assigned to closed
  • resolution set to fixed

fixed in changeset:8039

follow-up: ↓ 10   Changed 3 years ago by FND

  • status changed from closed to reopened
  • resolution fixed deleted
  • milestone changed from 2.4.2 to 2.5.1

Reverted in changeset:8233

The pure-CSS solution introduced in changeset:8039 had unexpected side-effects - in particular, the sidebar's More tabs wrapped onto two lines.

in reply to: ↑ 9   Changed 3 years ago by EricShulman

The pure-CSS solution introduced in changeset:8039 had unexpected side-effects - in particular, the sidebar's More tabs wrapped onto two lines.

When I first investigated various ways of enabling tab wrapping, I tried numerous CSS-only solutions. Some worked better than others, but none worked properly in all circumstances (and I'm only talking about standard documents with typical layouts). Notably, as with the most recent CSS-only attempt, the sidebar tab wrapping issue kept showing up under various odd circumstances, depending upon subtle changes in font metrics, window sizes, etc.

In addition, all the CSS solutions were relatively complicated and involved careful use of combinations of attributes (floats, alignments, etc). This makes the CSS solutions very "brittle" and does not allow for much (if any) customization by TW authors, as even a very small variation in the CSS seems to prevent the desired wrapping behavior from being properly applied.

To avoid all these CSS stumbling blocks, I came up with another approach (the one proposed in this ticket): let the browser's own, non-CSS word-wrap logic take over, simply by inserting an intervening whitespace DOM element in between each tab, while also hiding the whitespace elements from the display in order to preserve the current tab appearance and spacing.

... and, to great relief, every test that had previouly showed problems with the CSS-only solutions seems to work exactly as intended! Of course, this did not prevent the sidebar tabs from wrapping (as noted previously, those tabs simply do not fit in the available space of default layout... a fact that is only apparent once wrapping is enabled). Thus, the addition of the sidebar-specific CSS to set whitespace:nowrap so that the sidebars are unaffected by the new DOM-element induced wrapping.

Interestingly, this same CSS, when applied on top of any of the previously-attempted CSS only solutions did not correct the sidebar wrapping problem. In this last case, because a DOM-element based solution is used to trigger the tab wrapping, the sidebar nowrap CSS does work, because there is no complex underlying CSS rules to be overridden.

note: while adding a DOM element to affect word-wrapping might seem like an in-elegant solution, it is actually the most straightforward and reliable means to achieve this result, as it relies upon well-established, fundamental HTML rendering logic rather than extended CSS rendering logic which clearly has subtle variations in implementation and effect that are much more difficult to understand and control.

In addition, this approach has been extensively field-tested via  http://www.TiddlyTools.com/#CoreTweaks, and has been used in the TW community for over 7 months without any reports of tab wrapping problems.

I think that all of the above should provide sufficient justification for implementing the DOM-element based solution without further experimentation. Of course, if a successful CSS-only solution is identified at a later date, we can always create a new ticket (or re-open this one) in order to further refine the implementation for some future release.

follow-up: ↓ 12   Changed 3 years ago by PhilHawksworth

I'm unable to reproduce this issue in: FF2/FF3 on Mac OSX Safari v3.2.1 on Mac OSX IE6 on Win XP IE7 on Vista Chrome on Vista

I've tried resizing the fonts ans window in the browser but to no avail. Could anyone provide more info on how to reproduce this?

With regards to the approach for fixing the issue, I'm really keen to do this with CSS and not by artificially injecting characters into the markup and then hiding them with CSS. Even though Eric has had success with this approach, I think that it is a practice that we should try to avoid if we can. Separation of style and content is desirable, right?

I'm happy to pursue a CSS fix for this. I'm confident that it is the correct approach. If I can just reproduce the issue, I'll crack on.

in reply to: ↑ 11 ; follow-up: ↓ 13   Changed 3 years ago by EricShulman

I'm happy to pursue a CSS fix for this. I'm confident that it is the correct approach. If I can just reproduce the issue, I'll crack on.

While I concur that 'separation of style and content' is generally a good goal, it shouldn't be treated as an absolute rule... and in this particular case, the added space elements are not being used to define the *style* of the tabs; rather, they should be viewed as additional semantic *content* that tells the browser to handle each tab as a separate word that then permits a CSS-based *style* definition using standard, trivial-to-implement "white-space:wrap" or "white-space:nowrap" CSS declarations to be correctly applied in a robust, cross-browser compatible fashion.

It's my assertion that continuing to search for a CSS-only solution is a dead-end effort, and here's two reasons why:

  • Based on numerous CSS experiments, I have found that there *are* definitely cross-browser inconsistencies in handling for word-wrapping that seem to be related in very subtle ways to font-metric round-offs or other small (few pixel) platform-specific differences. Unfortunately, as you've already discovered from your own attempts, these differences can trigger unintended wrapping of tabs and, even though it can be hard to reproduce the problem, it is a persistent problem that continues to re-appear unexpectedly (and usually just after find what seems to be a workable solution :-(
  • Even if you manage to reproduce the problem consistently and find a solution for that particular case, I'd still have concerns about other CSS oddities that might still be lurking about. In addition, if a reliable CSS-only solution can be found, I suspect that it will be somewhat complex, and thus relatively hard for TW authors to work with, as complex CSS rules can be somewhat 'brittle' and break easily, especially when inheriting styles from surrounding custom CSS class definitions that may set white-space and word-wrapping CSS styles.

in reply to: ↑ 12 ; follow-up: ↓ 14   Changed 3 years ago by PhilHawksworth

Replying to EricShulman:

While I concur that 'separation of style and content' is generally a good goal, it shouldn't be treated as an absolute rule...


OK, but every little helps and we should try not to keep taking small steps away from best practices if we can help it. I think this is doable.

and in this particular case, the added space elements are not being used to define the *style* of the tabs; rather, they should be viewed as additional semantic *content* that tells the browser to handle each tab as a separate word that then permits a CSS-based *style* definition using standard, trivial-to-implement "white-space:wrap" or "white-space:nowrap" CSS declarations to be correctly applied in a robust, cross-browser compatible fashion.


This would mean that a space means "you can wrap here" (or not, depending on our CSS) so how would these 3 tabs behave?:

tab one tab two tab three



Unfortunately, as you've already discovered from your own attempts, these differences can trigger unintended wrapping of tabs and, even though it can be hard to reproduce the problem, it is a persistent problem that continues to re-appear unexpectedly (and usually just after find what seems to be a workable solution :-(


Well, I haven't discovered this really. I can't seem to reproduce the issue. If anyone can reproduce it, perhaps I can put a little effort into a attempting a fix. It may involve rewriting the CSS for the tabs as a whole, but nested tabs are pretty common on the web these days. I'd be surprised if a CSS solution didn't exist.

In addition, if a reliable CSS-only solution can be found, I suspect that it will be somewhat complex, and thus relatively hard for TW authors to work with, as complex CSS rules can be somewhat 'brittle' and break easily, especially when inheriting styles from surrounding custom CSS class definitions that may set white-space and word-wrapping CSS styles.

I actually hope that the correct solution might be rooted in simplification rather than in adding complexity. I'm perhaps being naive. ;)

in reply to: ↑ 13 ; follow-up: ↓ 15   Changed 3 years ago by EricShulman

This would mean that a space means "you can wrap here" (or not, depending on our CSS) so how would these 3 tabs behave?: {{{ tab one tab two tab three }}}

The CSS for the content *inside* the tabs is different from the CSS for the tabset itself, so you can easily write the following trivial rules so the tabs will wrap as needed, while content inside the tabs will not:

.tabset { white-space:wrap; } .tab { white-space:nowrap; }

I actually hope that the correct solution might be rooted in simplification rather than in adding complexity. I'm perhaps being naive. ;)

nah... just really, really optimistic... after all, this *is* CSS we are talking about!

in reply to: ↑ 14   Changed 3 years ago by PhilHawksworth

Replying to EricShulman:

The CSS for the content *inside* the tabs is different from the CSS for the tabset itself, so you can easily write the following trivial rules so the tabs will wrap as needed, while content inside the tabs will not:


Oh, of course! You're quite right about that.

nah... just really, really optimistic... after all, this *is* CSS we are talking about!

Ha! But I love CSS in spite of its trickiness (I think I might be one of the few who does).

Ok. I think that there is more value in just getting this fixed than debating it for ages. Given that there is a bug that I am struggling to reproduce, and a fix that you have already implemented, I think we should go with your fix.

  Changed 3 years ago by MartinBudden

  • owner changed from PhilHawksworth to EricShulman
  • status changed from reopened to new

  Changed 3 years ago by MartinBudden

  • milestone changed from 2.5.1 to 2.5.2

  Changed 3 years ago by FND

What's the status here - hasn't this been solved already?

  Changed 3 years ago by FND

  • milestone changed from 2.5.3 to 2.5.4

  Changed 2 years ago by MartinBudden

  • status changed from new to closed
  • resolution set to fixed

fixed in changeset:11455

  Changed 9 months ago by RainBow

Yes, hasn't this been resolved already?

Ok. I think that there is more value in just getting this fixed than debating it for ages. Given that there is a bug that I am struggling to reproduce, and a fix that you have already implemented, I think we should go with your fix.

I agree. There's no point in carrying this argument for too long. It's not like we're writing an  essay or anything. Too much rhetorics here.

  Changed 8 months ago by SaraFord

There are lots of articles but this one is really inventive!I hope that there will be a kind of continuing of it.I will <a href=" http://www.professay.com/?page=buy_essay">buy essay</a> on this topic.

Note: See TracTickets for help on using tickets.