The CSS :lang() selector targets elements within documents that do not specify a particular language

Can elements that do not have a language set or inherited, meaning they are in an unspecified ("unknown") language, be targeted?

Facts

The language of an HTML document or element can be specified using the HTML lang attribute, for example:

<html lang="en">
<h1>Dictionary</h1>
<dl>
<dt><abbr lang="en-Mors">-... - .--</abbr>
<dd><i lang="fr-Latn">à propos</i>
</dl>

or by including code(s) in the HTTP Content-language header:

HTTP/2 200 OK
[other headers]
Content-language: en,en-Brai,fr-Latn

<html>
<h1>Dictionary</h1>
[rest of document]

or using the deprecated, yet still functional <meta http-equiv> tag:

<html>
 <head>
  <meta http-equiv="content-language" content="en,en-Brai,fr-Latn">
</head>
<html>
<h1>Dictionary</h1>
[rest of document]

In all cases, the CSS selector :lang(en) would target the main heading and other elements with no explicit lang attribute set to "en".

Objective

If a document is sent without the Content-language HTTP header or <meta> element, and without a lang attribute, is it possible to target elements in the inevitable "unknown" language?

Furthermore, can the lang() CSS selector be used to match elements with an empty lang="" attribute, effectively opting out of having a language?

HTTP/2 200 OK
[no content-language header or meta present]

<html>
<p>I Want to select this. <span>And this.</span></p>
<p lang="">And this.</p>
<p lang="en">Not this. <span lang="">But this again.</span></p>

Methods that Do Not Work

Neither :lang(), :lang(unknown), :lang(''), nor :not(:lang(*)) work for this purpose. Selectors such as :not([lang]), [lang=''] would logically result in false negatives for scenarios involving the HTTP Content-language header/meta.

Answer Criteria

We are looking for an answer that either provides a solution without false negatives or confirms that it is impossible, with references to specifications (or their absence), along with an explanation of why this is the case.


Additional Notes:

When targeting the empty lang="" attribute, using the selector [lang=""] works, but may seem awkward given the dedicated :lang() pseudo-class for language-related selections.

Answer №1

Update 2021: After thorough investigation, this issue is now recognized as a bug here


We incorporate language range in the :lang() rule and they are compared against language tags. There have been mentions of supporting asterisks in language ranges:

Language ranges containing asterisks should be either correctly escaped or quoted as strings, for instance: :lang(*-Latn) or :lang("*-Latn") reference

In an old draft from 2013:

Each language range in :lang() must be a valid CSS identifier [CSS21] or consist of an asterisk (* U+002A) immediately followed by an identifier beginning with an ASCII hyphen (U+002D) for the selector to be valid. reference

However, I am unable to make p:lang(\*-US) work on Windows in Chrome and Firefox. While the rule p:lang(en\002DUS) functions correctly, p:lang(en\002D\002A) does not. The support for the special range "*" in browsers remains uncertain. Moreover, there is no indication of matching "undefined" with the special range "*" in Matching of Language Tags.


Nonetheless, p:lang(\*) and p:not(:lang(\*)) operate effectively on iPadOS across Safari and Chrome. Test it out on iPad by visiting this jsfiddle
https://i.stack.imgur.com/omNKB.png
It appears that chromium may lack complete support for the :lang() feature.


Solution: If utilizing a bit of JavaScript is feasible, consider the following workaround:

document.addEventListener('DOMContentLoaded', init);

function init() {
  if (!document.documentElement.lang) {
    fetchSamePageHeaders(checkHeaderLanguage);
  }
}

//make a lightweight request to the same page to get headers
function fetchSamePageHeaders(callback) {
  var request = new XMLHttpRequest();
  request.onreadystatechange = function() {
    if (request.readyState === XMLHttpRequest.DONE) {
      if (callback && typeof callback === 'function') {
        callback(request.getAllResponseHeaders());
      }
    }
  };

  // The HEAD method asks for a response identical to that 
  // of a GET request, but without the response body.
  //you can also use 'GET', 'POST' method depending on situation      
  request.open('HEAD', document.location, true);
  request.send(null);
}

function checkHeaderLanguage(headers) {
  //console.log(headers);
  headers = headers.split("\n").map(x => x.split(/: */, 2))
    .filter(x => x[0]).reduce((ac, x) => {
      ac[x[0]] = x[1];
      return ac;
    }, {});

  if (!headers['content-language']) {
    console.log('No language in response header. Marking the html tag.');
    let html = document.querySelector('html');
    html.lang = 'dummyLang';
  } else {
    console.log('The response header has language:' + headers['content-language']);
  }
}
p {
  margin: 0;
}

p[lang=""],
p:lang(dummyLang) {
  color: darkgreen;
  font-size: 2em;
}

p:lang(en\2dus)::after {
  content: '<= english';
  font-size: 0.5em;
  color: rebeccapurple;
}
<p>I Want to select this.</p>
<p lang="">And this.</p>
<p lang="en-us">Not this.</p>
<span lang='en-us'>
    <p>Also, not this.</p>
    <p lang="">But, this too.</p>
</span>


Here, JavaScript is used to determine whether the language is mentioned in the HTML tag or the response header. It assigns the language "dummyLang" to the HTML tag. Consider checking meta tags as well.
For a detailed explanation on retrieving HTTP headers in JavaScript and the advantages and disadvantages of this approach, refer to this discussion on Stack Overflow.

Answer №2

After brainstorming, I've devised a clever solution. Firstly, you can execute some JavaScript code to assign the "xyz" language attribute to all elements that do not have one. Then, you can target those elements using CSS...

document.querySelectorAll("p").forEach(e => {
  if (e.lang == "") e.lang = "xyz";
})
p:lang(xyz) {
  color: red;
}
<p>I Want to style this.</p>
<p lang="">And this.</p>
<p lang="en">But not this.</p>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Distribute divs of equal width evenly within a grid

I'm facing a unique challenge at the moment. I'm attempting to create a grid system where all elements have a fixed width of 200px each. What I envision is a clever grid setup using only CSS, where each "row" will strive to accommodate as many el ...

Any advice on how to horizontally center my css slideshow?

After using jsfiddle for the file, I encountered an issue with centering the slideshow at the bottom. Despite my efforts, it remains aligned to the left margin. Check out the end results here: https://jsfiddle.net/n6kae2rn/ https://jsfiddle.net/n6kae2rn ...

Tips for avoiding table column overlap during window resizing situations

My current issue involves using a table to present information. While resizing the window, I noticed that the columns in the table were overlapping. Below is the code snippet: <table style="width:100%;table-layout:fixed"> <tr style="border-bo ...

What is the best way to place an icon in the lower right corner of a design

I have encountered an issue while building the testimonial section below. The problem arises when the amount of text in each block is not the same, causing the quote icon to be displayed improperly in the bottom right corner. Sometimes, it even extends out ...

Tips for properly utilizing "require" in application.css with the Skeleton framework

I am currently working on implementing the skeleton-rails CSS framework into my application. Within the app/views/layouts/application.html.erb file, I have created containers and a list nav that require styling. Following the guidelines provided by the ske ...

Can JavaScript be utilized to dynamically adjust the size of all elements on the screen to a specified percentage of their initial height and width when a certain event occurs?

I'm fairly new to the world of JavaScript, but I have a basic understanding of it. I want to optimize my personal website for mobile devices. I've already taken care of screen orientation and element positioning, everything is centered nicely and ...

change the width of a div element to match that of its nearest sibling element

Can the width of a div be automatically set to match its closest sibling when the width is set to width: auto;? In my coding example on jsFiddle, you can observe three colored divs - red, green, and blue. I am aiming for the blue div to adjust its size ba ...

Cursor hovers over button, positioned perfectly in the center

I am facing a challenge with implementing a hover function for a set of buttons on the screen. The goal is to display the mouse pointer at the center of the button upon hovering, rather than the actual position of the cursor being displayed. I have tried u ...

Display text on the screen with a customized design using JavaScript's CSS styles

I need help with printing a specific page that contains some information designed in print.css. I want to print this page, including an image, with the same style. function printContent() { var divContents = document.getElementById("terms").innerH ...

Hover and hover-off functions in navigation menu

html <div class="hidden-nav"> <h4>lorem</h4> <ul class="decor-menu-list"> <li><a href="#">123</a></li> <li><a href="#">123</a></li> <li><a hre ...

Are there any resources available to ensure my jQuery script is compatible with multiple browsers?

After realizing that Internet Explorer does not support certain selectors in jQuery, I began to question how to ensure my code will function properly during the writing process. As a Linux user, my testing options are limited to Chrome and Firefox. Is ther ...

Struggling with converting my menu design into a dropdown menu

Recently completed creating my initial menu with a left navigation bar design. Wondering if it is achievable to implement a dropdown effect on hover without the use of javascript? I have come across several solutions but they do not seem to work for me, po ...

Adjust the parent element to match the width of the child by utilizing the "display: grid" property

edit: I'm uncertain if this is a duplicate issue. My concern is not about the background color extending beyond the container width, but rather about expanding the container to match the size of its child with display: grid. I have updated the example ...

Modify the color of drop-down menu links

Recently, I set up a drop-down menu containing links. Initially, when hovering over the names in the menu, they would change color and display the drop-down. I had successfully made all the names golden, with the hovering name turning black while display ...

Control the transparency of the initial parent div that includes an *ngFor loop

I want to add opacity only to the first div which contains an icon and a heading in another nested div. The second div should remain fully visible (opacity: 1). Here is the HTML structure: <div class="row clearfix"> <div class="col-lg-3 col- ...

Utilize CSS to position my image in the center on mobile devices with responsive design

I am having an issue with the responsiveness of my logo image on my website's showcase section. Currently, the image is only showing up in the left corner on mobile devices, and I want it to be centered. Below is my HTML code: <section id="showca ...

What is the best way to add data from an array to a DOM element in the same order it was retrieved from Firebase?

Utilizing Google Firebase Firestore for data storage and the Open Movie Database (OMD) in combination with Axios to retrieve movie information. I am currently developing a website that allows users to add movies to collections. On the collections page, al ...

Transforming CSS with React Router Links

Why is my CSS being significantly altered by the React Router Link? Is there a way to prevent the Link from affecting the styling? Without Link: With Link: This is the code for the Link. It does not have any style properties. <Link to={`/link/${i ...

Enhancing Your Website with Animation Delay using Animate.css and ViewportChecker

I am attempting to apply a delay to various elements with animated classes on a specific webpage using animate.css version 3.5.1 by Daniel Eden and jquery-viewport-checker version 1.8.7 by Dirk Groenen. My initial approach was to utilize the setTimeout fu ...

The mystery of the Accordion Effect: A Next.js/React.js issue where it slides up but refuses to

After implementing a custom accordion using next.js, I encountered an issue where the slide animation worked successfully when moving up and out upon clicking the button. However, when trying to move it back down into the content, it did not animate as exp ...