This page is a must read, even if you plan on redesinging the pages at the component level you must at least understand how to remove the default CSS styles.
Understanding the CSS class system
Upon inspecting the DOM in storybook you will see that most element have at least a couple of classes applied to them.
A class starting with kc, for example kcLabelClass.
One or more classes with pf-, for example pf-c-form__label, pf-c-form__label-text
The classes starting with kc do not have any actual styles applied to them. Their sole purpose is to be a target for you to apply your custom styles.
The classes with pf- are Paterfly classes. Patternfly is a CSS framwork in the like of Bootstrap created by RedHat, it is what the the Keycloak team uses to build all their UIs.
Applying your custom CSS
Do not edit the any file in the public/keycloakify-dev-resources directory. Thoses are resource files used by Storybook for simulating a Keycloak environement during devloppement, thoses files aren't part of your theme.
To apply your custom CSS style you should use the kc classes to target the components.
Having diferent stylesheet for the login page, the register page ext...
Here we used a global stylesheet that applies to all pages of the login theme however you can also apply stylesheet on a page-by-page basis (a stylesheet for the login page, another stylesheet for the register page ect...).
If you are planning to customize the pages using React/Angular/Svelte at the component level it will be very obvious how to do so after reading the using a component library page.
However if you plan to stick with with CSS only customization it might not be apparent to you how to do it so here is shat show how it can be acheived:
src/login/KcPage.tsx
import { Suspense, lazy, useMemo} from"react";exportdefaultfunctionKcPage(props: { kcContext:KcContext }) {const { kcContext } = props;const { i18n } =useI18n({ kcContext });constclasses=useCustomStyles(kcContext);return ( <Suspense> {(() => {switch (kcContext.pageId) {default:return ( <DefaultPagekcContext={kcContext}i18n={i18n}classes={classes}Template={Template}doUseDefaultCss={true}UserProfileFormFields={UserProfileFormFields}doMakeUserConfirmPassword={doMakeUserConfirmPassword} /> ); } })()} </Suspense> );}functionuseCustomStyles(kcContext:KcContext) {returnuseMemo(() => {// You stylesheet that applies to all pages.import("./main.css");let classes: { [keyinClassKey]?:string } = {// Your classes that applies to all pages };switch (kcContext.pageId) {case"login.ftl":// You login page specific stylesheet.import("./pages/login.css"); classes = {...classes,// Your classes that applies only to the login page };break;case"register.ftl":// Your account page specific stylesheetimport("./pages/register.css"); classes = {...classes,// Your classes that applies only to the register page };break;// ... }return classes; }, []);}
If this code does not make much sense to you you can check out this video tutorial where this approach is demonstrated in practice.
Using Tailwind
You'll be of course able to use Tailwind the regular way by applying the utility classes to the React/Angular/Svelte components.
However be aware that you can also use tailwind without having to modify the pages structures using the @apply dirrective. It's demonstrated in this page.
Using Bootstrap or some other CSS framwork
If you wish to use bootstrap or some other CSS framwork that provide standardized CSS classes you might wonder how to apply thoses classes.
Here is an example with Bootstrap:
By writing that you've effectively replaced the Patterfly classes pf-c-form__label pf-c-form__label-text by the bootstrap classes form-label col-form-label.
dWhat will happen in practice, if you inspect the lement in your browser is that the form label that was previously rendered as:
Let's consider the "Sign In" button of the login page:
Let's see how we can unstyle it so that we can apply our custom styles without having to wory about our CSS conflicting with the default Patternlyfly styles.
To remove the Patternfly styles we must first inspect the element in our browser:
Doing that we can see what Patterfly classes are applied by default to the standardized element:
kcButtonClass get assigned pf-c-button
kcButtonPrimaryClass get assigned pf-m-primary and long-pf-btn
kcButtonBlockClass get assigned pf-m-block
kcButtonLargeClass get assigned btn-lg
Since we want to remove all the default styles we can instruct Keycloakify to remove all the classes that gets assigned by default to thoses kc classes:
Maybe you'd prefer to remove all the Patterfly style alltogether and start fresh.
What's nice with this approach is that not only will all the pf classes been stripped out all at once but also the global Patterfly stylesheet won't even be loaded.
A common scenario is to use npx keycloakify eject-page to eject some pages of the login UI to customize them in depth.
On the page that you have ejected, you're likely to want to disable all the default styles, however you might want to keep the Patterfly styles on the pages that you haven't redesigned.
Here is an example where the login.ftl page have been ejected, disable the default styles for it while keeping them for the other pages:
Removing the classes in the ejected components (kcClsx)
If you have ejected some pages with npx keycloakify eject-page and disabled the defaut styles with doUseDefaultCss set to false you might wonder if you need to keep the kcClsx in the pages, for example:
Just be aware that if you have defined some custom CSS that use the kc classes as selector ( Like for example .kcButtonClass { /* ... */ } ) they will no longer be applied.