DEV Community

Connie Leung
Connie Leung

Posted on

Day 20 - Github Card project Part 3 - Styling

Table of Contents

Styling is actually the easiest part of the this exercise.
The steps are generally the same in the frameworks.

  1. Installed tailwindcss and DaisyUI
  2. Added DaisyUI plugin in a css file
  3. Copied the the card layout to the template
  4. Replaced the static text with profile values
  5. Replaced custom CSS classes with the equivalent tailwindcss utility classes

Installation

Vue 3 and SvelteKit

npm install tailwindcss@latest @tailwindcss/vite@latest daisyui@latest
Enter fullscreen mode Exit fullscreen mode

Add tailwind CSS to vite

import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [tailwindcss(), ...other plugins...],
});
Enter fullscreen mode Exit fullscreen mode

Enable daisyUI plugin in css

@import "tailwindcss";
@plugin "daisyui";
Enter fullscreen mode Exit fullscreen mode

Angular 20 application

npm install daisyui@latest tailwindcss@latest @tailwindcss/postcss@latest postcss@latest --force
Enter fullscreen mode Exit fullscreen mode

Configuration file

// .postcssrc.json
{
  "plugins": {
    "@tailwindcss/postcss": {}
  }
}
Enter fullscreen mode Exit fullscreen mode

Enable DaisyUI plugin in CSS

// src/style.css

@import "tailwindcss";
@plugin "daisyui";
Enter fullscreen mode Exit fullscreen mode

Apply Tailwind CSS utility classes

In the GithubProfileList component, the CSS utility classes can be applied to the header.

<div class="p-[0.75rem] col-span-full text-center">
    <h1 class="text-3xl">Github Profile List (Angular Ver.)</h1>
</div>
Enter fullscreen mode Exit fullscreen mode

The header class can be removed from the style sheet.

Moreover, the CSS grid layout can be styled by the utility classes

Vue 3 Application

In the template of the App Component

<div class="grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]">
    <GithubProfileList :usernames="usernames" />
</div>
Enter fullscreen mode Exit fullscreen mode

SvelteKit Application

// +layout.svelte

<div id="app" class="grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]">
    {@render children()}
</div>
Enter fullscreen mode Exit fullscreen mode

Angular 20 application

In the @Component decorator of the AppComponent, the styles property is modified

In order to use @apply in a CSS class, I must apply @reference to include the src/styles.css file without duplication.

styles: `
    @reference "../../../styles.css";

    :host {
        @apply grid grid-cols-2 pt-0 pb-0 pl-[2rem] pr-[2rem]
    }
`,
Enter fullscreen mode Exit fullscreen mode

The Grid layout is applied successfully in all frameworks

Beautified the Card Layout

The CSS styles are the same in the examples but the frameworks has different syntaxes in control flow and interpolation.

Vue 3 Application

// GithubProfileCard.vue

<div class="card card-side bg-base-100 shadow-sm" v-if="profile">
    <figure class="basis-[30%] grow shrink">
      <img :src="profile.avatar_url" :alt="profile.name" />
    </figure>
    <div class="card-body basis-[70%] grow shrink">
      <h2 class="card-title">{{ profile.login }}</h2>
      <p>Name: {{ profile.name }}</p>
      <p>Bio: {{ profile.bio || 'N/A' }}</p>
      <p>Followers: {{ profile.followers }}</p>
      <p>Following: {{ profile.following }}</p>
      <p>Public Repos: {{ profile.public_repos }}</p>
      <div class="card-actions justify-end">
        <button class="btn btn-primary">
          <a :href="profile.html_url" target="_blank" rel="noopener noreferrer">
            <span class="text-white">View Profile</span>
          </a>
        </button>
      </div>
    </div>
  </div>
  <div v-else-if="error">Error: {{ error }}</div>
Enter fullscreen mode Exit fullscreen mode

SvelteKit Application

// github-profile-card.svelte

<div>
    {#if profile}
        <div class="card card-side bg-base-100 shadow-sm">
            <figure class="basis-[30%] grow shrink">
                <img src={profile.avatar_url} alt={profile.name} />
            </figure>
            <div class="card-body basis-[70%] grow shrink">
                <h2 class="card-title">{ profile.login }</h2>
                <p>Name: { profile.name }</p>
                <p>Bio: { profile.bio || 'N/A' }</p>
                <p>Followers: { profile.followers }</p>
                <p>Following: { profile.following }</p>
                <p>Public Repos: { profile.public_repos }</p>
                <div class="card-actions justify-end">
                    <button class="btn btn-primary">
                        <a href={profile.html_url} target="_blank" rel="noopener noreferrer">
                            <span class="text-white">View Profile</span>
                        </a>
                    </button>
                </div>
            </div>
        </div>
    {:else if error}
        <div>
            <p>Error: {error}</p>
        </div>
    {/if}
</div>
Enter fullscreen mode Exit fullscreen mode

Angular 20 Application

@let status = profileResource.status();
@if (status === 'loading') {
    <p>Loading profile...</p>
} @else if (status === 'error') {
    <p>Error loading profile: {{ error() }}</p>
} @else {
    @if (profile(); as profile) {
        <div class="card card-side bg-base-100 shadow-sm" v-if="profile">
            <figure class="basis-[30%] grow shrink">
              <img [src]="profile.avatar_url" [alt]="profile.name" />
            </figure>
            <div class="card-body basis-[70%] grow shrink">
              <h2 class="card-title">{{ profile.login }}</h2>
              <p>Name: {{ profile.name }}</p>
              <p>Bio: {{ profile.bio || 'N/A' }}</p>
              <p>Followers: {{ profile.followers }}</p>
              <p>Following: {{ profile.following }}</p>
              <p>Public Repos: {{ profile.public_repos }}</p>
              <div class="card-actions justify-end">
                <button class="btn btn-primary">
                  <a [href]="profile.html_url" target="_blank" rel="noopener noreferrer">
                    <span class="text-white">View Profile</span>
                  </a>
                </button>
              </div>
            </div>
          </div>
    } @else if (error()) { 
        @let message = error();
        <div>Error: {{ message }}</div>
    }
}
Enter fullscreen mode Exit fullscreen mode


html

Github Repositories

Resources

Top comments (0)