Settings

Theme

Show HN: Marginotes, quick and elegant side notes for your paragraphs

github.com

111 points by Stately 10 years ago · 30 comments

Reader

lolc 10 years ago

Looks nice!

I was a little surprised at the last line in your code:

window.jQuery.prototype.marginotes = window.$.prototype.marginotes = marginotes

Last I checked (one minute ago) jQuery and $ refer to the same object. jQuery === $ unless somebody is using $ to refer to something else in which case thanks you just clobbered $'s prototype. You should follow the jQuery conventions https://learn.jquery.com/plugins/basic-plugin-creation/

Chris_Newton 10 years ago

Notes on web pages are tricky because there are so many edge cases, and they tend to expose the limitations of our current HTML+CSS model.

For example, we can achieve an effect similar to the one shown here using just CSS (no JS) if we’re able to use position:relative on the containing paragraph without breaking anything else in the styling:

HTML:

    <p class="note-container">This is some text with a <span class="note" desc="Style me!">marginal note</span>. Lorem ipsum dolor sit amet...</p>
CSS:

    .note-container {
      position: relative;
      width: 400px;
    }
    
    .note {
      text-decoration: underline;
    }
    
    .note:hover::after {
      content: attr(desc);
      position: absolute;
      top: 0;
      left: 440px;
      width: 150px;
      height: 100%;
      border-left: 1px solid black;
      padding-left: 9px;
    }
I put a quick demo of this one here:

https://jsfiddle.net/2ejk2who/

However, what happens if we need to work with touch-only devices, where hover effects aren’t available? Two options would be to show the notes all the time, or to embed a hidden checkbox and make the anchor text its label. In the latter case, tapping on the text could then toggle whether the marginal note appears if we used something based on :checked instead of :hover.

But now what if more than one note is set to visible at once? We can’t combine the position:absolute technique to get neat alignment at the top of the paragraph with using floats so multiple notes automatically fall under one another. I don’t have a good pure-CSS answer for this one.

In any case, on a smaller screen we might not want to show marginal notes alongside the main text anyway. It would be helpful if there were a way to have the notes drop underneath the paragraph and stack up, but again, we can’t combine the kind of absolute positioning that would place a note there with something that extends the paragraph’s box so later content moves down after any visible notes.

Perhaps one day we’ll have more flexible options for generated content and CSS positioning that will let us do these things, but for now the only ways I know to achieve some of these effects still rely on JS.

mshenfield 10 years ago

I made a little experiment, and converted this to a vanilla Javascript library. Relevant to some of the questions below about whether this should use jQuery or not.

Edit: There were two gotchas beyond browser compatibility. jQuery provides a consistent interface to set numeric style values - in vanilla Javascript you have to remember to turn these numbers into strings suffixed with "px". And I hacked together the code that stops fadein and fadeout from stepping on each other.

Changes: https://github.com/fdansv/marginotes/pull/2 Working Example: http://mshenfield.github.io/fdansv.github.io/

  • cornstalks 10 years ago

    Looks like you've got a bug when the mouse passes over a link that has no sidenote. To reproduce:

      1. Hover over a link with a sidenote (i.e. "Bill Gates").
      2. Hover over a link without a sidenote (i.e. "unrecognised").
      3. Move your mouse off of the link.
    
    During step 3 the previous sidenote will briefly appear.

    (I'm running Chrome 48.0.2564.116 on OS X 10.11.3 if that matters)

    • mshenfield 10 years ago

      Nice catch! My fadeout function mistakenly set the opacity to 1 to start off. Fixed.

kozak 10 years ago

Very nice. It would be even better if it had some CSS media query-based fallbacks for the case when the page is being printed. And yes, jQuery should not be a requirement.

joeclark77 10 years ago

This is excellent. I've been thinking about rolling my own blog software since Medium took away their marginal note feature (IIRC, you can now make notes but they're for yourself only, readers can't see them). Since reading Ed Tufte's books, I'm convinced that margin notes are infinitely better than footnotes or (egad) endnotes for sharing little "extras" with your readers.

tauchunfall 10 years ago

Mouse-over actions are nice on desktop. But what happens if I use a touch device?

  • Mahn 10 years ago

    Tap to show, tap to hide? Not quite the same, but that's how I'd do the fallback for mouse hover effects.

DenisAyumu 10 years ago

Last time I checked you couldn't add HTML properties that don't exist. It's not valid HTML code. The exception are "data-*" properties. So the HTML markup should be <span data-desc="whatever">whatever</span>.

gkya 10 years ago

What happens if I have JavaScript disabled (and I do have)?

  • dspillett 10 years ago

    > and I do have

    So you can tell us: what happens if you have Javascript turned off?

    I have sympathy for the "what happens if I'm using a screen reader or other accessibility device" question, not excluding those who need to use assertive technologies where possible is important. geocar's post below suggests what might be a better implementation in that regard, which will support your use case too, but some advanced screen readers might try run the script (to access generated content like Google does for indexing) and then not read the text because said code has hidden it via DOM manipulation, meaning the technique might not work in all cases.

    But disabling all javascript and expecting the world to support your preference in everything we produce (you can at least read be core content in this case) feels a bit entitled IMO, along the lines of people/companies (who I deal with in my day job) who use legacy browsers and are upset when that means they can't have shiny new features in the browser based applications that they use (or want to use).

    I understand the desire to block all the iffy JS (adverts, particularly adverts that eat CPU cycles and therefore my battery when mobile, tracking, and so on) and I understand that running noscript or similar plugins is too cumbersome in many opinions, but unless you are paying for the content in some way you can't really expect to demand to control how it is delivered to you.

    A thought for reducing tracking and such without blocking code used for page functionality: I'd like to see browsers block 3rd party code as an option (as some do for 3rd party cookies), with a whitelist to enable CDNs (possibly with the major CDNs on the whitelist by default). That would still allow iffy code if it is served from the same site (by design or because it has been hacked) so isn't perfect, but it might be a good compromise.

    • gkya 10 years ago

      I disable javascript for two reasons: I do not want to download megabytes of useless scripts everyday dozens of times, and I do not want to allow strangers run arbitrary Turing-complete code on my computer, even on a restricted platform like the browser. Thus, I use xombrero + very strict whitelisting. I do not want the world to conform to me, I just conform selectively. I know the consequences of being a NoJS surfer, I just live with it, and don't complain. I even have chromium installed for edge cases.

      And here I try to make some criticism of the posted work, and constructively. I think coding defensively for the noscript case is a good, important practise, even if the chosen remedy is to show up a "please enable JS" message. And then there's the case of printing the page, the read-it-later things, archival, etc... I can't run JS on paper, or on PDFs, right? But the WWW is ephemeral, and if something is important, I have to archive. And people have disablities, how would margin notes be readable with say 5x zoom? How will a disabled person get to read the popup margin note if he can't even move the mouse to hover the anchor tag? One may well say that disabled people are not worthy of seeing their content, and however disgusting may it sound they've the right to say so, but the OP may be open to such suggestions for inclusivity and improvement, and I suggest.

      I think the JS CDNs are the most stupid things on the world. It is a virus vector. Hack one CDN, and you'll get to run your code on maybe millions of websites. And who decides which CDNs are major, and/or better or more secure?

      • dspillett 10 years ago

        > I do not want the world to conform to me, I just conform selectively.

        A healthy attitude.

        > I know the consequences of being a NoJS surfer, I just live with it, and don't complain.

        I'm a bit more open with JS, though I've completely blocked flash for years. Any site that doesn't work just, well, doesn't work - I can always try others.

        > And here I try to make some criticism of the posted work, and constructively.

        I may have misread your short message as being much more "snarky" than you intended, in which case I apologise for my knee jerking in reaction.

        > I think the JS CDNs are the most stupid things on the world. Hack one CDN, and you'll get to run your code on maybe millions of websites

        Good point, and why I use local copies instead of CDNs myself. That and I prefer not to rely on an external resource unless I have to - it is an extra possible point of failure. The extra bandwidth use is insignificant from a hosting point of view and if you have caching directives set properly it'll only affect your users on first access (and you can often minimise that effect with careful lazy loading). But CDNs are an unavoidable consideration because every other man/woman/other and their dog seem to disagree.

        > And who decides which CDNs are major, and/or better or more secure?

        A thorny point. I would only include official locations of significant projects like code.jquery.com rather than anything more generic. I wouldn't even exclude ajax.googleapis.com from the "nothing generic" rule.

        • gkya 10 years ago

          Happy we mostly agree. Should've been more elaborate, sorry. I sometimes trade off elaboration for brevity and/or laconicism, which causes misunderstandings and off-topic threads.

          With regards to CDN, I guess the best option is to have a "standard library" for web, where the browsers provide a standard selection of javascript libraries, jquery, react (I really don't know what this last one is) and the like, and bootstrap and stuff, so that these need not be downloaded, and we can be sure that our copies are mostly secure (audited, tested) and that there's no real single point of failure.

          There's still a who decides problem with this approach, but at least I won't be able to steal millions of session cookies should I manage to tamper a single JS file on some domain. Tho I'm not a security person, so it's possible that I'm telling useless crap.

          • dspillett 10 years ago

            No, that is definitely a valid security concern if copies of code on CDNs are compromised. Though once you have code injected into something like that you can pretty directly do worse than take session cookies.

            One possibility would be to have everything signed and include the fingerprint with the <script> tag. That way you could safely read jquery.version.js from anywhere and be as sure it is the real thing as if you'd picked it up from jquery.com. That would in fact remove the need for a CDN - one that copy has been ready from my site and verified there would be no need to read it from your site, so every site that uses the signed version essentially becomes part of a global communal CDN. Of course then you have the hassle of certificate management (how do I trust the signature on that file?). The current infrastructure used for SSL certificates, for all its faults, would suffice, but getting library maintainers to use it might be a struggle.

            On further thought: in fact a digital signature may not be needed. Just a hash (and not even a salted one) using a sufficiently provably secure function may be adequate, as already provided by many download sites for verifying the absence of transmission errors, removing the need for any signature/certificate jiggery pokery.

  • onion2k 10 years ago

    You don't see anything.

    • gkya 10 years ago

      Which is bad if them notes are not ornaments only. So there should be some fallback. I guess a good approach would be to collect the content from some p.marginnote elements which would be hidden if JS is present and left intact if not. So, like

        <a href='#' mnref='gcc'>GCC</a>
        ...
        <p class='marginnote' mnname='gcc'>The GNU Compiler Collection</p>
      
      With JS, they'd become margin notes, whithout it, they'd render as plain footnotes.
      • geocar 10 years ago

        Why not just:

            <a href="#fn-gcc" class="has-footnote">GCC[1]</a>
            …
            <p id="fn-gcc" class="marginnote"><label>1. </label>The GNU Compiler Collection</p>
        
        It's compatible with the W3C recommended idiom for footnotes[2], is accessible without JavaScript, and you can still use `.marginnote` to provide CSS styling.

        [2]: https://www.w3.org/TR/html5/common-idioms.html#footnotes

        • gkya 10 years ago

          Well if this works it seems better, I'm mostly a user of hypertext so a bit ignorant, sorry.

      • onion2k 10 years ago

        Sure, but as the README.md states "adds notes to the margin with the text provided in HTML attributes" it's presumably left up to the user how else they display the data if they want it to be visible for people who disable JS. This library is a progressive enhancement. It's very much the right way to do web dev in my opinion.

        • NoGravitas 10 years ago

          It's almost the right way -- somewhat better would be to do what one of the above comments say, to add the notes as footnotes using POSH. Then the javascript can rewrite the footnotes into hide/show marginal notes with the same appearance and user interface as this library.

anacleto 10 years ago

Pretty. Thanks.

gberger 10 years ago

http://youmightnotneedjquery.com/

  • have_faith 10 years ago

    What do you consider a reasonable reason to build something as a jQuery plugin as opposed to pure-js? or do you believe jQuery plugins are redundant by default?

    Just interested.

    • jakejake 10 years ago

      I personally find it odd to create every component as a jquery plugin. To me, it makes more sense to write a plugin only when you're extending jquery core functionality itself in some way.

      As far as "extending" goes though, it's not always clear. Is a date picker extending jquery's core? I personally think not, but there has evolved an expectation that every web component must be initialized like so:

      $('#container').doSomething();

      So I suppose a lot of people do it that way just to have a familiar look to their API, or even just to show up in listing as a jquery plugin.

      • bobm_kite9 10 years ago

        Basically, this function is just an onMouseOver event, which then inspects the element and displays text from the "desc" tab in the right place.

        I've been thinking for a while that it would be nice if we could add events to the CSS syntax, something like:

        a[desc] { onMouseOver: asideFunction(); }

        I _kind_ of worry that this is subverting the purpose of the css, but since it also handles hover and selected behaviour, it seems like the line isn't well-drawn anyway as to where styling ends and where behaviour begins.

        What do other people think?

        • codingdave 10 years ago

          I think that would be mixing presentation with functionality in a way that would become a maintenance nightmare.

  • plugnburn 10 years ago

    I second this. JQuery must die.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection