Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Using the canvas API I found that I can embed <style></style> blocks of CSS in the wiki_page[body]. for example:
<style>
.fp-body-columnx{
width:280px;
word-wrap:break-word;
}
.fp-body-container{
display:flex;
flex-wrap:no-wrap;
justify-content: center;
}
@media (max-width:900px) { // these don't work in Canvas!
.fp-header-span-second {
display: none;
}
}
</style>
<h2> and starts the page ...</h2>
<div class="fp-body-container">
<div class="fp-body-columnx">
</div>
</div>
While Canvas (through the API) is permitting the <style></style> blocks into the wikibody, for some reason it's decided to filter the @media attribute. Note - if I open these pages in the Canvas page editor, all the style code disappear. This is an API-only feature.
My app is autogenerating a responsive frontpage using module-items. For narrow screens I'd like some of the data to disappear and others to be reformatted, depending on the display width of the browser.
Any suggestions for getting the @media tag to work? I thought that perhaps the "@" was causing the problem, but I can insert a "@@" and the media tag shows.
Below is an example of one the autogenerated frontpages. It reads module and module-item data from the current week and formats it into responsive columns. As the screen size changes, the page reformats itself.
This works great, except when the screen gets really narrow and one needs to change flex-box strategies. I'd like to use the "@media" CSS code to change some of the CSS attributes depending on current screen size.
Thoughts?
Thanks for the note about the API not properly sanitizing the code. I wouldn't rely on that feature. They may not fix it for a long time (if ever), but there are some things that people continue to push despite Canvas saying it's deprecated. I just wanted to throw that out there that this is undocumented and unsupported behavior and the official Canvas line is that you shouldn't rely on it and frequently test whenever upgrades to their software are made.
As you mentioned, editing the page with the Rich Content Editor makes it disappear as the style element isn't allowed in the body's HTML. This limits its suitability to courses where the instructor cannot change anything. That can be accomplished with Canvas using blueprint courses. If someone can edit the page, then all of the hard work disappears in a flash. I have that situation in one of my courses this semester. I have a flex model that I want the bottom two blocks to always be on a line by themselves. I can put an empty div in through the API but it gets stripped as soon as I edit the page.
The style element isn't allowed in the body. It's allowed in the head. It is invalid HTML to put it in the body, which is what you're doing. Don't expect there to be a solution for the media query when Canvas doesn't support style elements in the body anyways.
The correct solution is to add custom CSS to the theme. That's injected into the head of the HTML document and you could include your media descriptor there. It looks like you have design skills, but based on the name of the page, I cannot tell if you're an instructional designer for the school or this is a class about designing a better interface.
If you're working for the school in a design role (probable since you also know about the API), then you can see your Canvas admin about adding some well thought out CSS to the theme. If it's for a class project, they won't add that for the whole account.
You mention the issue with resizing. The flex grid model can handle some of that for you. I use it for my statistics course home pages and specify different layouts based on the width of the device. It mostly works well, although I get just one column on some phones. I originally started with 3 columns on a wide screen because it looked nice on my screen, but then went back down to two because of the way it looked on the student's. You may be able to make flex work for you rather than using media queries to accomplish it.
But if you really must use the media query, then add it to custom CSS applied through the theme. Realize, though, that it applies everywhere, so you will also want to add specific classes to make sure it doesn't change more than you want.
Another option, if you cannot get the CSS in the theme is to add JavaScript through the theme. It could look for whether the pathname matches a pattern (limiting yourself to content pages and not quizzes or assignments, for example) and then check if a certain classname is found on the page. If the classname is found, then inject the CSS by adding a stylesheet. If the class isn't found on the page, then just return. This is a way that you could add course-level CSS rather than account-level CSS.
One note with pages, though, you may have to add a mutation observer to wait for the page to be rendered -- I've found that guarantees that your script will not run until certain things are available isn't always the case. That was years ago, though, and it might have changed.
Setting aside the technical issues, that's a nice job autoformatting the homepage based on the module items. I looked at doing that this semester, but I took over the modules structure to use with badges so it's not available for me to use as the homepage anymore. I want the students to see the modules so they can check their status on the badges faster, but with 63 badges / modules, it would be confusing to throw the weekly content in there as well.
I ended up writing code that scanned all of my existing pages for blocks, saved it to a JSON file, and then created an organization structure in a spreadsheet. Then I could move the blocks from week to week (that was my main issue) by renumbering them in a spreadsheet. Then it wrote the code back to Canvas.
I also have comments and extra information in my block that wasn't available in the module items. That also prevented me from using the module items approach. Since I just treat each item as a block, it keeps whatever is in the block. It's definitely more work than just using modules.
I also have a much smaller weekly jump table at the bottom using buttons from the styleguide. It's smaller, which makes it work better on a small screen. I also use the float style on an unordered list rather than flex-box for it.
@James Thanks for the tips! I'm a relative novice at course design. I'm still using modules that map to weeks, rather than advancing to modules mapping to topics and leveraging mastery paths. While I've been teaching for almost 40 years, I'm new to teaching these specific courses. This semester is my 2nd time through for this course, and I am therefore focused on building the course materials. Concurrently I'm developing a CLI that helps me automate the organization of my material into lectures and keeping the entire course organized on Canvas.
I'm a professor in CS (in a department) and not associated with our central team that manages the Canvas infrastructure. I like to keep my coding skills sharp, so I dive deeper into the CSS, HTML, API and automation than most. WRT to CSS, I could ask for some custom CSS codes to be added to the account CSS. I don't believe that we implement subaccounts at VCU yet, so perhaps when we get that far, I can get some space in the CSS file.
Like you I keep my course organized in a google sheet. The google sheet tracks the weeks and date, homework assignments, lectures, projects and quizzes. I fill in data on the outline tab and the sheet automatically builds a prettier course summary tab that can be embedded directly within a Canvas page.
My CLI processes the google sheet directly through the google API and then update/add content to Canvas through the Canvas API. I can edit weekly titles, lecture titles, etc., and the CLI will make the appropriate changes in Canvas to keep it all in sync. Below are a few of the commands that my CLI implements.
My CLI also automates creation of the frontpages, one for each week and then associates them with the buttons. I need to run my script manually at the beginning of each week, updating all the frontpages so that the button backgrounds and frontpage headers all align for the current week. For example, here is the command I just ran to freshen the menu for this week:
And here is this week's frontpage, assigned to HOME, with the appropriate buttons active, and the color hints for the buttons and header aligned for the current week of the term.
My course materials are stored in a quarto study guide, and I can edit/update the study guide as necessary.
My CLI can pull sections from the study guide and create lectures. I do have to adhere to a rather strict format in the guide, but the formats that I'm using seems to work for this particular class (user interface design and development). For example, here is a section from the study guide on visual design, and here is a reveal-js slide deck for the same material that can be embedded into an iframe on a lecture page within canvas.
Phew. I appreciate learning about how you leverage the canvas API. It's great for automation!
@jleonard99 - I really enjoyed your postings and was very interested in what you have done with injecting the Quarto content into Canvas. Do you make your cnvsapi tools available?
As to the "@media" problem - when I insert your HTML above into a Canvas wikipage, the tag has already been stripped out when the page was inserted with the PUT - as the response to the PUT shows the body as:
'body': '<style>\n'
' .fp-body-columnx{\n'
' width:280px;\n'
' \n'
' }\n'
' .fp-body-container{\n'
' display:flex;\n'
' flex-wrap:no-wrap;\n'
' justify-content: center;\n'
' }\n'
' \n'
'</style>\n'
'<h2> and starts the page ...</h2>\n'
'<div class="fp-body-container">\n'
'<div class="fp-body-columnx">\n'
'</div>\n'
'</div>\n',
Looking at the source code, the filtering was done by sanitize_field :body, CanvasSanitize::SANITIZE
in https://github.com/instructure/canvas-lms/blob/master/app/models/wiki_page.rb by the sanitize code in https://github.com/instructure/canvas-lms/blob/master/gems/canvas_sanitize/lib/canvas_sanitize/canva...
Interestingly, the actual set of tags and attributes allowed seems to be more liberal than those enumerated at https://community.canvaslms.com/t5/Canvas-Resource-Documents/Canvas-HTML-Editor-Allowlist/ta-p/38706... - the sanitize code comment notes there are differences between the "tinymce and canvas_sanitize whitelists" - hence the difference between what can be injected via the API and what can be entered with the editor.
As @James has pointed out, one way you can solve your problem is to ask your local Canvas admin to add the custom CSS for the subaccount where you are putting your pages. It is important to point out to them that the custom CSS can be limited to a specific subaccount, so it does not need to be done for the whole Canvas instance. It is even possible to have custom Javascript for use in a subaccount. One could do the media queries in JavaScript as described at https://dev.to/lindaojo/how-to-use-media-queries-in-html-css-and-javascript-n8o
Update: The API will also strip out style tags that have a "media" attribute, so one cannot say:
<style media="only screen and (max-width: 600px)">
body {
background-color: lightblue;
}
</style>
The media attribute is stripped out, but the style applies and the background color changes to lightblue (for the whole page).
I would like to thank @jleonard99 for your question and @jleonard99 and @James for your replies. This helped me solve a problem of how to show marked-up text in a Canvas wikipage where the markup was of Common European Framework of Reference for Languages: Learning, teaching, assessment (CEFR) levels (A1, A2, B1, B2, C1, and C2 - plus some extra pseudo levels that I use for things that I don't know or where a CEFR level is not applicable). An example is shown in:
https://canvas.kth.se/courses/11/pages/style-page-examplec
The colors are not optimal, but they are currently just to show some differences. Additionally, using the abbr tag enables one to get a tooltip to show the level—for those like me who cannot see the colors well.
An improved example is shown in https://canvas.kth.se/courses/11/pages/style-page-exampled.
To participate in the Instructure Community, you need to sign up or log in:
Sign In