How to conditionally attach a stylesheet to a page, preventing anonymous users from getting a cached version? I'd like to create a module capable of overriding some of the theme's css (for any theme). Think of small things like hiding the image, changing font sizes and colors, etc.

My initial thought was to toggle this using a session variable:

/**
 * Implements hook_library_info_build().
 */
function my_module_library_info_build() {
  $libraries = [];
  $libraries['override'] = [
    'version' =&gt; '1.0',
    'css' =&gt; [
      'base' =&gt; [
        'override.css' =&gt; [],
      ],
    ],
  ];
  return $libraries;
}

/**
 * Implements hook_preprocess_HOOK().
 */
function my_module_preprocess_page(&amp;$variables) {
  if ($_SESSION['override']['enabled']) {
    $variables['#attached']['library'][] = 'my_module/override';
  }
}


This works very well for logged in users, but for anonymous users it only caches the first version of the page (using the status of $_SESSION['override']['enabled'] at that time). So some pages show the regular lay-out, and some only show the overridden version.

I realized that I probably have to add a cache tag, so I tried adding

$variables['page']['#cache']['tags'][] = 'override:' . $_SESSION['override']['enabled'];


Assuming this would allow 2 versions of the page to be cached, either for override enabled or disabled. But that does not work either. 

What needs to be done to allow multiple versions of the same page to be cached and served, depending on a $_SESSION variable?
Related: Cache context drupal don&#39;t work.

But your logic is actually depending on the session, and the internal page cache is disabled automatically for users with a session.

So it is more likely that you are having a problem with the dynamic page cache.

Your problem is that cache tags are not about caching multiple variations. They are about invalidating already cached things when something changes. So if you have configuration which override value should load which value, then you'd need a cache tag for that, so you can invalidate it when that happens. Also in 95%+ of the cases, you don't need to make up your own cache tags, but just use the default cache tags for entities, config objects and so on.

What you want is a cache context, either the default 'session' or make your own, that doesn't vary for the whole session content but only your key, whould is more efficient. See https://www.drupal.org/docs/8/api/cache-api/cache-contexts

And you should also read https://www.drupal.org/docs/8/api/render-api/cacheability-of-render-arrays to understand when you need cache tags, contexts, ..