I want to make a responsive web site using Tailwind CSS and Next.js, but I can't apply my custom responsive utility classes. I added my custom breakpoints in tailwind.config.js.
Other media queries are working fine.
I designated w-[600px] in max-1280px and w-[400px] in max-768, but I can't apply max-768 and another media query only applied max-1280px.
import React from 'react';
import profile from '../../assets/images/me.jpg';
import Image from 'next/image';
import Link from 'next/link';
import { aboutContent } from '../../data/aboutContent';
const about = () => {
return (
<div className='animate-fade-in-up'>
<h1 className='text-5xl font-appleSemiBold laptopM:text-center laptopM:underline laptopM:mb-12 tablet:text-4xl'>
About Me
</h1>
<div className='border-2 w-40 ml-[142px] mb-12 laptopM:hidden'></div>
<div className='flex flex-row justify-between items-center font-appleRegular laptopM:flex-col laptopM:gap-10'>
<Image
className='w-[600px] tablet:w-[400px]'
src={profile}
alt='Picture of me'
/>
<div className='w-6/12 laptopM:w-[600px] tablet:w-[400px]'>
<div className='text-2xl mb-8 tablet:text-xl'>
<p>test</p>
<p>
test
</p>
</div>
</div>
</div>
<div className='font-regular'></div>
</div>
);
};
export default about;
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,jsx,ts,tsx}',
'./components/**/*.{js,jsx,ts,tsx}',
],
theme: {
extend: {
screens: {
mobileS: { max: '320px' },
mobileM: { max: '375px' },
mobileL: { max: '425px' },
tablet: { max: '768px' },
laptop: { max: '1024px' },
laptopM: { max: '1280px' },
laptopL: { max: '1440px' },
},
},
plugins: [],
};
Related
I am trying to change the color of the text of my p tag but for some reason it is not working. I am very new to coding so any advice would help.
import React from 'react'
import { SocialIcon } from 'react-social-icons';
type Props = {}
export default function Header({}: Props) {
return (
<header className="sticky top-0 flex items-start justify-between max-w-7xl mx-auto z-20 xl:items-center">
<div className="flex flex-row items-center">
{/* Social Icons */}
<SocialIcon
url="https://"
fgColor="gray"
bgColor="transparent"
/>
<SocialIcon
url="https://"
fgColor="gray"
bgColor="transparent"
/>
</div>
<div className="flex flex-row items-center text-gray-300 cursor-pointer">
<SocialIcon
className="cursor-pointer"
network="email"
fgColor="gray"
bgColor="transparent"
/>
<p className="text-gray-400">Why wont this work</p>
</div>
</header>
);
}
**tailwind.config.js**
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./compnents/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
the line of code Why wont this work does not do anything and simply leaves the text black
I honestly have no idea what to do here. I thought the other div classNames might be affecting the p tag somehow so I tried deleting them but that didn't work either. Below I attached an image of it as proof.
enter image description here
Maybe your tailwind.confing.js is not correct or something wrong.
Tailwind Css supplies the public document.
please check here.
https://tailwindcss.com/docs/customizing-colors
For example, can you set your customize color on theme.extend.colors in tailwind.config.js ?
you can customize for what you expect.
Here is sample.
tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
gray: {
400: '#303030', // custom
},
}
},
},
}
Please rebuild your app after changing that config at last.
try it.
From my code below, If I comment out the pin: true property, the code works normally but the container that wraps the sections I expect to scroll horizontally are not sticky to the top. If I uncomment the pin: true, all the container (trigger) will not be visible.
Any suggestions on how to resolve this issue will be greatly appreciated.
import React, { useEffect } from "react";
import OverlayMenu from "./OverlayMenu";
import { gsap } from "gsap";
import ScrollTrigger from "gsap/dist/ScrollTrigger";
function MainContent({ overlayRef }) {
gsap.registerPlugin(ScrollTrigger);
useEffect(() => {
// alert(document.querySelector(".main__content").offsetWidth)
const sections = gsap.utils.toArray(".section");
gsap.to(sections, {
xPercent: -100 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: ".main__content",
scrub: 1,
markers: true,
start: "top top",
// // snap: 1 / (sections.length - 1),
end: "+=" + document.querySelector(".main__content").offsetWidth,
pin: true,
},
});
}, []);
return (
<div className="main__content__wrapper w-[calc(100%_-_80px)] h-screen ml-20">
<div className="w-full relative h-screen">
<OverlayMenu overlayRef={overlayRef} />
{/* <div className="w-full h-screen bg-black"></div> */}
<div className="main__content w-[300%] bg-purple-700 h-screen flex flex-nowrap">
<div className="section w-full h-screen- bg-red-500">1</div>
<div className="section w-full h-screen- bg-blue-500">2</div>
<div className="section w-full h-screen- bg-yellow-500">3</div>
</div>
</div>
</div>
);
}
export default MainContent;
Step back the version to 3.8.0
yarn add gsap#3.8.0
OR
npm install gsap#3.8.0
You can read more here:
https://greensock.com/forums/topic/30747-scrolltrigger-in-nextjs-build-not-working-reliably/#comment-153675
import React, { useEffect, useState } from "react";
import OverlayMenu from "./OverlayMenu";
import { gsap } from "gsap";
import ScrollTrigger from "gsap/dist/ScrollTrigger";
function MainContent({ overlayRef }) {
gsap.registerPlugin(ScrollTrigger);
const [hasRendered, setHasRendered] = useState(false);
useEffect(() => {
// ******This will set the state of hasRendered when the page render so as to keep track of the rendering steps *******
setHasRendered(true);
}, []);
useEffect(() => {
// ******* I added the conditional statement here to only create the instance of the gsap timeline ONLY after the page has rendered*******
if (hasRendered) {
// alert(document.querySelector(".main__content").offsetWidth)
const sections = gsap.utils.toArray(".section");
gsap.to(sections, {
xPercent: -100 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: ".main__content",
scrub: 1,
markers: true,
start: "top top",
// // snap: 1 / (sections.length - 1),
end: "+=" + document.querySelector(".main__content").offsetWidth,
pin: true,
},
});
}
}, [hasRendered]); //******** Dont forget the dependencies array too */
return (
<div className="main__content__wrapper w-[calc(100%_-_80px)] h-screen ml-20">
<div className="w-full relative h-screen">
<OverlayMenu overlayRef={overlayRef} />
{/* <div className="w-full h-screen bg-black"></div> */}
<div className="main__content w-[300%] bg-purple-700 h-screen flex flex-nowrap">
<div className="section w-full h-screen- bg-red-500">1</div>
<div className="section w-full h-screen- bg-blue-500">2</div>
<div className="section w-full h-screen- bg-yellow-500">3</div>
</div>
</div>
</div>
);
}
export default MainContent;
I have two components.In first MovieItem.js i created a card.In second Movies.js i am looping through an array of cards and displaying them in UI - 4 per row.I am using Tailwind grid template columns to do this, and it s working fine.
return (
<div className="grid grid-cols-4 gap-4">
{movies.map((movie) => (
<MovieItem key={movie.id} movie={movie}></MovieItem>
))}
</div>
);
However if the width of the screen is less then 640 pixels i want to show only one card per row which means that each card should have width 100% and that they should be all horizontally stacked on top of each other, but i am not getting any results with this.
return (
<div className="grid grid-cols-4 sm:grid grid-cols-1 gap-4">
{movies.map((movie) => (
<MovieItem key={movie.id} movie={movie}></MovieItem>
))}
</div>
);
MovieItem.js
import React from "react";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import AlternativeImage from "./AlternativeImage";
const MovieItem = ({ movie: { id, title, poster_path } }) => {
return (
<div className=" bg-gray-900 px-4 pt-4 pb-5 overflow-hidden rounded ">
{poster_path ? (
<img
src={"https://image.tmdb.org/t/p/w400/" + poster_path}
alt=""
className="w-full block content-center p-4 content-image"
/>
) : (
<AlternativeImage></AlternativeImage>
)}
<h6 className="text-base text-center text-white my-3 font-mono">
{title}
</h6>
<div className="button-container">
<Link
to={`/movie/${id}`}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded "
>
Movie Details
</Link>
</div>
</div>
);
};
export default MovieItem;
Movies.js
import React, { useContext } from "react";
import MovieItem from "./MovieItem";
import MovieContext from "../context/movie/movieContext";
const Movies = () => {
const movieContext = useContext(MovieContext);
const { movies } = movieContext;
return (
<div className="grid grid-cols-4 sm:grid grid-cols-1 gap-4">
{movies.map((movie) => (
<MovieItem key={movie.id} movie={movie}></MovieItem>
))}
</div>
);
};
export default Movies;
I also made necessary changes in Tailwind config file:
const tailwindcss = require("tailwindcss");
module.exports = {
theme: {
screens: {
xl: { max: "1279px" },
// => #media (max-width: 1279px) { ... }
lg: { max: "1023px" },
// => #media (max-width: 1023px) { ... }
md: { max: "767px" },
// => #media (max-width: 767px) { ... }
sm: { max: "639px" },
// => #media (max-width: 639px) { ... }
},
},
plugins: [tailwindcss("./tailwind.js"), require("autoprefixer")],
};
By default, Tailwind uses a mobile first breakpoint system, similar to what you might be used to in Bootstrap or Foundation.
What this means is that unprefixed utilities (like uppercase) take effect on all screen sizes, while prefixed utilities (like md:uppercase) only take effect at the specified breakpoint and above.
In your case, simply do this
grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 md:gap-4
Check docs.
I'm using inline style to style the HTML DOM element. I want to display converted plain CSS. I'm changing the inline style using component state.
I do the following. It prints the style objects. e.g.,
{"display":"flex","flexDirection":"column"}
import React, {Component} from 'react';
class Sample extends Component {
constructor(props) {
super(props);
this.state = {
style: {
display: "flex",
flexDirection: "column"
},
}
}
render() {
const {style} = this.state;
return (
<div>
<div style={style}>
<div id={1}>1</div>
<div id={2}>2</div>
<div id={3}>3</div>
<div id={4}>4</div>
</div>
<div>{JSON.stringify(style)}</div>
</div>
);
}
}
export default Sample;
I expect the output as plain CSS instead of inline style object. e.g., "display: flex; flex-direction: column;"
This is some hack, but it will fulfil your requirement.
import React, {Component} from 'react';
class Sample extends Component {
constructor(props) {
super(props);
this.state = {
style: {
display: "flex",
flexDirection: "column"
},
}
}
getStyle(){
let styled = '{';
Object.keys(this.state.style).forEach(e => {
let key = e.split(/(?=[A-Z])/).join('-').toLowerCase()
styled += `${key}:${this.state.style[e]};`
});
styled += '}'
return styled;
}
render() {
const {style} = this.state;
return (
<div>
<div style={style}>
<div id={1}>1</div>
<div id={2}>2</div>
<div id={3}>3</div>
<div id={4}>4</div>
</div>
<div>{this.getStyle()}</div>
</div>
);
}
}
export default Sample;
Demo
Best way would be configure webpack to extract css to a new file.
npm install extract-text-webpack-plugin --save-dev
npm install style-loader css-loader --save-dev
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]
}
I come across ReactJS ref document. And I tried the below way. It works as I was expecting. Demo
import React, { Component } from "react";
class Sample extends Component {
constructor(props) {
super(props);
this.itemContainerRef = React.createRef();
this.state = {
style: {
display: "flex",
flexDirection: "column"
},
itemContainerCSS: {}
};
}
componentDidMount() {
this.setState({
itemContainerCSS: this.itemContainerRef.current.style.cssText || {}
});
}
render() {
const { style, itemContainerCSS } = this.state;
return (
<div>
<div style={style} ref={this.itemContainerRef}>
<div id={1}>1</div>
<div id={2}>2</div>
<div id={3}>3</div>
<div id={4}>4</div>
</div>
<div>{JSON.stringify(itemContainerCSS)}</div>
</div>
);
}
}
export default Sample;
I ejected my create-react-app in order to use css modules. I modified my webpack.config.dev.js from
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true, //added this
localIdentName: "[name]__[local]___[hash:base64:5]" //added this
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
}
Then I tried to uss css modules in one of my components
import React, { Component } from 'react';
import styles from './sidebar.css';
class MenuPanel extends Component {
render() {
return (
<div>
<div className={styles.navbarSide}>
<div className="tessact-logo"></div>
<div className="navbar-item active">
<a className="navbar-item-link"><span className="fa fa-comment"></span> TRIVIA</a>
</div>
But className navbarSide didn't get applied to div. I see no className for that particular div. What am I doing wrong? Ideally that div should have got className navbarSide.
just add import { StyleSheet } from 'react-native';
import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import styles from './sidebar.css';
class MenuPanel extends Component {
render() {
return (
<div>
<div className={styles.navbarSide}>
<div className="tessact-logo"></div>
<div className="navbar-item active">
<a className="navbar-item-link"><span className="fa fa-comment"></span> TRIVIA</a>
</div>