The <script> Element
As defined in the HTML Living Standard, the <script> element allows authors to include dynamic scripts and data blocks in their documents. The element either contains scripting statements or points to an external script file using the src attribute.
<script>
console.log("Internal script execution.");
</script>
The <script> tag can be placed in either the <head> or the <body>, depending on when you want the logic to execute.
Performance & Accessibility: Async vs. Defer
The way a script is loaded can significantly impact the perceived performance and accessibility of a page.
- Normal: The browser stops parsing the HTML until the script is fetched and executed. This can cause the page to appear "frozen."
async: The script is fetched in the background but executes immediately once it's ready, potentially interrupting HTML parsing.defer: The script is fetched in the background and only executes after the HTML is fully parsed. This is generally preferred for accessibility as it ensures the page content is available to the user as quickly as possible.
<script src="analytics.js" async></script>
<script src="ui-logic.js" defer></script>
WCAG and Script-Generated Content
If your script dynamically generates content or changes the state of the UI, you must follow specific accessibility rules.
WCAG Requirement: Name, Role, Value
Success Criterion 4.1.2 (Level A): For all user interface components, the name and role can be programmatically determined...
When using scripts to create custom widgets (like a custom dropdown or a carousel), the script must manage the ARIA roles and states manually. For example, if a script toggles a menu, it should update aria-expanded="true/false" so screen reader users are notified of the change.
Security & Integrity
Modern standards provide attributes to ensure that scripts are loaded securely and haven't been tampered with.
integrity: Uses a cryptographic hash (Subresource Integrity) to verify that the external script file matches what the developer intended.crossorigin: Handles how the browser requests scripts from different domains, helping to prevent certain types of data leaks.- Content Security Policy (CSP): While not an attribute, a strong CSP header can prevent "inline" scripts from executing, mitigating Cross-Site Scripting (XSS) attacks.
<script src="https://cdn.example.com/lib.js"
xintegrity="sha384-..."
crossorigin="anonymous">
</script>
Best Practices
- Progressive Enhancement: Build core functionality with HTML/CSS first, then use
<script>to add layers of enhancement. - Provide Fallbacks: Use the
<noscript>element to provide alternative content or instructions if the script fails to load or the user has disabled scripting. - Keyboard Focus: When scripts move focus (e.g., opening a modal), ensure the new focus target is logical and that the user isn't trapped.
A11y Tip: Reducing Motion
If your script handles animations, use the window.matchMedia('(prefers-reduced-motion: reduce)') query to detect if a user has requested minimal movement, satisfying WCAG SC 2.3.3 (Animation from Interactions).