Search code examples
cssepubepub3

How to prevent @media from breaking the parsing of the CSS file on some Kobo EPUB readers?


I am working on the styling of an EPUB 3 file.

I have a CSS containing a @media query.

@media (min-width: 460pt) {
    aside {
        float: right;
        max-width: 40%;
        margin: 10pt 0 10pt 15pt;
    }
}

When rendered in a browser context or Calibre, it works as expected. But on a Kobo Clara HD, this breaks the CSS file; the rules are not loaded at all.

After removing the @media query, the CSS file works again. So the problem is isolated to this feature.

I have tried to put the @media in another file and use an @import. Results: the main CSS is not broken anymore; but the issue is, in contexts where @media works, the rules are not in the right order, so the applied rule is not the one I want. Put in other terms, the @media rule MUST come between the main rules regarding the element I want to style, but because the @import rule MUST be defined first as per the CSS specifications, so it does not fit my requirements.

  • Well, I may theoretically deconstruct my main CSS file in 3 files (the beginning, the media, the rest), called each with an @import, but this seems excessive; I would need to break the main CSS file everywhere a @media rule has been added.
  • I cannot use !important, because subsequent rules in the main file reset some rules which are in the media.

Regarding @supports, I didn't find any @supports rule for checking if @media rules are supported. I have tried the following:

@supports selector(div) {
  /* The same rules from the previously shown code block. */
}

It makes the main CSS file work, because @supports selector(...) is still experimental nowadays (Nov. 2023) and unsupported on my Kobo. But what it demonstrates: we can have a way to disable the @media rule block with @supports.

Are there any workaround?


Solution

  • This is because, for Kobo ereaders, advanced CSS features are loaded for .kepub.epub files and not .epub files. The .epub files are rendered with a broken (or simplistic) implementation of CSS.

    Simply change the extension of the file to .kepub.epub, and the stylesheet won't fail due to @media.

    Don’t use Calibre to transfer the file; or else Calibre will change back the extension to .epub, so it’s better to copy the file directly to the storage. If you really want to use Calibre, install KoboTouchExtended, a Calibre's third party extension.

    After this change, other unsupported CSS features will also start working, such as :not and ::before / ::after. This will also make the footnotes preview work (as long as the implementation in the file is correct).

    To distinguish between EPUB and KEPUB files loaded on a Kobo Clara HD, in the ebook list, you will find next to the book title the file type:

    • .epub files are noted as “EPUB”
    • .kepub.epub as “KOBO EPUB”.