# Login page CSS

### Overview

With the login page CSS you can target the below components with full component coverage:

* Login form section
* Input fields and labels
* Buttons and actions
* Branding message and imagery
* Notification containers

Briefly, this is how a branded login page looks like with Ubidots native CSS styling:

<figure><img src="https://884329393-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MhzNRg0B4ECiNXc093G%2Fuploads%2F91ygE9xBddmJFX2ZIkgB%2Fimage.png?alt=media&#x26;token=2b841d4a-3653-4131-ac91-3d1e428ade82" alt=""><figcaption></figcaption></figure>

With the below CSS stylesheet, the login page can be changed into this:

<details>

<summary>Login CSS stylesheet</summary>

```css
/* TYPOGRAPHY */
.login__title,
.login__label,
.login__input,
.login__button,
.login__terms-text,
.login__custom-message {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: -0.01em;
}

/* BACKGROUND */

.login__wrapper {
  background: linear-gradient(135deg, #000000 0%, #0a0a0a 100%);
}

.login__background {
  background: linear-gradient(135deg, 
    #000000 0%, 
    #0d2d1d 25%,
    #1a4d32 50%, 
    #0d2d1d 75%,
    #000000 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: none;
}

/* CONTAINER */

.login__container {
  background: rgba(12, 12, 12, 0.5);
  border: 1px solid rgba(45, 189, 104, 0.25);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5),
              0 0 80px rgba(45, 189, 104, 0.1);
  backdrop-filter: blur(24px) saturate(180%);
}

/* FORM SECTION */

.login__section--form {
  background: rgba(10, 10, 10, 0.4);
  backdrop-filter: blur(20px) saturate(180%);
  border-radius: 0.9375rem 0 0 0.9375rem;
  overflow: visible;
}

.login__section--form::before {
  height: 2px;
  background: linear-gradient(90deg, 
    transparent 0%, 
    rgba(45, 189, 104, 0.6) 50%, 
    transparent 100%);
}

.login__section--form::after {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.03) 0%,
    transparent 30%,
    rgba(45, 189, 104, 0.02) 100%);
  border-radius: 0.9375rem 0 0 0.9375rem;
  pointer-events: none;
}

/* LOGO */

.login__logo-link {
  display: block;
  text-align: center;
  margin-bottom: 1.75rem;
}

.login__logo-image {
  width: 200px;
  height: auto;
}

/* IMAGE SECTION */

.login__section--image {
  backdrop-filter: none;
  overflow: hidden;
  border-radius: 0 0.9375rem 0.9375rem 0;
  background-size: cover;
  background-position: center;
}

.login__section--image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* TITLE */

.login__title {
  display: none;
  visibility: hidden;
  opacity: 0;
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

/* FORM */

.login__form::before {
  content: 'Welcome back';
  display: block;
  color: #E3E3E3;
  font-size: 2.25rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  margin-bottom: 0.5rem;
  text-align: center;
  background: linear-gradient(135deg, #E3E3E3 0%, #2DBD68 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.login__form::after {
  content: 'Enter your credentials to access your account';
  display: block;
  color: rgba(227, 227, 227, 0.6);
  font-size: 0.9375rem;
  font-weight: 400;
  margin-bottom: 2rem;
  margin-top: -0.5rem;
}

/* LINKS */

a {
  color: #2DBD68;
  transition: color 0.2s ease;
  font-weight: 500;
  text-decoration: none;
}

a:hover {
  color: #3DD378;
  text-decoration: underline;
}

.login__forgot-link {
  color: #2DBD68;
  transition: color 0.2s ease;
  font-weight: 500;
  text-decoration: none;
}

.login__forgot-link:hover {
  color: #3DD378;
  text-decoration: underline;
}

/* LABELS */

.login__label {
  color: rgba(227, 227, 227, 0.7);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
}

/* INPUT FIELDS */

.login__input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(45, 189, 104, 0.2);
  color: #E3E3E3;
  transition: all 0.3s ease;
  backdrop-filter: blur(12px) saturate(180%);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3),
              inset 0 1px 0 rgba(255, 255, 255, 0.08),
              inset 0 -1px 0 rgba(0, 0, 0, 0.2);
  font-weight: 400;
  font-size: 0.9375rem;
}

.login__input::placeholder {
  color: rgba(227, 227, 227, 0.35);
  font-weight: 300;
}

.login__input:focus {
  outline: none;
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(45, 189, 104, 0.5);
  box-shadow: 0 0 0 3px rgba(45, 189, 104, 0.15),
              0 4px 20px rgba(45, 189, 104, 0.2),
              inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

/* ICONS */

.login__icon {
  color: rgba(227, 227, 227, 0.5);
  transition: all 0.2s ease;
  cursor: pointer;
  font-size: 1rem;
}

.login__icon:hover {
  color: #2DBD68;
}

.login__icon[data-tooltip]::after {
  content: attr(data-tooltip);
  background: rgba(15, 15, 15, 0.98);
  border: 1px solid rgba(45, 189, 104, 0.3);
  color: #fff;
  padding: 0.3125rem;
  border-radius: 0.25rem;
  font-family: "Nunito", sans-serif;
  font-size: 0.875rem;
  font-weight: 400;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}

.login__icon:hover[data-tooltip]::after {
  opacity: 1;
}

/* BUTTON */

.login__button {
  background: linear-gradient(135deg, 
    rgba(45, 189, 104, 0.9) 0%, 
    rgba(37, 160, 88, 0.9) 100%);
  color: #000000;
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.02em;
  transition: all 0.3s ease;
  box-shadow: 0 4px 20px rgba(45, 189, 104, 0.4),
              inset 0 1px 0 rgba(255, 255, 255, 0.2),
              inset 0 -1px 0 rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(45, 189, 104, 0.6);
  backdrop-filter: blur(10px);
  overflow: hidden;
  animation: fadeInUp 0.6s ease backwards;
  animation-delay: 0.3s;
}

.login__button::before {
  display: block;
  background: linear-gradient(135deg, 
    rgba(255, 255, 255, 0.2) 0%, 
    rgba(255, 255, 255, 0.05) 50%,
    transparent 100%);
  opacity: 1;
  transition: opacity 0.3s ease;
}

.login__button::after {
  display: block;
  width: 200%;
  height: 200%;
  background: linear-gradient(45deg,
    transparent 40%,
    rgba(255, 255, 255, 0.3) 50%,
    transparent 60%);
  opacity: 0;
  transition: opacity 0.6s ease;
}

.login__button:hover {
  background: linear-gradient(135deg, 
    rgba(45, 189, 104, 1) 0%, 
    rgba(37, 160, 88, 1) 100%);
  box-shadow: 0 6px 30px rgba(45, 189, 104, 0.6),
              inset 0 1px 0 rgba(255, 255, 255, 0.3);
  border-color: rgba(45, 189, 104, 0.8);
}

.login__button:hover::after {
  opacity: 1;
}

.login__button:disabled {
  background: rgba(60, 60, 60, 0.3);
  color: rgba(227, 227, 227, 0.3);
  border-color: rgba(227, 227, 227, 0.1);
  box-shadow: none;
}

.login__button:disabled:hover {
  background: rgba(60, 60, 60, 0.3);
}

.login__button-text {
  display: inline;
}

.login__button-loader {
  font-size: 1.5rem;
  color: #000000;
  display: none;
}

.login__button--loading .login__button-loader {
  display: inline-block;
}

/* FOOTER */

.login__terms-text {
  color: rgba(227, 227, 227, 0.5);
  font-size: 0.75rem;
  font-weight: 400;
  font-family: "Nunito", sans-serif;
}

.login__terms-link {
  color: rgba(45, 189, 104, 0.9);
  font-weight: 500;
  text-decoration: none;
}

.login__terms-link:hover {
  color: #3DD378;
  text-decoration: underline;
}

.login__custom-message {
  color: #E3E3E3;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  font-weight: 500;
  letter-spacing: -0.02em;
  font-family: "Inter", sans-serif;
  font-size: 1.5625rem;
}

/* FEEDBACK */

#loader {
  color: #000000;
}

.font-error {
  color: #ff6b6b;
  font-weight: 400;
  background: rgba(255, 107, 107, 0.1);
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid rgba(255, 107, 107, 0.3);
  backdrop-filter: blur(10px);
  font-family: Inter, sans-serif;
  font-size: 0.875rem;
  margin-top: 2rem;
  max-width: 23.875rem;
}

/* RESPONSIVE DESIGN */

@media (min-width: 48rem) {
  .login__section--form {
    width: 35%;
    order: 1;
  }
  
  .login__section--image {
    width: 65%;
    order: 2;
    display: flex;
  }
}

/* INPUT GROUPS */

.login__input-group-container {
  gap: 1.25rem;
}

.login__input-group {
  animation: fadeInUp 0.6s ease backwards;
}

.login__input-group:nth-child(1) {
  animation-delay: 0.1s;
}

.login__input-group:nth-child(2) {
  animation-delay: 0.2s;
}

.login__input-group:nth-child(3) {
  animation-delay: 0.3s;
}

/* ANIMATIONS */

@keyframes fadeInUp {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
```

</details>

<figure><img src="https://884329393-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MhzNRg0B4ECiNXc093G%2Fuploads%2FVj2PqNtk5k8ZEXQgiNkb%2Fimage.png?alt=media&#x26;token=dad2a6a5-f763-4a46-a14b-3f7946533591" alt=""><figcaption></figcaption></figure>

### Login Component Classes Reference

#### Class Hierarchy

The login page follows a strict hierarchical BEM structure with the root container `login__viewport` containing all sub-elements.

{% code expandable="true" %}

```html
login__viewport (Root)
├── login__notification-container
└── login__wrapper
    ├── login__background
    │   └── login__background--app (modifier)
    └── login__container
        ├── login__section
        │   ├── login__section--form (modifier)
        │   ├── login__section--image (modifier)
        │   └── login__section--image-app (modifier)
        │
        ├── [LEFT SIDE - Form Section]
        │   ├── login__logo-link
        │   │   └── login__logo-image
        │   ├── login__title
        │   └── login__form
        │       ├── login__input-group-container
        │       │   └── login__input-group
        │       │       ├── login__input-group--workspace (modifier)
        │       │       ├── login__label
        │       │       ├── login__input
        │       │       └── login__input-wrapper
        │       │           ├── login__input-wrapper--icon (modifier)
        │       │           ├── login__input
        │       │           └── login__icon
        │       │               └── login__icon--eye (modifier)
        │       ├── login__forgot-link
        │       ├── login__actions-container
        │       │   └── login__button
        │       │       ├── login__button--loading (modifier)
        │       │       ├── login__button-text
        │       │       └── login__button-loader
        │       └── login__terms-container
        │           └── login__terms-text
        │               └── login__terms-link
        │
        └── [RIGHT SIDE - Image Section]
            └── login__custom-message
```

{% endcode %}

### Classes by Section

#### Outer Container Classes

The parent class for the outer structure is `login__viewport`.

1. `login__viewport` - Root container for entire login page
2. `login__notification-container` - Container for notifications/alerts
3. `login__wrapper` - Main wrapper around login experience
4. `login__background` - Background layer
   1. `login__background--app` - App-specific background modifier
5. `login__container` - Main login container with border and shadow

***

#### Section Classes

The parent class for the sections is `login__container`.

1. `login__section` - Base section container
   1. `login__section--form` - Form section (LEFT SIDE)
   2. `login__section--image` - Image/branding section (RIGHT SIDE)
   3. `login__section--image-app` - App-specific image section modifier

***

#### Logo & Branding

The parent class for the logo is `login__section--form`.

1. `login__logo-link` - Logo link wrapper
   1. `login__logo-image` - Logo image element

***

#### Title

The parent class for the title is `login__section--form`.

1. `login__title` - Main login heading

***

#### Form Wrapper

The parent class for the form is `login__section--form`.

1. `login__form` - Form wrapper element

***

#### Input Groups

The parent class for the input groups is `login__form`.

1. `login__input-group-container` - Container for all input groups
   1. `login__input-group` - Individual input group wrapper
      1. `login__input-group--workspace` - Workspace input group modifier
      2. `login__label` - Input label element
      3. `login__input` - Input field element
      4. `login__input-wrapper` - Wrapper for inputs with icons
         1. `login__input-wrapper--icon` - Modifier for icon wrapper
         2. `login__input` - Input field element
         3. `login__icon` - Icon element
            1. `login__icon--eye` - Eye icon modifier (password visibility toggle)

***

#### Forgot Password Link

The parent class for the forgot password link is `login__form`.

1. `login__forgot-link` - Forgot password link

***

#### Actions Container

The parent class for the actions container is `login__form`.

1. `login__actions-container` - Container for action buttons
   1. `login__button` - Login button element
      1. `login__button--loading` - Loading state modifier
      2. `login__button-text` - Button text element
      3. `login__button-loader` - Loading spinner element

***

#### Terms Container

The parent class for the terms container is `login__form`.

1. `login__terms-container` - Terms section container
   1. `login__terms-text` - Terms text element
      1. `login__terms-link` - Terms link element

***

#### Custom Message

The parent class for the custom message is `login__section--image`.

1. `login__custom-message` - Custom branding message (tagline/message on right panel)

### CSS Properties Guide

#### Safe to Modif

* `color` - Text colors
* `background` - Background colors and gradients
* `border` - Border styles and colors
* `border-radius` - Corner rounding
* `font-family` - Font choices
* `font-size` - Text sizes
* `font-weight` - Text weights
* `box-shadow` - Shadow effects
* `filter` - Visual filters (grayscale, blur, etc.)
* `backdrop-filter` - Blur and glass morphism effects
* `padding` - Internal spacing
* `margin` - External spacing
* `transform` - Translations, rotations, scaling
* `transition` - Animation transitions
* `opacity` - Transparency
* `width` - Element width
* `height` - Element height

#### Properties to Avoid

* `position: absolute` - May break layout (use relative positioning instead)
* `!important` - Security restriction
* `behavior` - Security restriction
* `expression` - Security restriction
* `javascript:` - Security restriction
* `data:text` - Security restriction
* `vbscript:` - Security restriction
* `file:` - Security restriction
* `ftp:` - Security restriction

#### Responsive Design Considerations

The login page is mobile-responsive by default. Key breakpoints:

* **Mobile (< 768px):** Single column layout, full width form
* **Tablet (768px+):** Split layout appears, form on left, branding on right
* **Desktop (72.5rem+):** Full featured layout with max constraints

Keep these breakpoints in mind when customizing:

```css
@media (min-width: 48rem) {
  .login__section--form {
    width: 50%;
  }
  
  .login__section--image {
    display: flex;
    width: 50%;
  }
}
```

#### Font Customization

Import custom fonts and apply globally:

```css
:root {
  --font-family-primary: "Your Custom Font", sans-serif;
}

*:not([role="icon"]) {
  font-family: var(--font-family-primary);
}
```

#### Transitions and Animations

Use CSS variables for consistent animation timing:

```css
:root {
  --transition-fast: 0.3s ease;
  --transition-normal: 0.2s ease;
}

.login__input {
  transition: border-color var(--transition-fast);
}

.login__button {
  transition: background-color var(--transition-fast), 
              box-shadow var(--transition-fast);
}
```
