I've been trying to build this UI for almost a day.
I'm just stuck with not getting the middle div in the center of the screen and the last Copyright div align to the bottom of the screen. I'm a mobile dev first, just started out styling on web. This is what I've managed to build so far, ignore rest of the UI, I can do that part. Here's the sandbox for my code as well : https://codesandbox.io/s/tailwind-css-and-react-forked-v9c22d?file=/src/App.js:140-2801
<div className="bg-background-light dark:bg-background-dark h-screen w-full">
<div>
<img
src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a"
className="h-24 w-24 mt-9 ml-9"
/>
<div className="flex justify-center items-center h-fit">
<div className="flex flex-col items-start">
<div className="text-4xl text-black">Admin Dashboard</div>
<div className="text-login-subtitle-light dark:text-login-subtitle-dark mt-6">
Enter your email and password to sign in
</div>
<label className="dark:text-white text-text-color-primary-light mt-6">
Email
</label>
<input
placeholder="Email"
className="w-full rounded font-thin px-5 py-3 mt-4"
autoFocus
type="email"
required
/>
<label className="dark:text-white text-text-color-primary-light mt-6">
Password
</label>
<input
placeholder="Password"
id="password"
className="w-full rounded font-thin px-5 py-3 mt-4"
autoFocus
type="password"
required
/>
<label
for="default-toggle"
class="inline-flex relative items-center cursor-pointer"
>
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600 mb-5"></div>
<input
type="checkbox"
value=""
id="red-toggle"
class="sr-only peer"
checked
/>
<span class="ml-3 text-sm font-medium text-text-color-primary-light dark:text-white mb-5">
Remember me
</span>
</label>
<button
className="text-white bg-red-900 h-16 rounded-xl w-full text-xl"
type="submit"
>
Sign In
</button>
<div className="text-black dark:text-white">
© Example Technologies Pvt. Ltd.
</div>
</div>
</div>
</div>
</div>
Problem highlight, as you can see the second div starts as soon as the image ends
After adding your code and when I scroll, so when we add a bottom padding to the copyright view, it creates a white bg when I open the console, is this the expected behaviour?
You need to set the logo and the copyright absolute. The copyright can you stick to the bottom and left and right side with bottom-0 left-0 right-0, and center the text with text-center.
Then, you need to add flex to the parent div, and then m-auto to the div with the fields. This will center the div horizontal and vertical on the page (in the main div). I also set a background on it so you can see the div, but that is not necessary of cause.
Here is the code:
import React from "react";
import "./styles.css";
import "./styles/tailwind-pre-build.css";
export default function App() {
return (
<div className="relative flex bg-background-light dark:bg-background-dark h-screen w-full">
<img
src="https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a"
className="absolute h-24 w-24 mt-9 ml-9"
/>
<div className="m-auto bg-gray-500 rounded-lg p-8">
<div className="flex justify-center items-center h-fit">
<div className="flex flex-col items-start">
<div className="text-4xl text-black">Admin Dashboard</div>
<div className="text-login-subtitle-light dark:text-login-subtitle-dark mt-6">
Enter your email and password to sign in
</div>
<label className="dark:text-white text-text-color-primary-light mt-6">
Email
</label>
<input
placeholder="Email"
className="w-full rounded font-thin px-5 py-3 mt-4"
autoFocus
type="email"
required
/>
<label className="dark:text-white text-text-color-primary-light mt-6">
Password
</label>
<input
placeholder="Password"
id="password"
className="w-full rounded font-thin px-5 py-3 mt-4"
autoFocus
type="password"
required
/>
<label
for="default-toggle"
class="inline-flex relative items-center cursor-pointer"
>
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600 mb-5"></div>
<input
type="checkbox"
value=""
id="red-toggle"
class="sr-only peer"
checked
/>
<span class="ml-3 text-sm font-medium text-text-color-primary-light dark:text-white mb-5">
Remember me
</span>
</label>
<button
className="text-white bg-red-900 h-16 rounded-xl w-full text-xl"
type="submit"
>
Sign In
</button>
</div>
</div>
</div>
<div className="absolute bottom-0 left-0 right-0 text-center text-black dark:text-white">
© Example Technologies Pvt. Ltd.
</div>
</div>
);
}
Related
I'm creating a blog with next.js, the blog uses a modal for updating or adding new blogs and their content. I'm struggling with the tailwindcss. I'm trying to center the modal but it goes off the screen.
Here is my code but it doesn't work.
const styles = {
modal: `flex justify-center place-self-center vertical-align-center`,
wrapper: `h-full grid grid-cols-1 gap-4 rounded-xl bg-gray-50 max-w-sm mx-autoflex flex-col
justify-start items-center gap-[1rem] p-[1rem] m-auto font-mediumSerif overflow-scroll`,
title: `my-[2rem] font-bold text-3xl`,
smallField: `w-full flex justify-between gap-[1rem]`,
fieldTitle: `flex-1 text-end`,
inputContainer: `flex-[5] h-min border-2 border-[#787878]`,
inputField: `w-full border-0 outline-none bg-transparent`
}
const PostModal = () => {
return (
<div className={styles.modal}>
<div className={styles.wrapper}>
<div className={styles.title}>Create a New Post</div>
<div className={styles.smallField}>
<span className={styles.fieldTitle}>Title</span>
<span className={styles.inputContainer}>
<input
className={styles.inputField}
type='text'
/>
</span>
</div>
<div className={styles.smallField}>
<span className={styles.fieldTitle}>Brief</span>
<span className={styles.inputContainer}>
<input
className={styles.inputField}
type='text'
/>
</span>
</div>
<div className={styles.smallField}>
<span className={styles.fieldTitle}>Banner Image Url</span>
<span className={styles.inputContainer}>
<input
className={styles.inputField}
type='text'
/>
</span>
</div>
<div className={styles.smallField}>
<span className={styles.fieldTitle}>Category</span>
<span className={styles.inputContainer}>
<input
className={styles.inputField}
type='text'
/>
</span>
</div> <div className={styles.smallField}>
<span className={styles.fieldTitle}>Estimated Read Length (in minutes)</span>
<span className={styles.inputContainer}>
<input
className={styles.inputField}
type='text'
/>
</span>
</div>
<div className={styles.smallField}>
<span className={styles.fieldTitle}>Article Text</span>
<span className={styles.inputContainer}>
<textarea
className={styles.inputField}
type='text'
rows={12}
/>
</span>
</div>
</div>
</div>
)
}
export default PostModal;
I tried justify-center, tiems-aling, flex, but nothing works, h-screen, adjusting the width and height, but nothing so far.
The simplest way to center something using tailwind CSS is to use the grid system
Pass this to the outer container
<div className="grid h-screen place-items-center">{children}</div>
or using flex
<div className="flex items-center justify-center h-screen">
{children}
</div>
I'm trying to vertically align the placeholder of the third input field. Assuming that "text-start" and "text-end" classes when used with placeholder modifier in tailwind vertically align the placeholder text. But weirdly, in my case, "text-start" & "text-end" are doing the same as "text-left" & "text-right" respectively.
<div class="flex flex-col space-y-8">
<div class="flex flex-col space-y-4 w-[540px]">
<input class="placeholder-Eerie-Black text-[13px] font-normal tracking-[0px] leading-[15px] bg-Amber border-2 border-opacity-50 border-Eerie-Black rounded-lg h-[50px] p-2" placeholder="Name and Surname*">
<input class="placeholder-Eerie-Black text-[13px] font-normal tracking-[0px] leading-[15px] bg-Amber border-2 border-opacity-50 border-Eerie-Black rounded-lg h-[50px] p-2" placeholder="Email*">
<input class="placeholder:text-end placeholder-Eerie-Black text-[13px] font-normal tracking-[0px] leading-[15px] bg-Amber border-2 border-opacity-50 border-Eerie-Black rounded-lg h-[98px] p-2 text-start" placeholder="Please provide as much detailed information as possible. Thank you *">
</div>
<button class="bg-Green w-[210px] h-[50px] rounded-lg">SUBMIT MESSAGE</button>
</div>
After doing a bit of research about the issue, I got to know that adding class placeholder:-translate-y-6
fixes this bug. But still curious why the above mentioned classes aren't doing this.
I'm using tailwind and Vue to make some reusable toggle component. Border of component is gray color, but plan is when I click on component, border will be red like on a image below (I'm using/trying using focus).
Problem is because I can use focus just on input and button, but I need focus on div tag
I have one div, inside is two paragraph and one input (type:checkbox). I tried with tabindex and it doesn't work, when I click in checkbox or input field (gray button) it doesn't focus. Only focuses when I click inside a component but not in checkbox field.
Code is
<template>
<div>
<div tabindex="1"
class="relative border border-gray-300 px-10 max-w-md mx-auto my-2 cursor-pointer rounded-lg px-5 py-4 rounded-lg border bg-white transition duration-150
ease-in-out placeholder:text-zinc-400 hover:bg-zinc-100 focus:border-transparent
focus:outline-none focus:ring disabled:opacity-50 motion-reduce:transition-none
dark:bg-zinc-900 dark:placeholder:text-zinc-500 dark:hover:bg-zinc-800" :class="[ error
? 'border-red-500 caret-red-500 focus:ring-red-500/50'
: 'border-zinc-300 caret-primary focus:ring-primary/50 dark:border-zinc-600 dark:focus:border-transparent',
]"
>
<div class="flex justify-between">
<div>
<h1 class="text-md font-semibold text-black">
{{ titleToggle }}
</h1>
<p class="inline text-md text-gray-500">
{{ subtitleToggle }}
</p>
</div>
<label class="switch my-auto">
<input
:value="toggleSwitch"
v-bind="$attrs" type="checkbox"
class="rounded-lg " :class="[
error
? 'border-red-500 caret-red-500 focus:ring-red-500/50'
: 'border-zinc-300 caret-primary focus:ring-primary/50
dark:border-zinc-600 dark:focus:border-transparent',]" #click="updateInput"
>
<span :class="[toggleSwitch ? 'bg-red-500 border-red-500' : 'bg-gray-300 border-gray-300',
]" class="slider round absolute cursor-pointer inset-0 border rounded-full"
/>
</label>
</div>
</div>
</div>
</template>
Is anyone have advice, or maybe different way how to do it ?
I don't really understand your question, but you may have a look at this from the tailwind documentation :
focus-within (:focus-within) : Style an element when it or one of its descendants has focus using the focus-within modifier:
<div class="focus-within:shadow-lg ...">
<input type="text" />
</div>
https://tailwindcss.com/docs/hover-focus-and-other-states#focus
I am using Tailwind + Headless UI to create a hamburger Menu bar on mobile to show the menu on click. But when I click on the menu it does not close automatically and creates a bad UX.
<Disclosure
as="nav"
className="fixed top-0 left-0 right-0 z-10 w-full bg-white shadow"
>
{({ open }) => (
<>
<div className="px-2 mx-auto max-w-7xl sm:px-4 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex px-2 lg:px-0">
<div className="flex items-center flex-shrink-0">
<Link href="/">
<a className="relative block w-12 h-12">
<Image
src="/img/logo.png"
alt="NFT Volt Logo"
layout="fill"
className="w-auto h-6 lg:block"
/>
</a>
</Link>
</div>
<div className="hidden lg:ml-6 lg:flex lg:space-x-1">
{navLinks.map((link) => (
<NavLink key={link.id} href={link.href}>
{link.name}
</NavLink>
))}
</div>
</div>
<div className="flex items-center justify-center flex-1 px-2 lg:ml-6 lg:justify-end">
<div className="w-full max-w-lg lg:max-w-xs">
<label htmlFor="search" className="sr-only">
Search
</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<SearchIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</div>
<input
id="search"
name="search"
className="block w-full py-2 pl-10 pr-3 leading-5 placeholder-gray-500 bg-white border border-gray-300 rounded-md focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder="Search NFT projects..."
type="search"
/>
</div>
</div>
<Link href="/list-project" passHref>
<a
href="#"
className="items-center hidden px-4 py-2 ml-6 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm lg:inline-flex hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 whitespace-nowrap"
>
List your Project
</a>
</Link>
</div>
<div className="flex items-center lg:hidden">
{/* Mobile menu button */}
<Disclosure.Button className="inline-flex items-center justify-center p-2 text-gray-400 rounded-md hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500">
<span className="sr-only">
Open main menu
</span>
{open ? (
<XIcon
className="block w-6 h-6"
aria-hidden="true"
/>
) : (
<MenuIcon
className="block w-6 h-6"
aria-hidden="true"
/>
)}
</Disclosure.Button>
</div>
</div>
</div>
<Disclosure.Panel className="lg:hidden">
<div className="pt-2 pb-3 space-y-1">
{/* {navLinks.map((link) => (
<NavLinkMobile
key={link.id}
href={link.href}
onClick={() => {
console.log('click');
close();
}}
>
{link.name}
</NavLinkMobile>
))} */}
{navLinks.map((link) => (
<Disclosure.Button
as={NavLinkMobile}
key={link.id}
href={link.href}
>
{link.name}
</Disclosure.Button>
))}
<NavLinkMobile href="/list-project">
List your Project
</NavLinkMobile>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
Tried to add manually close on click but doesn't seem to work.
The trick is to wrap the links with <Disclosure.Button> </Disclosure.Button> and it will close automatically the panel.
See: https://headlessui.dev/react/disclosure#closing-disclosures-manually
Use can use the close prop from Disclose itself.
import it this way ({ open, close }) and use it
onClick={() => {
close();
}}
Try using Next.js Router's push function to navigate the user when the Disclosure.Button is clicked.
At the top of your component, call the useRouter hook:
const router = useRouter();
With that, you can modify your JSX by adding an onClick property where you then call router.push({path}) , like this:
{
navLinks.map((link) => (
<Disclosure.Button
as="a"
key={link.id}
onClick={() => {
router.push(`${link.href}`);
}}
>
{link.name}
</Disclosure.Button>
));
}
Using the Next.js router will navigate the user to the desired href while still allowing the Disclosure render prop to toggle from open to closed.
For more infomation, check out - https://nextjs.org/docs/api-reference/next/router#routerpush
I have a simple login form on a sliding modal. On desktop and in responsive mode with dev tools it looks as it should. However on mobile Chrome and Safari -- on an iphone, there's a weird gray rounded box or shadow.
I'm using tialwind css. And the component was built with headless ui.
I've tried adding -webkit-appearance: none; to the form, but the box still persits.
Here's how it looks on desktop:
desktop view
and here is how it looks on my iphone:
mobile view
here is the component code:
return (
<Transition.Root show={showModal.open} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 overflow-hidden"
onClose={() => setShowModal({ open: false })}
>
<div className="absolute inset-0 overflow-hidden">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-500"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-500"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="absolute inset-0 bg-black bg-opacity-80 transition-opacity" />
</Transition.Child>
<div className="fixed inset-y-0 right-0 pl-10 max-w-full flex">
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-500 sm:duration-700"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-500 sm:duration-700"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<div className="w-screen max-w-md">
<div className="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll">
<div className="px-4 sm:px-6">
<div className="flex items-start justify-between">
<Dialog.Title className="text-2xl font-light text-vhGreen">
Welcome!
</Dialog.Title>
<div className="ml-3 h-7 flex items-center">
<button
type="button"
className="bg-white rounded-md text-vhGreen hover:text-gray-500 focus:outline-none"
onClick={() => setShowModal({ open: false })}
>
<span className="sr-only">Close panel</span>
<XCircleIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
</div>
</div>
<div className="mt-6 relative flex-1 px-4 sm:px-6">
{/* Replace with your content */}
<div className="absolute inset-0 px-4 sm:px-6">
<div className="relative p-6 flex-auto bg-white">
<h4 className="text-vhGreen font-light">
Login or sign up to gain access to the gallery and to
receive periodic updates from Thea
</h4>
<form
type="submit"
onSubmit={(e) => handleSubmit(e)}
className="bg-white"
>
{isNewUser && (
<>
<div className="my-4 text-sm">
<label className="block text-vhGreen">
First Name
</label>
<input
value={authForm.firstName || ""}
onChange={(e) => handleChange(e)}
type="text"
name="firstName"
placeholder="First Name"
className="w-full px-4 py-3 rounded-md text-vhGreen font-light"
/>
</div>
<div className="my-4 text-sm">
<label className="block text-vhGreen">
Last Name
</label>
<input
value={authForm.lastName || ""}
onChange={(e) => handleChange(e)}
type="text"
name="lastName"
placeholder="Last Name"
className="w-full px-4 py-3 rounded-md"
/>
</div>
</>
)}
<div className="my-4 text-sm">
<label className="block text-vhGreen">Email</label>
<input
value={authForm.email || ""}
onChange={(e) => handleChange(e)}
type="text"
name="email"
placeholder="Email"
className="w-full px-4 py-3 rounded-md"
/>
</div>
<div className="my-4 text-sm">
<label className="block text-vhGreen">
Password
</label>
<input
value={authForm.password || ""}
onChange={(e) => handleChange(e)}
type="password"
name="password"
placeholder="Password"
className="w-full px-4 py-3 rounded-md"
onKeyDown={(e) => onKeyDown(e)}
/>
<div className="flex justify-end text-vhGreen text-sm font-light">
<button
type="button"
onClick={() => handleNewSwitch()}
>
{!isNewUser
? "Need an account? Sign Up!"
: "Already have an account? Login!"}
</button>
</div>
</div>
</form>
</div>
{/*footer*/}
<div className="flex items-center justify-center p-6 border-t border-solid border-blueGray-200 rounded-b">
<button
className="text-vhGreen background-transparent font-light uppercase px-6 py-2 text-xl outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
type="button"
onClick={(e) => handleSubmit(e)}
>
{isNewUser ? "Sign Up" : "Login"}
</button>
</div>
</div>
{/* /End replace */}
</div>
</div>
</div>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
);
faced same thing.
The problem is in:
type="button"
Try to remove that, works for me