A simple and super lightweight web component to create block links.
<script
src="https://unpkg.com/@alangdm/block-link?module"
type="module"
></script>
<block-link main-link="h2 a">
<small><a href="#date">Date: 2020/01/01</a></small>
<h2><a href="#header">Header</a></h2>
<p>Some content</p>
<footer><a href="#footer">Footer link</a></footer>
</block-link>
Have you ever set a link on a whole section of your web app like this?
<a href="/some-link">
<div>
Some content maybe with an image
<img src="/some-image.png" />
</div>
</a>
If you have, you probably have noticed that while this is super simple, it has a couple of issues:
- You can't select the text inside this div
- The accessibility is bad, keyboard navigation and screen readers don't work well with this
And even if you want to solve this either with pure HTML/CSS or adding some JS you might new problems like:
- Links added to children of the section might not work
- Using this for many parts of your app might get confusing and hard to maintain
This component solves all those problems
and you can use it like you would use a plain old <div>
.
This component's code is mostly an adapted version of the code in the article "Block Links: The Search for a Perfect Solution" by Vikas Parashar (@vicode_in).
There are only slight differences in the core behavior of both implementations so if you want more insight on the thought that went into this code to prevent the problems mentioned above please give Vikas's article a read.
npm i @alangdm/block-link
Import the component in your JS files
import "@alangdm/block-link";
You can use a CDN like unpkg or Pika CDN too
In your HTML files
<!-- example from unpkg -->
<script
src="https://unpkg.com/@alangdm/block-link?module"
type="module"
></script>
Or in your JS files
import "https://unpkg.com/@alangdm/block-link?module";
Basically, just use it as if it was a <div>
, all the magic will happen automatically! 🎉
<block-link>
<h2><a href="#header">Main Link</a></h2>
<p>
Some Text
</p>
<footer><a href="#footer">Footer link</a></footer>
</block-link>
By default, the first <a>
element inside the block-link component will be used as
the link that gets triggered when a user clicks on any place that's not another link.
You can add the main-link
(or mainlink
) attribute to customize which element is used as the main link.
The value has to be a selector relative to the parent <block-link>
that can be used to identify the <a>
that will be your main link.
<block-link main-link=".main-link">
<h2><a href="#header">This won't be the main link</a></h2>
<p>
Some text
</p>
<footer>
<a class="main-link" href="#footer">This will be the main link</a>
</footer>
</block-link>
In this case we used the .main-link
class selector to identify our main link,
but we could have also used footer>a
or even a[href="#footer"]
.
Any selector works as long as it serves as a unique identifier for the link.
You can use <block-link>
s inside of other <block-link>
s, they can even be the main link.
<block-link main-link=".child">
<block-link class="child" main-link="#link">
<img src="/some_image.png" />
<a href="#main_link" id="link">This will end up being the main link</a>
</block-link>
<p>Some other content. It might have <a href="#other">other links</a></p>
</block-link>
This component's only style is display: block;
but you can customize both
the component and its children behave with plain CSS.
block-link {
width: 200px;
height: 200px;
border: 1px solid black;
}
block-link h2,
block-link a {
color: purple;
}
block-link a {
text-decoration: none;
}
This would look something like this in action (Go here if you can't see this properly ):
import "./index.js";
This will only work if you're viewing it at the demo/docs site.
Footer DataThis component works as-is on all evergreen browsers (Chrome, Safari, Edge, Firefox). 💪
This component doesn't support any IE variation, however, due to it's nature, it will degrade gracefully on IE so that the markup and styles display properly just without the block link behavior, for example, clicking on links will work but clicking on the rest of the component won't.
- "Block Links: The Search for a Perfect Solution" by Vikas Parashar (@vicode_in)
- "Block Links are a Pain and Maybe just a Bad Idea" by Chris Coyier
- "Cards" by Heydon Pickering
- "Block Links, Cards, Clickable Regions, Rows, Etc." by Adrian Roselli
- "Pitfalls of Card UIs" by Dave Rupert
Created with WebComponents.dev