cancel
Showing results for 
Search instead for 
Did you mean: 
JimmyW
Community Participant

Hide point etc. using CSS

Jump to solution

Hi I found a similar post about this and I'm wondering if someone maybe can help me clear out some things.

I tried to use the below to pinpoint the sites where i want to hide the point etc. on but without success. My question is can I be more exact on the parts I want to hide, I have put together some CSS that actually works and achieves what I want but I'm not sure that this is the best way of doing it as my CSS skill is very low.

The pointer below does not seem to work for me to specify the exact parts/sites I want the function on.

 

 

 

 

a[href^=

 

 

 

 

 

My CSS, this is working, my question is can i be more granular in Selecting the exact parts I want to hide?

 

 

 

 

/* Hides Score column & Out of column in Grades */
#grades_summary .assignment_score, .possible { display: none;}
/* Hides points in Modules */
#context_modules .points_possible_display {display: none;}
/* Hides points in Quizzes */
#assignment-quizzes .ig-details .ig-details__item:last-of-type {display: none;}
/* Hides points in Gradebook view */
#gradebook_grid .assignment-points-possible {display: none;}
/* Hides total column in gradebook */
.gradebook div[id*="total_grade"], .gradebook div.total-cell {visibility: hidden;}‍‍‍‍‍‍‍‍‍‍
/* Block adding color overlay on course cards */
.ic-DashboardCard__header_image .ic-DashboardCard__header_hero {   background:none !important;}

 

 

 

 

The above is working but I'm not sure how i can be more specific/granular in selecting the right parts to hide.

We do not use points in our grading, we only have pass/fail and when printing grades we don't want to show total score or any score etc.

2021-06-01 09_46_35-Window.png

2021-06-01 09_48_01-Window.png

2021-06-01 09_50_14-Window.png

2021-06-01 09_49_10-Window.png

Labels (1)
Tags (3)
1 Solution

Accepted Solutions
James
Community Champion

@JimmyW 

JavaScript is executed once. The theme editor is just the way Canvas provides for injecting it into the page. It doesn't matter how the JavaScript is loaded, it's still just executed once. You can add Mutation Observers or attach element listeners to wait for future events to happen, but the main block is just executed the single time.

Unless you install Mutation Observers or continually poll the page (don't do that) looking for changes, your JavaScript will not be aware of any changes that happened after it was executed.

You might not think that's a problem, but some content is loaded after the page is ready and your JavaScript has executed. For example, none of the grades in the gradebook are delivered in the HTML sent from the server. They are dynamically fetched from the server using the Canvas API and then displayed. In other places, like content pages and the student view of grades, the content is delivered with the HTML, but it is inside the ENV variable and not as part of the displayed HTML. JavaScript that acts on the page might be executed before Canvas puts the content into the DOM. To be safe, you have to wait for the content to be put into the DOM before you act on it. Many programmers were using setTimeout() to poll until it was ready and then executing the code, but I advocate for Mutation Observers (event driven rather than polling).

Depending on your situation, waiting for the content to appear may be all that you have to do. In some cases, Canvas with take the React Virtual DOM and rerender it, wiping out any changes you've made to the displayed DOM. If I recall correctly, one place this was used was in adding students.

Once you have identified the elements you need to act on and whether it is a one-time thing or needs checked repeatedly, then you can execute the JavaScript that modifies the page. The CSS selector or href is often in a span or div element but Canvas throws in the accessibility stuff that makes that not the element I want to hide. It is some sort of ancestor (perhaps immediate parent, but more often several parents back).

The approach I take varies depending on what the DOM looks like.

  • I can look for the href and then use the closest() method to find the proper element to hide. Unfortunately, the element I need to hide might be 8 div elements up in the DOM and not have a usable class or other CSS selector, so this doesn't always work.
  • A second approach is to search for the elements to hide. For example, if I'm trying to hide rows in a table, but there is a CSS selector buried somewhere in there, then I would search for all of the tr elements and then check to see if the CSS selector was within that element (instead of document.querySelector, use element.querySelector -- where element is the one returned by the first CSS selector). In this case, I already have the element that I need to hide and don't have to go looking for the closest().

I had forgotten about that post from three years ago (I tend to write a lot of stuff). I like the last sentence and the fact that I'm consistent. I still prefer educating people when you do weird stuff.

View solution in original post

4 Replies
James
Community Champion

@JimmyW 

You often cannot be more specific using just CSS.

As Canvas rewrites sections of their code, they are using ReactJS that creates random-looking class names that may change with each release. The human-friendly names like .points_possible_display may not be available.

In other cases, CSS selectors are contained in the children, but you need to hide the parent. This requires JavaScript to accomplish as CSS does not allow you to operate on a parent element.

Sometimes, there may be no suitable class or id selector at all and you will need to revert to the a[href] type selector. This is almost always going to result in selecting the wrong item and you will need to hide a parent of the anchor element that you found. Then you're back to using JavaScript.

Using JavaScript is not without its own set of issues. CSS acts on the page whenever content is added. If you add new content that matches a selector, then the CSS applies. JavaScript acts on the content that is there when the JavaScript is ran. If a page is modified after your JavaScript runs, it will not be affected. This involves adding MutationObservers to watch for when the content changes.

There is one option to hide grades in Canvas. You're probably already aware of that, but just in case, the Hide totals in student grades summary option on the Course settings page will hide some of this for you.

Other hacks that you've probably considered are to make most assignments (other than quizzes) graded as complete/incomplete (it still shows the total) or to make every assignment worth 1 point and then treat it as a binary 0 = fail and 1 = pass situation. In the second case, the total represents the number of assignments and the student's score represents the number that they passed.

My favorite solution for this type of issue is always education. Do a good job explaining to the students (and any observers) that the points are meaningless and tell them what they should be looking at instead.

JimmyW
Community Participant

Thank you @James 

I actually cam across this from one of your answers in another post.

https://community.canvaslms.com/t5/Canvas-Developers-Group/CSS-to-hide-the-totals-columns-in-Grades/...

That CSS is still working and was done 3 years ago.
I'm applying to to the theme itself. 

If the Class or ID changes then yes it would not work, but you are saying it is possible to make it work with JavaScript instead?
And when you say after my JavaScript ha run, changes after that would not be affected? But if the JavaScript is in the theme itself?

Thank you for taking your time and answering this.

James
Community Champion

@JimmyW 

JavaScript is executed once. The theme editor is just the way Canvas provides for injecting it into the page. It doesn't matter how the JavaScript is loaded, it's still just executed once. You can add Mutation Observers or attach element listeners to wait for future events to happen, but the main block is just executed the single time.

Unless you install Mutation Observers or continually poll the page (don't do that) looking for changes, your JavaScript will not be aware of any changes that happened after it was executed.

You might not think that's a problem, but some content is loaded after the page is ready and your JavaScript has executed. For example, none of the grades in the gradebook are delivered in the HTML sent from the server. They are dynamically fetched from the server using the Canvas API and then displayed. In other places, like content pages and the student view of grades, the content is delivered with the HTML, but it is inside the ENV variable and not as part of the displayed HTML. JavaScript that acts on the page might be executed before Canvas puts the content into the DOM. To be safe, you have to wait for the content to be put into the DOM before you act on it. Many programmers were using setTimeout() to poll until it was ready and then executing the code, but I advocate for Mutation Observers (event driven rather than polling).

Depending on your situation, waiting for the content to appear may be all that you have to do. In some cases, Canvas with take the React Virtual DOM and rerender it, wiping out any changes you've made to the displayed DOM. If I recall correctly, one place this was used was in adding students.

Once you have identified the elements you need to act on and whether it is a one-time thing or needs checked repeatedly, then you can execute the JavaScript that modifies the page. The CSS selector or href is often in a span or div element but Canvas throws in the accessibility stuff that makes that not the element I want to hide. It is some sort of ancestor (perhaps immediate parent, but more often several parents back).

The approach I take varies depending on what the DOM looks like.

  • I can look for the href and then use the closest() method to find the proper element to hide. Unfortunately, the element I need to hide might be 8 div elements up in the DOM and not have a usable class or other CSS selector, so this doesn't always work.
  • A second approach is to search for the elements to hide. For example, if I'm trying to hide rows in a table, but there is a CSS selector buried somewhere in there, then I would search for all of the tr elements and then check to see if the CSS selector was within that element (instead of document.querySelector, use element.querySelector -- where element is the one returned by the first CSS selector). In this case, I already have the element that I need to hide and don't have to go looking for the closest().

I had forgotten about that post from three years ago (I tend to write a lot of stuff). I like the last sentence and the fact that I'm consistent. I still prefer educating people when you do weird stuff.

View solution in original post

JimmyW
Community Participant

@James Thank you so much for taking your time and answering 🙂

Tags (1)