*** i map through an array and for every item m calling ListItem component so there should be 3 ListItems but only one is getting populated ,dont know what wrong please help
*** this my app js ***
import FeedbackList from "./components/FeedbackList";
import FeedbackStatus from "./components/FeedbackStatus";
import Header from "./components/Header";
import feedbackData from "./data/feedback";
function App() {
return (
<div className="App">
<Header/>
<FeedbackStatus feedback={feedbackData}/>
<FeedbackList/>
</div>
);
}
export default App;
*** this is my feedbacklist component , where i map through feedbackData and for each item i m calling feedbackItem component , passed item as prop ***
import React from "react";
import FeedbackItem from "./FeedbackItem";
import { useState } from "react";
import feedbackData from "../data/feedback";
function FeedbackList() {
const [feedback, setFeedback] = useState(feedbackData);
return (
<div className="feedbackList">
<div className="imgcon">
<img
className="feedbackimage"
src="https://png.pngtree.com/png-clipart/20220930/original/pngtree-customer-reviews-with-people-giving-star-ratings-on-a-mobile-phone-png-image_8644419.png"
alt="feedback"
/>
</div>
<div className="showfeedback">
{feedback.map((item) => (
<FeedbackItem key={item.id} item={item} />
))}
</div>
</div>
);
}
export default FeedbackList;
*** my feedbackData ***
const feedbackData = [
{
id: 1,
rating: 10,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
{
id: 2,
rating: 9,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
{
id: 3,
rating: 8,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
]
export default feedbackData
*** this is my feedbackItem component , here i have received item as prop ***
import React from 'react'
function FeedbackItem({item}) {
return (
<div className='feedbackItem'>
<p className='rating'> {item.rating}</p>
<p className='review'></p>
</div>
)
}
export default FeedbackItem
*** this is my css if it helps ***
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#400;600;700&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Poppins', sans-serif;
background-color: rgb(9, 154, 154);
line-height: 1.6;
}
.heading{
text-align: center;
color: white;
max-width: 768px;
margin: auto;
padding: 0 20px;
}
.feedbackList{
display: flex;
height: 100vh;
}
.imgcon{
flex: 4;
justify-content: center;
align-items: center;
}
.showfeedback{
flex: 6;
}
.feedbackimage{
object-fit: cover;
width: 600px;
height: 600px;
margin-left: 100px;
margin-top: 100px;
background-attachment: fixed;
}
.feedbackItem{
border-radius: 20px;
background-color: aquamarine;
width: 50vw;
height: 20vh;
position: absolute;
margin-top: 110px;
margin-left: 50px;
margin-bottom: 50px;
}
.review{
text-align: center;
font-weight: 900;
margin: 10px 5px 5px 5px ;
color:#fff;
}
.rating{
display: flex;
justify-content: center;
align-items: center;
border-radius: 50px;
width: 30px;
height: 30px;
background-color: rgb(251, 221, 51);
text-align: center;
position: relative;
top: 5px;
left: 5px;
vertical-align: middle;
color: black;
}
.states{
display: flex;
justify-content: space-between;
align-items: center;
}
.states :nth-child(1){
margin-left: 20px;
}
.states :nth-child(2){
margin-right: 20px;
}
import FeedbackList from "./components/FeedbackList";
import FeedbackStatus from "./components/FeedbackStatus";
import Header from "./components/Header";
import feedbackData from "./data/feedback";
function App() {
return (
<div className="App">
<Header/>
<FeedbackStatus feedback={feedbackData}/>
<FeedbackList feedbackData={feedbackData}/>
</div>
);
}
export default App;
function FeedbackList(props) {
const [feedback, setFeedback] = useState(props.feedbackData);
return (
<div className="feedbackList">
<div className="imgcon">
<img
className="feedbackimage"
src="https://png.pngtree.com/png-clipart/20220930/original/pngtree-customer-reviews-with-people-giving-star-ratings-on-a-mobile-phone-png-image_8644419.png"
alt="feedback"
/>
</div>
<div className="showfeedback">
{feedback.map((item) => (
<FeedbackItem key={item.id} item={item} />
))}
</div>
</div>
);
}
Related
I tried to build this kind of FAQ question boxes in my website:
If I click on "plus" icon or text, they won't be open. Therfore I think, there may be some errors in JavScript code.
These are codes of the FAQ boxes in HTML, CSS & JavaScript:
[But they are not working well]
// Showing/hiding FAQS answers
const faqs = document.querySelectorAll('.faq');
faqs.forEach(faq => {
faq.addEventListener('click', () => {
faq.classList.toggle('open');
// Changing icon
const icon = faq.querySelector('.faq__icon i');
if (icon.className === 'uil uil-plus') {
icon.className = "uil uil-minus"
} else {
icon.className = "uil uil-plus"
}
})
})
.faq {
padding: 2rem;
display: flex;
align-items: center;
gap: 1.4rem;
height: fit-content;
background: var(--color-primary);
cursor: pointer;
}
.faq h4 {
font-size: 1rem;
line-height: 2.2;
}
.faq__icon {
align-self: flex-start;
font-size: 1.2rem;
}
.faq p {
margin-top: 0.8rem;
display: none;
}
.faq.open p {
display: block;
}
<article class="faq">
<div class="faq__icon"><i class="uil uil-plus"></i></div>
<div class="question__answer">
<h4>Lorem Ipsum ?</h4>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptates sapiente odio natus excepturi, culpa rem deleniti? Cum pariatur aut nulla a recusandae sit itaque voluptatem optio! Possimus, iure! Mollitia, voluptatum?</p>
</div>
</article>
I do not know how to do this; can you help me, please?
I'm new to the front-end world, and I'm trying to make a "responsive" card grid, meaning I want to place an unknown number of cards inside a grid and make the text and layout fit
nicely. I'm using react-bootrap Card and CardGroup, this is what I got so far.
If I use too many Cards, they get horizontally stretched and don't create new rows for a better layout, I'd expect to have a min-width so if it doesn't fit it creates a new row, but I'm not sure how to get this done or if it's the best practice.
Sorry if some of the terms are incorrect; I just started learning as mentioned.
Here is my GridCard.js code
import React from "react";
import {Card, CardGroup, Button} from "react-bootstrap";
import "./CardGrid.css"
const CardGrid = () => {
return (
<CardGroup>
{Array.from({ length: 10 }).map((_, index) => (
<Card className={"card-grid"} key={index}>
<Card.Img className={"card-img"} variant="bottom" src={"https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_960_720.jpg"}/>
<Card.Body>
<Card.Title><strong>Lorem ipsum dolor sit amet</strong></Card.Title>
<Card.Text>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores harum, illum.
Accusamus assumenda commodi consequuntur cumque, delectus deleniti dolorum eum illum
nam nostrum provident quaerat quisquam quos reiciendis, reprehenderit voluptas!</p>
</Card.Text>
<Button variant="primary"
href="www.google.com"
rel={"noopener noreferrer"}>
Learn More
</Button>
</Card.Body>
</Card>
))}
</CardGroup>
)
}
export default CardGrid
and my CardGrid.css
.card-group {
justify-content: center;
}
.card-grid, .card {
padding: 5px 5px !important;
height: auto !important;
justify-content: center;
margin: 1rem;
}
.card-body {
background-color: #F6F5F5;
margin: 0;
}
.card-img,
.card-img-top,
.card-img-bottom {
height: 10rem;
width: auto;
align-content: flex-start;
}
.card-text {
height: fit-content;
margin-bottom: 2rem;
}
.btn, .btn-primary {
position: absolute;
bottom: 5px;
color: #263238;
overflow: auto;
}
this is something complex I used in another project, this is the parent grid container
.parent{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(40rem, 1fr));
grid-gap: 2rem;
margin-block: 2rem;
padding: 0 1rem;
justify-items: center;
align-items: center;
}
Where the grid-template-columns creates a column size from a minimum of 40rem and a maximun of 1fr. You can play with the sizes.
But if you're looking for something simpler, I'd use display flex and flex-wrap like this
.parent{
display:flex;
max-width: 1200px;
flex-wrap: wrap;
}
UPDATE...
Apparently what we were missing was assigning a width to the card component, we fixed it by using min-width to the card component
This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 3 years ago.
I am a very new developer attempting to make a presentable photo-gallery-esque type thing to practice a bit. I have been leaning on CSS grid heavily for my layout...and I am pretty proud of what I have thus far.
I have four cards each containing an image thumbnail, a header, and some text. When the user hovers over any card they have the option to "view" the image which brings up a full screen modal. Everything works as I have intended...however...when I decrease the screen size some cards end up disappearing off screen!
I am very new to CSS grid and I have tried just about everything I know at this point. Please help me cross the finish line!
The code below works perfectly if just copy-pasted into the html portion on codepen.io.
Thank you in advance for any help you may offer!
const buttons = document.querySelectorAll('button');
const modal = document.querySelector('.modal');
const image = modal.querySelector('img');
buttons.forEach(button => {
button.addEventListener('click', handleButtonClick);
});
function handleButtonClick(event) {
const card = event.currentTarget.closest('.card');
const chosenImage = card.querySelector('img').src;
image.src = chosenImage;
modal.classList.add('open');
}
document.addEventListener('click', function(event) {
const target = event.target;
const isModal = target.classList[0] === 'modal';
if (isModal) {
modal.classList.remove('open');
}
});
body {
margin: 0;
height: 100vh;
display: grid;
align-content: center;
background: linear-gradient(0deg, rgba(130, 109, 118, 1) 0%, rgba(172, 52, 52, 1) 100%);
}
.wrapper {
display: grid;
grid-gap: 40px;
justify-content: center;
grid-template-columns: repeat(auto-fit, 300px);
grid-template-rows: 450px;
grid-auto-rows: 450px;
}
.card {
border: solid 5px #ac3434;
border-radius: 0.8rem;
overflow: hidden;
background: #3a363670;
display: grid;
grid-gap: 4px;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(8, 1fr);
}
.img-wrapper {
grid-column: 2 / span 3;
grid-row: 2 / span 3;
display: grid;
}
.img-wrapper img {
height: 100%;
width: 100%;
object-fit: cover;
border: solid 3px #ac3434;
border-radius: 50%;
}
.card-body {
grid-column: 1 / -1;
grid-row: 5 / -1;
padding: 0 10px 0;
font-family: 'Ubuntu', sans-serif;
}
.card-body h2 {
font-family: 'Anton', sans-serif;
}
.card-overlay {
grid-column: 1 / -1;
grid-row: 1 / -1;
background: #ac34347a;
display: grid;
place-items: center center;
transform: translateY(100%);
transition: 0.4s;
}
.card:hover .card-overlay {
transform: translateY(0%);
}
.card-overlay button {
background: none;
color: white;
text-transform: uppercase;
position: relative;
bottom: 78px;
border: solid 3px white;
border-radius: 0.4rem;
font-family: 'Ubuntu', sans-serif;
}
.modal {
height: 100vh;
width: 100vw;
position: fixed;
background: #0000008f;
display: grid;
place-items: center center;
/* Make modal invisible until triggered */
opacity: 0;
/* Makes it so the modal does not log click
events */
pointer-events: none;
}
.open {
/* Displays the modal */
opacity: 1;
pointer-events: all;
}
.modal-inner {
width: 500px;
}
.modal-inner img {
width: 100%;
height: 100%;
object-fit: contain;
}
<div class="wrapper">
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Sunny Walls</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim cupiditate molestias sed ea sit, dolore quos itaque consectetur doloribus at. Dolor accusamus consequuntur perspiciatis! Deserunt?
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Kit-the-Kat</h2>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dignissimos quaerat veritatis nobis voluptas minus exercitationem.
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Sass in the City</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo accusantium consectetur vel ullam assumenda corrupti id ratione odio, nisi adipisci?
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>City Things</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint culpa suscipit libero consequatur quod non dolore neque aperiam nihil beatae? Dolores, deserunt.
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
</div>
<div class="modal">
<div class="modal-inner">
<img>
</div>
</div>
You need to use media tags in the css.
Your site is not responsive and when you change screen size it does not resize the components.
https://www.w3schools.com/css/css_rwd_mediaqueries.asp
My navbar have a title named LOGO ABCD,
I try to set when scrolling down change colour by adding and removing class,
but no idea why not work
LOGO ABCD
A
B
C
D
nav.navbar {
transition: 0.5s;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top {
background-color: Black;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top a {
color : white;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top a:hover {
color : yellow;
}
$(window).scroll(function(evt){
if ($(window).scrollTop()>0)
$(".navbar").removeClass("navbar-top");
else
$(".navbar").addClass("navbar-top");
});
.PJ_title{color:grey;}
.PJ_color{color:red;}
$(window).scroll(function(evt){
if ($(window).scrollTop()>300)
$(".PJ_title").removeClass("PJ_color");
else
$(".PJ_title").addClass("PJ_color");
});
I test and "Test Title" has changed color successfully.
You can run lower snippet and scroll down and see change color. What's the problem?
$(window).scroll(function(evt){
if ($(window).scrollTop()>0)
$(".navbar").removeClass("navbar-top");
else
$(".navbar").addClass("navbar-top");
});
$(window).scroll(function(evt){
if ($(window).scrollTop()>300)
$(".PJ_title").removeClass("PJ_color");
else
$(".PJ_title").addClass("PJ_color");
});
nav.navbar {
transition: 0.5s;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top {
background-color: Black;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top a {
color : white;
}
nav.navbar.navbar-default.navbar-fixed-top.navbar-top a:hover {
color : yellow;
}
.PJ_title{color:grey;}
.PJ_color{color:red;}
.PJ_title{ position: fixed; }
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style='height: 1000px'>
<nav class='navbar navbar-default navbar-fixed-top navbar-top'>
<a>Test</a>
</nav>
<h1 class='PJ_title'>Test Title</h1>
</body>
</html>
Here's how you can do this. In the scroll function use, this.scrollY. Based on the value, add or remove classes as you see fit.
$(document).ready(function() {
$(window).scroll(function(evt) {
var scrollPos = this.scrollY;
if (scrollPos > 200) {
$(".navbar").removeClass("navbar-green");
$(".navbar").addClass("navbar-blue");
} else {
$(".navbar").addClass("navbar-green");
$(".navbar").removeClass("navbar-blue");
}
});
});
nav.navbar {
background-color: #ccc;
transition: all 0.5s ease-out;
}
nav.navbar-fixed-top {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
.extra-long {
height: 200vw;
}
nav.navbar-green {
background-color: green;
}
nav.navbar-blue {
background-color: blue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="extra-long">
<nav class="navbar navbar-fixed-top">
<p>LOGO ABCD</p>
<p>A</p>
</nav>
</div>
Here's a version of your code cleaned up that works. You'll have to change the color as needed:
const w = $(window);
const header = $('#main-header');
w.on('scroll', function() {
if(w.scrollTop() > 0) {
header.addClass('header-secondary');
} else {
header.removeClass('header-secondary');
}
});
html {
height: 100%;
}
body {
margin: 0;
font-family: sans-serif;
height: 100%;
}
header {
width: 100%;
display: flex;
position: fixed;
align-items: center;
background-color: #ccc;
height: 50px;
transition: background-color ease .3s;
}
header nav {
margin-left: auto;
padding-right: 15px;
}
header nav a {
text-decoration: none;
}
#logo {
font-weight: 700;
padding-left: 15px;
}
.header-secondary {
background-color: darkblue;
color: #fff;
}
.header-secondary nav a {
color: #fff;
}
main {
padding: 65px 15px 0;
background-color: salmon;
height: 200%;
}
main p {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header id="main-header">
<p id="logo">LOGO ABCD</p>
<nav>
item
item
item
</nav>
</header>
<main>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis adipisci totam odit natus voluptates ducimus impedit provident eum quia asperiores vitae neque ullam deserunt enim dolore minima, cum, perferendis et laborum. Magni, odit. Ducimus reiciendis illo assumenda dignissimos? Quidem eligendi molestiae atque mollitia, exercitationem officia. Debitis incidunt voluptas explicabo aliquam.</p>
</main>
I'm creating a testimonials page for my site, and some of the testimonials I have are rather long. As such I want to cut out anything longer than 3 lines.
To read the rest, the user clicks a button and the text expands to reveal the rest.
I've managed to do the above with line-clamp, however I'd like to have the ... clickable and styled with a different text. Is this possible?
I couldn't find a way to do that, so I tried a workaround. First I find out which elements have overflow so the [Read More] can be inserted. However it gets inserted at the end of the text, and not before the overflow.
I'm clueless as to how to solve this.
Desired result:
Current result (jsfiddle)
HTML
<div class="testimonial container-fluid">
<div class="col-xs-3 rating-container">
<div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</div>
<div class="col-xs-9">
<div class="title">Title</div>
<div class="content">Lorem ipsum dolor sit amet, vero essent gubergren ad pro, regione epicuri contentiones ea mea. Decore omnium id vim, pro et malis molestie, et porro nostro vis. Ei libris debitis reprehendunt est. Te per delenit scaevola scripserit. Partem erroribus rationibus ea vel, nihil euismod ei vim.
His sonet antiopam cotidieque ea, eu unum melius conclusionemque his. Ferri iisque sanctus pri ei. Ut ius tantas nonumy intellegam. Et per solum aliquam, melius elaboraret at qui.</div>
<div class="name_loc" id="demo">Name, London</div>
</div>
</div>
CSS
.testimonial {
width: 920px;
display: -webkit-box;
background-color: #EFEFEF;
color: #333;
padding: 8px;
margin: 0 0 20px;
border: 3px solid #506790;
}
.testimonial:nth-of-type(even) {
background-color: #EFEFEF;
}
.testimonial .rating-container {
height: 144px;
display: table;
}
.testimonial .rating-container > div {
display: table-cell;
vertical-align: middle;
}
.testimonial .star {
width: 32px;
height: 32px;
display: inline-block;
background-repeat: no-repeat;
background-image: url('http://www.timelinecoverbanner.com/cliparts/wp-content/digital-scrapbooking/lemon-star-md1.png');
background-size: cover;
}
.testimonial .title {
font-size: 18pt;
text-align: left;
font-weight: bold;
}
.testimonial .content {
-webkit-box-orient: vertical;
display: -webkit-box;
margin: 5px 0 10px;
font-size: 12pt;
text-align: left;
overflow: hidden;
height: 68px;
}
.testimonial .name_loc {
font-style: italic;
font-size: 12pt;
text-align: right;
}
JS
$('#demo').on('click', function() {
var t = $(this).closest('.testimonial');
var c = t.find('.content');
var h3 = c[0].scrollHeight;
c.animate({'height':h3},500);
});
$('.testimonial').each(function() {
var c = $(this).find('.content');
if (c.height() < c[0].scrollHeight) {
c.css('text-overflow', 'ellipsis');
//also tried:
c.css('line-clamp', '3');
}
});
You could do this with the ::after pseudo-element. I was playing with your fiddle and it seemed to work.
First the .content class needs to be positioned relative. Then add two new CSS classes:
.testimonial .content.collapsed {
/* styles removed from .content */
overflow: hidden;
height: 68px;
}
.testimonial .content.collapsed::after {
display: inline-block;
content: "...";
position: absolute;
bottom: 0;
right: 5px;
}
You could add the click handler to the pseudo element in the JS (I didn't try this part), and then remove the "collapsed" class after the click. You could also style the pseudo element any way you want, or change the content to "Read more..." or whatever.
Try fiddling with your revised JsFiddle. It uses:
$('.testimonial').on(
'click',
'.content',
function(e) {
if (this.scrollHeight > this.offsetHeight) {
$(this).removeClass('clipped')
.addClass('unclipped')
.css('height', this.scrollHeight+'px');
} else {
$(this).removeClass('unclipped')
.addClass('clipped')
.css('height', '');
}
}
);
and 2 extra css-classes: clipped and unclipped:
.clipped:after {
position: absolute;
content: '>';
top: 2.9em;
color: red;
font-weight: bold;
cursor: pointer;
}
.unclipped:after {
position: absolute;
content: '<';
top: 2.9em;
color: green;
font-weight: bold;
cursor: pointer;
}
What about this: http://jsfiddle.net/6nb0wwc3/1/
I added a "readme" div, which on click, shows the complete text.
<div class="name_loc" id="demo">Name, London</div>
<div class="readmore">Read more</div>
$('.readmore').each(function() {
$(this).click( function() {
$(this).parent().find('.content').css('height','100%');
$(this).hide();
});
});
Hope it helps