so I've made this simple popup with tailwindcss that will show project description.
This is how it looks:
import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react";
import Button from "../../../components/elements/Button";
import ReactMarkdown from "react-markdown";
import { Repo } from "../../../lib/types/Repos";
interface PageProps {
setIsOpen: Dispatch<SetStateAction<boolean>>;
project: Repo;
}
export default function ProjectDescription({ setIsOpen, project }: PageProps) {
useEffect(() => {
document.body.style.overflow = "hidden";
}, []);
const close = () => {
document.body.style.overflow = "auto";
setIsOpen(false);
};
return (
<div
onClick={close}
className="fixed inset-0 h-full w-full flex z-20 justify-center items-center p-4 cursor-pointer"
style={{ backgroundColor: "rgba(0,0,0,0.3)" }}
>
<div className="bg-gray-50 shadow-md scrollbar z-[9999999] max-w-xl max-h-[600px] w-full h-auto px-8 py-8 overflow-auto rounded-md">
<div className="flex justify-between items-center">
<p className="text-gray-700">
Project built with:{" "}
<strong className="text-indigo-600">{project.language}</strong>
</p>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-8 text-gray-900 cursor-pointer"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
onClick={close}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</div>
{project.readme && (
<ReactMarkdown
children={project.readme}
className="prose prose-indigo"
/>
)}
<div className="mt-4">
<Button>Webiste</Button>
<a className="ml-4">Github</a>
</div>
</div>
</div>
);
}
Now the problem is that this container(upper div) has click event, and first div inside him also has same event??? Basically I can click on div inside and close modal. And that should not happen? Could someone please explain what's happening.
If you give onClick event to parent div you call same event by click the child dive. It is because the first thing you click is again will be the parent. Give z-9999 insted of z-[9999999] to the child div. Usually what you want to do when making a modal is set onClick(close) event to button not to entirly div itself. In your case you can set onHide(close) to parent div. With this way you close the modal by clicking outside of the modal.
Related
I'm facing a strange problem while setting width and height of the video tag. I'm using Image component (from next/image), which is setting its height automatically.
It always shows height of 413px even if I use image with 150x150 dimensions. I'm not seeing any absolute height rule in CSS inspector even for parent elements or this Image component.
Actually it is the desired behavior (width/height) of the Image. I'm trying to do the same thing with the video tag. But it shrinks itself down to actual height of the video if video is smaller in height.
Video should not change it's height because it shares same CSS properties and has same container as Image. I'm also using object-fit:cover property.
Code for the component is:
import React, { useState } from 'react';
import Image from 'next/image';
import { IExclusiveCard } from '../../../typings/types';
import Link from 'next/link';
import useNFTMetadata from '../../../hooks/useNftMetaData';
import { BsFillPlayFill, BsPauseFill } from 'react-icons/bs';
const ExclusiveCard: React.FC<IExclusiveCard> = ({
id,
photo_name,
metadataUri,
cardInfo,
cardType,
cardInfoBg,
title,
desc,
collectionType,
asset_url,
thumbnail,
}) => {
let { data } = useNFTMetadata(metadataUri as string);
if (!metadataUri?.trim() && thumbnail && asset_url) {
data = {
asset_url,
thumbnail,
};
}
const [videoPaused, setVideoPaused] = useState(true);
let href = '';
if (collectionType === 'continuous') {
href = `/exclusives/${id}/auction`;
} else if (collectionType === 'editions') {
href = `/editions/${id}/mint`;
}
const image = data?.thumbnail || data?.image || photo_name;
const description = desc || data?.description || '';
return (
<Link href={href}>
<a className='h-full block'>
<div
className="token-card--items h-full w-[382px] md:w-full md:min-w-[216px] md:max-w-[216px] md:h-[317px] lg:w-[290px] laptop-x:w-[300px] laptop-m:w-[350px] desktop-m:w-[350px] rounded-3xl overflow-hidden bg-primary lg:rounded-2xl"
key={id}
>
<div className="token-img-cont-box h-full relative">
<div className="tokens-img-wrap h-full relative">
<div className="exclusive--card-img h-full w-full relative md:h-[317px]">
{/* If thumbnail exists, show video instead of an image */}
{!videoPaused && data?.asset_url ? (
<video
style={{
height: '100%',
objectFit: 'cover',
}}
src={data?.asset_url}
autoPlay
loop
muted
onEnded={() => setVideoPaused(true)}
/>
) :
image ? (
<Image
// src={image}
src={"https://picsum.photos/id/1/150/150"}
alt="tokens-card-img"
className="token-card-img h-full w-full object-cover"
width="382px"
height="520px"
/>
) : (
<div className="slim-nft-card-placeholder-bg rounded-[20px]"></div>
)}
</div>
<div className="tokens-card-top-cont flex justify-end items-start absolute top-0 left-0 p-5 w-full md:p-2">
<span
className={[
'card-updates-info text-fig-15 uppercase text-secondary block text-center font-primary font-normal rounded-[100%] w-[62px] h-[62px] leading-[62px] laptop-x:text-fig-12 laptop-x:w-[45px] laptop-x:h-[45px] laptop-x:leading-[45px] lg:w-[36px] lg:h-[36px] lg:text-fig-xs lg:leading-[36px]',
`bg-${cardInfoBg}`,
].join(' ')}
>
{cardInfo}
</span>
</div>
<div className="token-card-content-box pt-[13px] pb-4 px-6 absolute bottom-0 left-0 z-50 lg:px-4 w-full">
<h3 className="card-title font-primary font-normal text-fig-32 text-left text-secondary uppercase mb-4 laptop-x:text-fig-24 lg:text-fig-base lg:mb-2">
{title || data?.properties?.title}
</h3>
<p className="desc mb-8 text-fig-xs text-left text-secondary font-primary font-normal md:text-fig-xs md:mb-2">
{/* Truncate desc or data?.description if it is greater than 30 characters */}
{description.length > 50
? description.slice(0, 50) + '...'
: description}
</p>
<div
className={`token-cards-bottom flex ${
data?.thumbnail ? 'justify-between' : 'justify-end'
} w-full`}
>
{data?.thumbnail && (
<h3 className="card-type font-primary font-normal text-fig-32 text-right laptop-x:text-fig-24 text-white uppercase lg:text-fig-15 lg:mb-0">
{videoPaused ? (
<BsFillPlayFill
onClick={(ev) => {
ev.preventDefault();
setVideoPaused(false);
}}
className="text-4xl"
/>
) : (
<BsPauseFill
onClick={(ev) => {
ev.preventDefault();
setVideoPaused(true);
}}
className="text-4xl"
/>
)}
</h3>
)}
<h3 className="card-type font-primary font-normal text-fig-32 text-right laptop-x:text-fig-24 text-darkgray uppercase lg:text-fig-15 lg:mb-0">
{cardType}
</h3>
</div>
</div>
</div>
</div>
</div>
</a>
</Link>
);
};
export default ExclusiveCard;
I'm not sure what I'm missing here. What should I do to get same size of video like Image when I click play icon?
Cannot figure out how to get popover to close when next Link is clicked inside. Used popover from tailwindui and added next Link, tried the headlessUI closing popover using as={Link}, no luck.
<div className='max-w-7xl mx-auto grid gap-y-6 px-4 py-6 sm:grid-cols-2 sm:gap-8 sm:px-6 sm:py-8 lg:grid-cols-4 lg:px-8 lg:py-12 xl:py-16'>
{about.map((item) => (
<Popover.Button key={item.name}>
<Link href={item.href}>
<a
href={item.href}
className='-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50'>
<div className='flex md:h-full lg:flex-col'>
<div className='flex-shrink-0'>
<span className='inline-flex items-center justify-center h-10 w-10 rounded-md bg-cyan-500 text-white sm:h-12 sm:w-12'>
<item.icon
className='h-6 w-6'
aria-hidden='true'
/>
</span>
</div>
<div className='ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4'>
<div>
<p className='text-base font-medium text-gray-900'>
{item.name}
</p>
<p className='mt-1 text-sm text-gray-500'>
{item.description}
</p>
</div>
<p className='mt-2 text-sm font-medium text-cyan-600 lg:mt-4'>
Learn more
<span aria-hidden='true'>
→
</span>
</p>
</div>
</div>
</a>
</Link>
</Popover.Button>```
Help please, what am i missing?
I just ran into this exact issue.
I got it working by doing two things referenced separately in the Headless UI docs. This involved creating a custom wrapper component for Next's Link and exposing the close() render prop on the Popover Panel.
A minimal example using the solution is listed first followed by an explanation with references to the docs.
Solution/Example
import { forwardRef } from 'react'
import Link from 'next/link'
import { Popover } from '#headlessui/react'
const MyLink = forwardRef((props, ref) => {
let { href, children, ...rest } = props
return (
<Link href={href}>
<a ref={ref} {...rest}>
{children}
</a>
</Link>
)
})
function Example() {
return (
<Popover>
{({ open }) => (
<>
<Popover.Button>Open Popover</Popover.Button>
<Popover.Panel>
{({ close }) => (
<MyLink href='/profile' onClick={() => close()}>
Profile
</MyLink>
)}
</Popover.Panel>
</>
)}
</Popover>
)
}
Explanation
Step 1
Expose the close() render prop inside your Popover Panel, per the alternative solution suggested in the docs.
<Popover.Panel>
{({ close }) => (
We will call this in our link to manually close the popup when the link is clicked.
Step 2
Create your own custom MyLink component (or whatever name you want) that wraps Link and forwards props to the child a element. As explained in the Headless UI docs, Next's Link component doesn't forward unknown props by default and Headless needs to do this in order to work by adding the necessary event listeners.
const MyLink = forwardRef((props, ref) => {
let { href, children, ...rest } = props
return (
<Link href={href}>
<a ref={ref} {...rest}>
{children}
</a>
</Link>
)
})
I am trying to make a 404 page with Nextjs and typescript. Here are the screenshots:
As you see, I have the scrollbar on both the right and bottom sides and they are breaking the responsiveness.
I gave the background color to make this noticeable.
Here's my code...
import Link from "next/link";
import { useRouter } from "next/router";
import React from "react";
interface Props {}
const ErrorPage: React.FC<Props> = ({}) => {
const router = useRouter();
return (
<>
<div className="bg-gray-900 h-screen w-screen flex justify-center items-center absolute z-0">
<svg
className="p-6 lg:p-48 fill-current text-gray-300"
viewBox="0 0 445 202"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
// viewBox="0 0 24 24"
>
<path
d="M137.587 154.953h-22.102V197h-37.6v-42.047H.53v-33.557L72.36 2.803h43.125V124.9h22.102v30.053zM77.886 124.9V40.537L28.966 124.9h48.92zm116.707-23.718c0 22.46 1.842 39.643 5.525 51.547 3.684 11.905 11.23 17.857 22.64 17.857 11.411 0 18.89-5.952 22.44-17.857 3.548-11.904 5.323-29.086 5.323-51.547 0-23.54-1.775-40.97-5.324-52.29s-11.028-16.98-22.438-16.98c-11.41 0-18.957 5.66-22.64 16.98-3.684 11.32-5.526 28.75-5.526 52.29zM222.759.242c24.887 0 42.339 8.76 52.356 26.28 10.018 17.52 15.027 42.406 15.027 74.66s-5.01 57.095-15.027 74.525c-10.017 17.43-27.47 26.145-52.356 26.145-24.887 0-42.339-8.715-52.357-26.145-10.017-17.43-15.026-42.271-15.026-74.525 0-32.254 5.009-57.14 15.026-74.66C180.42 9.001 197.872.241 222.76.241zm221.824 154.711h-22.102V197h-37.6v-42.047h-77.355v-33.557l71.83-118.593h43.125V124.9h22.102v30.053zM384.882 124.9V40.537l-48.92 84.363h48.92z"
fillRule="nonzero"
/>
</svg>
</div>
<div className="h-screen w-screen flex justify-center items-center relative z-10">
<div className="p-6 text-center">
<h2 className="uppercase text-xl lg:text-5xl font-black">
We are sorry, Page not found!
</h2>
<p className="mt-3 uppercase text-sm lg:text-base font-semibold text-gray-900">
The page you are looking for might have been removed had its name
changed or is temporarily unavailable.
</p>
<div className="text-center">
<Link href="/">
<a
className="mt-6 m-auto bg-primary text-white py-4 px-6 w-1/3 block rounded-full tracking-wide
font-semibold font-display focus:outline-none focus:shadow-outline hover:bg-primaryAccent
shadow-lg transition-css"
>
Back To Homepage
</a>
</Link>
<button
onClick={() => router.back()}
className="mt-6 m-auto bg-primary text-white py-4 px-6 w-1/4 block rounded-full tracking-wide
font-semibold font-display focus:outline-none focus:shadow-outline hover:bg-primaryAccent
shadow-lg transition-css"
>
Go Back
</button>
</div>
</div>
</div>
</>
);
};
export default ErrorPage;
Is this happening because of h-screen and w-screen or is something wrong with flex? But if I don't use them, I don't make it to work as I am expecting which is placing one div above the other (absolute). I am probably looking at this code for too long and I am lost in space.
So, what am I doing wrong here? Thanks.
I would suggest to have a parent relative div
<div class="h-screen w-screen relative">
<!-- 404 -->
<div class="bg-gray-900 flex justify-center items-center absolute inset-0 z-0"> // inset-0 is important
<svg></svg>
</div>
<!-- content -->
<div class="flex justify-center items-center absolute inset-0 z-10">
</div>
</div>
I replicated your design.
I would recommend changing h-screen to min-h-screen.
You can check out an example using your code in the following link.
https://play.tailwindcss.com/eD7VEDN5AR
"width: 100vw" is breaking the page layout. There's a horizontal scrollbar appearing on the page.
That's because the w-screen property means "width: 100vw" (the element with such a property is supposed to consume the whole available device screen space horizontally).
As you have a vertical scrollbar on the page body () (as the body is probably bigger in height than the screen height (= 100vh)), you'll always have less gorizontal space than 100vw, as the horizontal space is also consumed by the vertical scrollbar.
It's not a TailwindCSS-related issue, but rather a CSS-related bug.
The vertical scrollbar's width is usually ~12 px, but it differs between OS'es and screen sizes.
What I think would be better is if CSS would count the available screen width for the 100vw property considering the scrollbar width, like 100vw = real screen width - (vertical scrollbar's width, if one is present).
"(height: 100vh // max-height: 100vh)" is breaking the page layout. There's a vertical scrollbar appearing
That's because the w-screen property means "width: 100vw" (the element with such a property is supposed to consume the whole available device screen space horizontally).
As you have a vertical scrollbar on the page body () (as the body is probably bigger in width than the screen width (= 100vw)), you'll always have less vertical space than 100vh, as the vertical space is also consumed by the horizontal scrollbar.
The horizontal scrollbar's width is usually ~12 px, but it differs between OS'es and screen sizes.
For this case CSS could count the property for the 100vh value like 100vh = real screen height - (horizontal scrollbar's height, if one is present).
What can be done now:
You better use width: 100% and height: 100% properties instead of width: 100vw and height: 100vh
It's always risky to use the vh and vw values. Why would you need that? Semantically, the child should always be smaller than the parent.
This is the same ugly workaround as hiding the problems with overflowing with "overflow-x: hidden".
So your code should look like:
import Link from "next/link";
import { useRouter } from "next/router";
import React from "react";
interface Props {}
const ErrorPage: React.FC<Props> = ({}) => {
const router = useRouter();
return (
<>
<div className="bg-gray-900 h-full w-full flex justify-center items-center absolute z-0">
<svg
className="p-6 lg:p-48 fill-current text-gray-300"
viewBox="0 0 445 202"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
// viewBox="0 0 24 24"
>
<path
d="M137.587 154.953h-22.102V197h-37.6v-42.047H.53v-33.557L72.36 2.803h43.125V124.9h22.102v30.053zM77.886 124.9V40.537L28.966 124.9h48.92zm116.707-23.718c0 22.46 1.842 39.643 5.525 51.547 3.684 11.905 11.23 17.857 22.64 17.857 11.411 0 18.89-5.952 22.44-17.857 3.548-11.904 5.323-29.086 5.323-51.547 0-23.54-1.775-40.97-5.324-52.29s-11.028-16.98-22.438-16.98c-11.41 0-18.957 5.66-22.64 16.98-3.684 11.32-5.526 28.75-5.526 52.29zM222.759.242c24.887 0 42.339 8.76 52.356 26.28 10.018 17.52 15.027 42.406 15.027 74.66s-5.01 57.095-15.027 74.525c-10.017 17.43-27.47 26.145-52.356 26.145-24.887 0-42.339-8.715-52.357-26.145-10.017-17.43-15.026-42.271-15.026-74.525 0-32.254 5.009-57.14 15.026-74.66C180.42 9.001 197.872.241 222.76.241zm221.824 154.711h-22.102V197h-37.6v-42.047h-77.355v-33.557l71.83-118.593h43.125V124.9h22.102v30.053zM384.882 124.9V40.537l-48.92 84.363h48.92z"
fillRule="nonzero"
/>
</svg>
</div>
<div className="h-full w-full flex justify-center items-center relative z-10">
<div className="p-6 text-center">
<h2 className="uppercase text-xl lg:text-5xl font-black">
We are sorry, Page not found!
</h2>
<p className="mt-3 uppercase text-sm lg:text-base font-semibold text-gray-900">
The page you are looking for might have been removed had its name
changed or is temporarily unavailable.
</p>
<div className="text-center">
<Link href="/">
<a
className="mt-6 m-auto bg-primary text-white py-4 px-6 w-1/3 block rounded-full tracking-wide
font-semibold font-display focus:outline-none focus:shadow-outline hover:bg-primaryAccent
shadow-lg transition-css"
>
Back To Homepage
</a>
</Link>
<button
onClick={() => router.back()}
className="mt-6 m-auto bg-primary text-white py-4 px-6 w-1/4 block rounded-full tracking-wide
font-semibold font-display focus:outline-none focus:shadow-outline hover:bg-primaryAccent
shadow-lg transition-css"
>
Go Back
</button>
</div>
</div>
</div>
</>
);
};
export default ErrorPage;
In the case of TailwindCSS, you should use h-full and w-full instead of h-screen and w-screen.
Also, in your specific case it's this line that was breaking everything, most likely:
<div className="h-screen w-screen flex justify-center items-center relative z-10">
As you already have this applied to the parent element:
<div className="bg-gray-900 h-screen w-screen flex justify-center items-center absolute z-0">
It's all wrong semantically in your code. This is ugly work-arounding.
You haven't provided the tailwind.config.js, so some of the colors in the demo are missing due to missing custom TailwidnCSS class names values.
But this is basically the same code with an exception of eplacing all -screen properties with -full and also removing the bottom padding of the svg, as on most of the screens, the svg has too much spacing and then consumes >100vh space of the screen and is not positioned at the center vertically, but rather has starneg white space at the bottom of the page.
https://dpd0jl.sse.codesandbox.io/
Recently I created a Custom Navmenu (using TailwindCSS) in my Blazor WebAssembly project.
Depending on the device-width a sidebar is being showed / hidden (with the use of Tailwind hidden and device-with CSS classes).
On a specific device-width a menu button is being showed, a div which is specific for the mobile sidebar is always hidden (with display: none), in Blazor I have created an #onclick function which sets the style of the mobile sidebar to empty (so display: none is being removed) and vice-versa.
This all works perfectly, however there is one problem with this approach. When the menu button is clicked, the mobile side-bar is being showed, if I now increase the device-width the menu button is being hidden automatically and so is the mobile sidebar, if i then decrease the device-width again the menu button is showed again but the 'opened' sidebar div is also being showed (because in the last smaller device-width is was also opened (style of display:none was removed).
The behavior should be, when the device width is increased the mobile-side bar should always retain its style property display:none.
Though, as far is I know there is no event in Blazor which triggers on a changed device width? is there any way to get this working?
Below some images and HTML code which shows the 'problem':
Normal size view:
Mobile view:
Mobile sidebar opened view:
So the problem is that when I go from Mobile sidebar opened view back to Normal size view and then back to Mobile view, it will show the Mobile sidebar opened view instead (because it still has an empty style property, which is equivalent to display: block)
The HTML / Blazor C# code :
<div class="md:hidden" style=#mobileSideBarDisplay> <!-- Blazor C# string that sets the display to display: none, or removes the display entirely to show it)
<div class="fixed inset-0 flex z-40">
<!--
Off-canvas menu overlay, show/hide based on off-canvas menu state.
Entering: "transition-opacity ease-linear duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "transition-opacity ease-linear duration-300"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0">
<div class="absolute inset-0 bg-gray-600 opacity-75"></div>
</div>
<!-- The menu item with is Blazor onclick event -->
<div class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-gray-800">
<div class="absolute top-0 right-0 -mr-14 p-1">
<button class="flex items-center justify-center h-12 w-12 rounded-full focus:outline-none focus:bg-gray-600" aria-label="Close sidebar" #onclick="ToggleSidebar">
<svg class="h-6 w-6 text-white" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<! -- rest of HTML, left out for readability -->
</div>
</div>
</div>
<!-- Static sidebar for desktop -->
<div class="hidden md:flex md:flex-shrink-0">
<div class="flex flex-col w-64">
<! -- rest of HTML, left out for readability -->
</div>
</div>
<!-- Horizontal navbar with the Menu button -->
<div class="flex flex-col w-0 flex-1 overflow-hidden">
<div class="relative z-10 flex-shrink-0 flex h-16 bg-white shadow">
<!-- menu button becomes visible at a certain device-width > done with the TailWind CSS class md:hidden -->
<button class="px-4 border-r border-gray-200 text-gray-500 focus:outline-none focus:bg-gray-100 focus:text-gray-600 md:hidden" aria-label="Open sidebar" #onclick="ToggleSidebar">
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7" />
</svg>
</button>
<! -- rest of HTML, left out for readability -->
</div>
</div>
<!-- C# code for viewing mobile sidebar on Menu button press -->
#code {
private bool showMobileSideBar = false;
private string mobileSideBarDisplay => showMobileSideBar ? "" : "display: none;";
private void ToggleSidebar()
{
showMobileSideBar = !showMobileSideBar;
}
}
You need js interop and the window.resize event.
There are libraries that can help, like this one https://github.com/EdCharbeneau/BlazorSize
This answer is for anybody else who is here and interested in using a UI library.
In addition to #rdmpton's answer, MudBlazor has a component: <MudBreakpointProvider> which lets you get access to window resize values.
Check out the Getting Started Docs.
Use it like this:
<MudBreakpointProvider>
<MudHidden Breakpoint="Breakpoint.Xl" Invert="true">
<MudCard Class="pa-5">
<MudText>XL</MudText>
</MudCard>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.Lg" Invert="true">
<MudCard Class="pa-5">
<MudText>LG</MudText>
</MudCard>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.Md" Invert="true">
<MudCard Class="pa-5">
<MudText>MD</MudText>
</MudCard>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.Sm" Invert="true">
<MudCard Class="pa-5">
<MudText>SM</MudText>
</MudCard>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.Xs" Invert="true">
<MudCard Class="pa-5">
<MudText>XS</MudText>
</MudCard>
</MudHidden>
</MudBreakpointProvider>
Moreover, they have tons of other components to help you build nice UIs.
I have been struggling trying to make TailwindCSS work with Angular. I followed some tutorials and looked in the documentation of Tailwind. For some reason in certain places in the Angular 9 application it's working and in lazy loaded modules it's not (so it seems)!
So first thing I did was following and implementing these tutorials:
https://dev.to/seankerwin/angular-8-tailwind-css-guide-3m45
https://dev.to/beavearony/building-tailwind-css-in-an-angular-cli-project-e04
I know for sure I have these installed correctly because of the following:
My sidebar(app-sidebar) is having the correct css and styling! But the page I'm on loaded through the is not.
I will provide you with my app-routing.module, and the default layout and the dashboard component. On this Dashboard the tailwindCSS is not loading. (Funny thing: if I add an H1 element with no class, no nothing I see this element on the dashboard page!) The other elements which contain some kind of tailwindCSS class don't. Also if I drag-and-drop through the content of my dashboard component to outside this dashboard component I see my elements, although without any styling. (I do this with Chrome DevTools)
app-routing.module.ts
{
path: 'login',
loadChildren: () => import('./modules/login/login.module').then(m => m.LoginModule)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full',
},
{
path: '',
component: DefaultLayoutComponent,
children:[
{
path: 'dashboard',
loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule)
}
]
},
{ path: '**', redirectTo: '' }
];
default-layout.component.html
<div class="h-screen flex overflow-hidden bg-gray-100">
<app-sidebar></app-sidebar>
<div id="content">
<router-outlet></router-outlet>
</div>
</div>
dashboard.component.html
<h1>Dashboard</h1>
<div class="flex flex-col w-0 flex-1 overflow-hidden">
<div class="md:hidden pl-1 pt-1 sm:pl-3 sm:pt-3">
<button class="-ml-0.5 -mt-0.5 h-12 w-12 inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150" aria-label="Open sidebar">
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
</div>
<main class="flex-1 relative z-0 overflow-y-auto pt-2 pb-6 focus:outline-none md:py-6" tabindex="0">
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<h1 class="text-2xl font-semibold text-gray-900">Dashboard</h1>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<!-- Replace with your content -->
<div class="py-4">
<div class="border-4 border-dashed border-gray-200 rounded-lg h-96"></div>
</div>
<!-- /End replace -->
</div>
</main>
</div>
The following I have tried but no succes:
ViewEncapsulation (How to get Angular's <router-outlet> to work with CSS Grid)
Added on each page a link to the CDN with tailwindCSS
Does it maby has any thing to do with the lazy loaded module?
Or maby that there is a double router-outlet?
Because this is how my app.component.html looks
<router-outlet></router-outlet>
So I have figured it out. There were actually two things left I had to do.
First was to set the tailwindcss configuration (tailwind.config.js) and attach it to tailwindcss with the help of my webpack.config.js
module.exports = {
module : {
rules: [
{
test : /\.scss$/,
loader : 'postcss-loader',
options: {
ident : 'postcss',
syntax: 'postcss-scss',
plugins: () => [
require('postcss-import'),
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer')
]
}
}
]
}
};
Second thing I had to do was putting the overall class of the component to the host in my Angular Component.
dashboard.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
host: {
class: "flex flex-col w-0 flex-1 overflow-hidden"
}
})
export class DashboardComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
So looking back at my question and looking at the dashboard.component.html file, the highest div is removed and the class of that div is placed in host! Like above.
I have followed the first link in my question!