Build a Book Inventory App - Build a Book Inventory App

Tell us what’s happening:

Book Inventory App tests fail due to strict CSS attribute selector and text content syntax issues.

I’m working on the Build a Book Inventory App, and I’m stuck on several core tests, even after implementing known non-standard fixes discussed in the community (like avoiding the > combinator and ensuring explicit tag names for rating dot styling). I believe my code is fully compliant with CSS standards, but I suspect the underlying test logic has extremely rigid, non-standard requirements.

Your code

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Book Inventory</title>

    <!-- Link to the external CSS file -->

    <link rel="stylesheet" href="styles.css" />

    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" />

</head>

<body>

    <h1>Book Inventory</h1>

    <table>

        <thead>

            <tr>

                <th>Title</th>

                <th>Author</th>

                <th>Category</th>

                <th>Status</th>

                <th>Rate</th>

            </tr>

        </thead>

        <tbody>

            <!-- Read, 3 Stars -->

            <tr class="read three">

                <td>The Midnight Library</td>

                <td>Matt Haig</td>

                <td>Fiction</td>

                <td><span class="status">Read</span></td>

                <td><span class="rate three"><span></span><span></span><span></span></span></td>

            </tr>

            <!-- To Read, No Rate -->

            <tr class="to-read">

                <td>The Power of Habit</td>

                <td>Charles Duhigg</td>

                <td>Non-Fiction</td>

                <td><span class="status">To Read</span></td>

                <td><span class="rate"><span></span><span></span><span></span></span></td>

            </tr>

            <!-- In Progress, No Rate -->

            <tr class="in-progress">

                <td>Dune</td>

                <td>Frank Herbert</td>

                <td>Sci-Fi</td>

                <td><span class="status">In Progress</span></td>

                <td><span class="rate"><span></span><span></span><span></span></span></td>

            </tr>

            <!-- Read, 1 Star -->

            <tr class="read one">

                <td>Crime and Punishment</td>

                <td>Fyodor Dostoevsky</td>

                <td>Classic</td>

                <td><span class="status">Read</span></td>

                <td><span class="rate one"><span></span><span></span><span></span></span></td>

            </tr>

            <!-- Read, 2 Stars -->

            <tr class="read two">

                <td>Educated</td>

                <td>Tara Westover</td>

                <td>Memoir</td>

                <td><span class="status">Read</span></td>

                <td><span class="rate two"><span></span><span></span><span></span></span></td>

            </tr>

            <!-- To Read, No Rate -->

            <tr class="to-read">

                <td>Sapiens</td>

                <td>Yuval Noah Harari</td>

                <td>History</td>

                <td><span class="status">To Read</span></td>

                <td><span class="rate"><span></span><span></span><span></span></span></td>

            </tr>

        </tbody>

    </table>

</body>

</html>
/* --- Global & Typography --- */
body {
    font-family: 'Inter', sans-serif;
    background-color: #0d1117;
    color: #c9d1d9;
    padding: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

h1 {
    color: #58a6ff;
    margin-bottom: 30px;
    text-shadow: 0 0 5px rgba(88, 166, 255, 0.5);
    font-weight: 700;
}

/* --- Table Structure --- */
table {
    width: 90%;
    max-width: 1000px;
    border-collapse: separate;
    border-spacing: 0 10px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    border-radius: 12px;
    overflow: hidden;
}

thead {
    background-color: #161b22;
    color: #f0f6fc;
    text-transform: uppercase;
    font-weight: 600;
}

th, td {
    padding: 15px;
    text-align: left;
}

span {
    display: inline-block;
}

/* --- Row Backgrounds (Tests 19-24) --- */
tr[class~="read"] {
    background-image: linear-gradient(to right, #1d402f, #1f272a);
}

tr[class~="to-read"] {
    background-image: linear-gradient(to right, #40321d, #1f272a);
}

tr[class~="in-progress"] {
    background-image: linear-gradient(to right, #1f2740, #1f272a);
}

tbody tr:hover {
    box-shadow: 0 0 15px rgba(88, 166, 255, 0.2);
    transform: translateY(-2px);
    transition: all 0.2s ease-in-out;
    cursor: pointer;
}

/* --- Shared Status/Rate Styles (Tests 35-38) --- */
span[class~="status"], span[class^="rate"] {
    height: 25px;
    width: auto;
    padding: 5px 10px;
    border-radius: 6px;
    font-size: 0.85em;
    font-weight: 700;
    text-shadow: none;
    text-transform: uppercase;
    line-height: 15px;
    text-align: center;
}

/* --- Status Descendant Selectors (Tests 26-34) --- */
tr[class~="to-read"] span[class~="status"] {
    border: 1px solid #ffab70;
    background-image: linear-gradient(45deg, #442a00, #2c1d00);
    color: #ffc17e;
}

tr[class~="read"] span[class~="status"] {
    border: 1px solid #3fb950;
    background-image: linear-gradient(45deg, #103316, #081a0b);
    color: #55d366;
}

tr[class~="in-progress"] span[class~="status"] {
    border: 1px solid #58a6ff;
    background-image: linear-gradient(45deg, #0a1f44, #050f22);
    color: #89caff;
}

/* --- Rate Dot Styling (Tests 39-45) --- */
span[class^="rate"] > span {
    border: 1px solid #30363d;
    border-radius: 50%;
    margin: 0 2px;
    height: 15px;
    width: 15px;
    background-color: #21262d;
    transition: background-image 0.3s ease;
}

/* --- Rate Filling (Tests 46-51) --- */
span[class~="one"] span:nth-child(1) {
    background-image: linear-gradient(45deg, #ffc17e, #f79038);
}

span[class~="two"] span:nth-child(-n+2) {
    background-image: linear-gradient(45deg, #ffc17e, #f79038);
}

span[class~="three"] span {
    background-image: linear-gradient(45deg, #ffc17e, #f79038);
}


Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0

Challenge Information:

Build a Book Inventory App - Build a Book Inventory App

Hi @Mbongisenit and welcome to our community!

There are two specific issues which I can see which are causing tests to fail.

  1. You are converting text to uppercase (e.g. column headings). For example, you should be matching the text ‘Read’, not ‘READ’.
  2. You are using tildes in your selectors when you should be explicitly matching exact class names. For example, you should be matching the class ‘in-progress’ not matching any class which contains the text ‘in-progress’.

If you address these two issues wherever they occur in your code, I think your code should pass.

Hello

Thank you so much for the reply,

I have applied your suggestions—I removed the text-transform: uppercase; from the headers/status styles, and I switched the selectors for single-class rows (to-read, in-progress) from [class~="..."] to the exact match [class="..."].
However, I’m still stuck on a few tricky ones. Here’s a breakdown of the remaining issues:
Persistent Failing Tests (Lines 14, 19-51)

Test 14 (Status Text Casing): I’ve removed text-transform: uppercase everywhere I could find it related to the status text, but this test is still failing, which is really confusing.
Tests 19-20 & 29-31 (Multi-Class read Row Selectors):
Since my read rows have classes like class=" read one", the exact match selector (tr[class="read"]) no longer works. I tried switching back to the correct “contains word” selector ([class~="read"]), and even tried removing the tr tag, but the tests still fail, even though that selector should work for multi-class elements.
Tests 39-51 (Rate Dot Styling): This whole section is breaking. I’m using a mix of attribute selectors and pseudo-classes (like [class^="rate"] > span and [class~="one"] span:nth-child(1)), but the test is rejecting these attribute selectors entirely.
Could anyone review the attached styles.css in Canvas and advise on the specific selector syntax that the test runner is looking for in these multi-class rows and the rate dots?

body {
font-family: 'Inter', sans-serif;
background-color: #0d1117;
color: #c9d1d9;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}

h1 {
color: #58a6ff;
margin-bottom: 30px;
text-shadow: 0 0 5px rgba(88, 166, 255, 0.5);
font-weight: 700;
}

table {
width: 90%;
max-width: 1000px;
border-collapse: separate;
border-spacing: 0 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
border-radius: 12px;
overflow: hidden;
}

thead {
background-color: #161b22;
color: #f0f6fc;
font-weight: 600;
}

th, td {
padding: 15px;
text-align: left;
}

span {
display: inline-block;
}

/* Row backgrounds */
tr[class="read"], tr[class="read one"], tr[class="read two"], tr[class="read three"] {
background-image: linear-gradient(to right, #1d402f, #1f272a);
}

tr[class="to-read"] {
background-image: linear-gradient(to right, #40321d, #1f272a);
}

tr[class="in-progress"] {
background-image: linear-gradient(to right, #1f2740, #1f272a);
}

tbody tr:hover {
box-shadow: 0 0 15px rgba(88, 166, 255, 0.2);
transform: translateY(-2px);
transition: all 0.2s ease-in-out;
cursor: pointer;
}

/* Shared status and rate styles */
span[class="status"], span[class^="rate"] {
height: 25px;
width: auto;
padding: 5px 10px;
border-radius: 6px;
font-size: 0.85em;
font-weight: 700;
text-shadow: none;
text-transform: uppercase;
line-height: 15px;
text-align: center;
}

/* Status styles */
tr[class="to-read"] span[class="status"] {
border: 1px solid #ffab70;
background-image: linear-gradient(45deg, #442a00, #2c1d00);
color: #ffc17e;
}

tr[class="read"], tr[class="read one"], tr[class="read two"], tr[class="read three"] {
/* already styled above */
}

tr[class="read"] span[class="status"],
tr[class="read one"] span[class="status"],
tr[class="read two"] span[class="status"],
tr[class="read three"] span[class="status"] {
border: 1px solid #3fb950;
background-image: linear-gradient(45deg, #103316, #081a0b);
color: #55d366;
}

tr[class="in-progress"] span[class="status"] {
border: 1px solid #58a6ff;
background-image: linear-gradient(45deg, #0a1f44, #050f22);
color: #89caff;
}

/* Rate dots */
span[class^="rate"] span {
border: 1px solid #30363d;
border-radius: 50%;
margin: 0 2px;
height: 15px;
width: 15px;
background-color: #21262d;
transition: background-image 0.3s ease;
}

/* Rate fill */
span[class="rate one"] span:nth-child(1) {
background-image: linear-gradient(45deg, #ffc17e, #f79038);
}

span[class="rate two"] span:nth-child(-n+2) {
background-image: linear-gradient(45deg, #ffc17e, #f79038);
}

span[class="rate three"] span {
background-image: linear-gradient(45deg, #ffc17e, #f79038);
}

I’ve edited your post to improve the readability of the code. When you enter a code block into a forum post, please precede it with three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add the backticks.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

did you make any changes to your html? if so please post your updated html too, if not, you need to adjust various things

like when you give the class to the table row, it needs to be only read to-read or in-progress, there should not be an other class there

the span elements for the rating needs to be siblings not nested in each other

1 Like

@ILM Thank you for assisting after such a strain. Finally worked out “I added one table row with exactly class="read" to satisfy the test’s strict selector.
Then I used tr[class="read"] and tr[class="read"] span[class="status"] in the CSS to match the test’s exact attribute selector requirements.”

1 Like