CSS Styling in OpenEMR

I am working on updating the appearance of previous addresses and have a few questions.

(1) OpenEMR CSS Styles/Themes
How should I do custom css styling in OpenEMR?
I know that you don’t want inline styling.
There are multiple themes. Is there a way that I can specify a custom style without having to change it in every theme?
Where do I put the custom styling?

(2) Using bootstrap styling
I am trouble having bootstrap do the exact styling that I need. Bootstrap documentation shows I can modify/customize some of the bootstrap styling.
Where in OpenEMR can I do this?
For example, there are 8 background colors in class .bg-primary, etc. I don’t like these. I would like to use gray-400 (specified in bootstrap) but I can’t figure out how to set the background to gray-400. .bg-gray-400 does not work.

(3) Table vs DIV
Previous addresses uses a table for the header, but div’s for the rows. I see why Stephen changed the rows to divs. I am thus trying to change the header to a div and not use table. However, I would like to display the divs using bootstrap’s table styling. I like the style of thead-light. However, it won’t work if I specify the class of the div as thead-light. I also like the lines between the table rows like class table-sm in bootstrap. Is there a way to easily use this in the div class? Or, should I just specify a bottom border to each row in css? Where do I specify this if I should not do inline styling.

Thank you for any advice/guidance.

In regards to my question 1
For styling, are we supposed to modify the following file:

Then, from the root folder of OpenEMR, run:
npm run dev

And, will this insert the changes into the css files of all of the themes?

hi @psoas, do you use the easy-dev docker? Step 6 of the guide has some tips.

Think you can run npm run build in general to build the themes again.

1 and 2
If this is for your personal or clinic use (and not standard codebase / PR), one of the options is something like Bootstrap Magic generate a full theme. Save that as xxx in themes directory and let everyone select it if they want.

3 - Table vs DIV
This is age old question. Tables by definition can’t be responsive. So if you expect same page to be used on desktop and tablets/phones, use div with col-* classes in BS. If the primary use will be desktop, table with few BS classes kinda works.

Somewhat related note re. addresses or data that can have wildly different sizes (e.g. something as simple as state - Ohio and New Hampshire), BS offers other elegant options like cards rather than traditional tabular layout (tables and/or div). Does need bit more effort though.

1 Like

npm run build worked.

I am wondering:
–If an OpenEMR update involves style changes, does the update script run “npm run build” or does that need to be run after the updates are made?

–If someone pulls code to get the latest commit and there are scss file changes, I guess that they definitely need to run “npm run build”, correct? Do most people do that when they pull commits? Probably not. I guess there is no way around that, though, is there?

1 Like

I have followed some ideas in this post, I have created a custom scss at Bootstrap Magic : Generate your own Bootstrap themes quickly and easily also have asked for some palette suggestions at https://www.canva.com/colors/color-palette-generator/

I have uploaded scss to openEMR docker, to /interface/themes/colors/style_custom.scss

The next step is to “npm run build”, I assume this is also inside openemr docker (I ran docker exec -it $(docker ps | grep _openemr | cut -f 1 -d " ") /bin/sh) but I got this message:

openemr-interface@0.2.0 build
gulp -b

sh: gulp: not found

Then I tried to do this: Composer and NPM - OpenEMR Project Wiki

npm run build

and I got this:

openemr-interface@0.2.0 build
gulp -b

Building OpenEMR themes using Gulp

[04:48:53] Using gulpfile /var/www/localhost/htdocs/openemr/gulpfile.js
[04:48:53] Starting ‘default’…
[04:48:53] Starting ‘clean’…
[04:48:53] ‘clean’ errored after 19 ms
[04:48:53] Error: EACCES: permission denied, unlink ‘/var/www/localhost/htdocs/openemr/public/themes/tabs_style_full.css’
at Object.unlinkSync (node:fs:1772:3)
at Function.rimrafSync [as sync] (/var/www/localhost/htdocs/openemr/node_modules/rimraf/rimraf.js:303:17)
at /var/www/localhost/htdocs/openemr/node_modules/del/index.js:130:11
at Array.map ()
at AsyncFunction.module.exports.sync (/var/www/localhost/htdocs/openemr/node_modules/del/index.js:122:29)
at clean (/var/www/localhost/htdocs/openemr/gulpfile.js:81:9)
at bound (node:domain:433:15)
at runBound (node:domain:444:12)
at asyncRunner (/var/www/localhost/htdocs/openemr/node_modules/async-done/index.js:55:18)
at processTicksAndRejections (node:internal/process/task_queues:78:11)
[04:48:53] ‘default’ errored after 25 ms
Thanks in advance!

Now I can share how I was able to compile customized themes:

I have my server running without docker.
I found this fix Fix gulp build deprecated warning by sjpadgett · Pull Request #6543 · openemr/openemr · GitHub
So I have downloaded:


Paste them on /var/www/html folder (I move everything from openemr folder to it).

I have updated node.js to v18
https://www.hostingadvice.com/how-to/update-node-js-latest-version/ (1. Update Node.js Using Node Version Manager (nvm)), in my case I first installed nvm, then ask it to install

nvm install v18.17.1

Then I run in my server´s terminal

npm install

(it takes a long time). Then create a custom scss with customized palette (for example style_custom.scss), you can take any existing theme. ( interface/themes/colors), and set your colors.

$colorname: "Custom";

$darkest: #404a6d;
$darker: #3a4b84;
$dark: #6b7cb6;
$mid: #8896c4;
$midpale: #a6b0d3;
$pale: #b5bdda;
$midpalepale: #c3cae1;
$palepale: #e1e4f0;
$palepurple: #e7e6f9;
$paler: #f8f8fd;
$midnightblue: #2f2f7d;
$white: #fff;
$navbar-text-color: $pale;

@import "utilities/default_variables";

// Import Bootstrap 4 SCSS Files before doing anything
// This gets replaced in gulp now -- do not touch
// bs4import

@import "../color_base";

I noticed that some files used to compile scss were out of date, so I downloaded most recent files from openemr github:


I replaced them in my server´s folder.

Then downloaded bootstrap4-theme files (src and dist folders).


I moved select2-bootstrap4-theme folder to match github path.

cd /public/assets

mv \@ttskch modified/\@ttskch

npm run build (at var/www/html where gulpfile.js and package.json are located).

Go and take a cup of coffee (it took 12 minutes in my server).

1 Like

Hello Marco, can you send an image of how this change turned out, I was curious. I’m trying to change the login screen, in particular putting an animated background, but without success so far.

Hi Bruno,

This is my customized theme and custom logo.

I have saved my custom logo on this path: /public/images/logos/core/login/primary/logo.png

Hope this helps!

1 Like

Very cool Marco, can you tell me how I could put a background on this home screen? My idea is to put an animated gif.

I can suggest you to try to use logo.gif and remove any other file on this logo path. That should do the trick.

But I would like to change the “background”, not the initial logo. So I don’t know where to make this change.
I will place the image where I would like to change it.

In order to be able to compile scss, I had to install gulp

npm install -g gulp

then I was able to execute the script

npm run build

Perfect, my friend, you solved my problem. Thank you very much!