Kalan's Blog

Software Engineer / Taiwanese / Life in Fukuoka

Current Theme light

Today I went to check out the Svelte source code, familiarizing myself with its architecture while also looking for any simple issues to practice on. And then I came across this - emits warning.

Although I think, based on the description of this issue, an a tag without an href should be considered invalid (at least not compliant with a11y). Later, I looked it up and found that there are some inconsistencies in the current specifications mentioned on StackOverflow.

However, in essence, href can be empty, but in this case, it is recommended to use a button or similar tags instead of a for better screen reader compatibility.

Later, I checked eslint-plugin-jsx-a11y and found that this eslint plugin helps to determine whether the href is a valid value. The following are considered invalid values:

<a onClick={foo} /> // can be replaced with button
<a href="#" /> // only # without an id
<a href={"#"} /> // literal value
<a href={`#`} /> // literal value
<a href="javascript:void(0)" /> // should not use javascript:void(0)
<a href={"javascript:void(0)"} /> // literal value
<a href={`javascript:void(0)`} /> // literal value

There are also cases where href is empty:

<a />
<a href={undefined} />
<a href={null} />

Svelte checks basic a11y issues for you, such as missing href or invalid href values, because Svelte itself goes through a compilation phase, making these checks during the compilation stage:

// compiler/compile/nodes/Element.ts
// L425
		if (this.name === 'a') {
			const attribute = attribute_map.get('href') || attribute_map.get('xlink:href');

			if (attribute) {
				const value = attribute.get_static_value();

				if (value === '' || value === '#') {
					component.warn(attribute, {
						code: `a11y-invalid-attribute`,
						message: `A11y: '${value}' is not a valid ${attribute.name} attribute`
					});
				}
			} else {
				component.warn(this, {
					code: `a11y-missing-attribute`,
					message: `A11y: <a> element should have an href attribute`
				});
			}
		}

At this stage, Svelte converts the syntax into an abstract syntax tree (AST), making the checks convenient.

However, upon closer inspection, huh? The case of javascript:void(0) seems to have been missed. Currently, it only handles cases where the value is empty or #. So I added a check: if (value === '' || value === '#' || /^\\W*javascript:/.test(value)) and submitted a Pull Request.

Another thing worth noting is that Svelte currently only checks for values that are is_static, so for cases like:

<a href={undefined} />
<a href={null} />
<a href={`#`} />
<a href={"javascript:void(0)"} />
<a href={`javascript:void(0)`} />

Because the content inside {} is an expression, Svelte cannot detect it (it marks is_static as false). To check these cases, additional handling is required for these expressions. I will fix them all when I have time (the Golden Week is coming up).

It doesn't seem like a very useful feature, to be honest. Since it is done during the compilation phase and doesn't affect the bundle size, I'm starting to feel that the compiler approach is feasible. You can write code in whatever way you prefer, and as long as it compiles to JavaScript, it's all good.

Although this is not a new idea, similar concepts can be found in languages like LiveScript or Elm, to some extent. However, I think the reason why Svelte has gained attention (or is more easily adopted) is that it retains most of the JavaScript syntax, making the template learning curve almost zero (if you know React or Vue). It feels like writing HTML, CSS, and JavaScript together, just like Vue.

Another advantage is Svelte's reactive mechanism and animation control, which are often important considerations when implementing front-end interfaces and are not easily provided by other compilers. Everyone wants functional programming, but in reality, if it doesn't solve the developers' real problems, it remains a pursuit of a few enthusiasts.

Prev

How to record video using XCode Simulator

Next

How to bring Github Actions to your project

If you found this article helpful, please consider buy me a drink ☕️ It'll make my ordinary day shine✨

Buy me a coffee

作者

Kalan 頭像照片,在淡水拍攝,淺藍背景

愷開 | Kalan

Hi, I'm Kai. I'm Taiwanese and moved to Japan in 2019 for work. Currently settled in Fukuoka. In addition to being familiar with frontend development, I also have experience in IoT, app development, backend, and electronics. Recently, I started playing electric guitar! Feel free to contact me via email for consultations or collaborations or music! I hope to connect with more people through this blog.