{"id":4517,"date":"2026-06-08T19:36:37","date_gmt":"2026-06-08T16:36:37","guid":{"rendered":"https:\/\/notes.profidev.online\/?p=4517"},"modified":"2026-06-09T21:08:49","modified_gmt":"2026-06-09T18:08:49","slug":"image-carousel-2","status":"publish","type":"post","link":"https:\/\/notes.profidev.online\/ru\/reactjs\/4517\/","title":{"rendered":"Image Carousel React.js"},"content":{"rendered":"\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"Image Carousel. React.js\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/hrMrYTT_K4Y?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;jsx&quot;,&quot;mime&quot;:&quot;text\/jsx&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;JSX&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;JSX&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;jsx&quot;}\">\/\/App.jsx\n\nimport { useState } from 'react'\n\nconst slides = [\n  {\n    img: &quot;url('https:\/\/cdn.mos.cms.futurecdn.net\/dP3N4qnEZ4tCTCLq59iysd.jpg')&quot;,\n    title: '&quot;Lossless Youths&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n  {\n    img: &quot;url('https:\/\/i.redd.it\/tc0aqpv92pn21.jpg')&quot;,\n    title: '&quot;Estrange Bond&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n  {\n    img: &quot;url('https:\/\/wharferj.files.wordpress.com\/2015\/11\/bio_north.jpg')&quot;,\n    title: '&quot;The Gate Keeper&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n  {\n    img: &quot;url('https:\/\/images7.alphacoders.com\/878\/878663.jpg')&quot;,\n    title: '&quot;Last Trace Of Us&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n  {\n    img: &quot;url('https:\/\/theawesomer.com\/photos\/2017\/07\/simon_stalenhag_the_electric_state_6.jpg')&quot;,\n    title: '&quot;Urban Decay&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n  {\n    img: &quot;url('https:\/\/da.se\/app\/uploads\/2015\/09\/simon-december1994.jpg')&quot;,\n    title: '&quot;The Migration&quot;',\n    desc: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore fuga voluptatum, iure corporis inventore praesentium nisi. Id laboriosam ipsam enim.',\n  },\n]\n\nexport default function App() {\n  const [items, setItems] = useState(slides)\n\n  const handleNext = () =&gt; setItems(prev =&gt; [...prev.slice(1), prev[0]])\n  const handlePrev = () =&gt; setItems(prev =&gt; [prev[prev.length - 1], ...prev.slice(0, -1)])\n\n  return (\n    &lt;main&gt;\n      &lt;ul className=&quot;slider&quot;&gt;\n        {items.map((item) =&gt; (\n          &lt;li\n            key={item.img}\n            className=&quot;item&quot;\n            style={{ backgroundImage: item.img }}\n          &gt;\n            &lt;div className=&quot;content&quot;&gt;\n              &lt;h2 className=&quot;title&quot;&gt;{item.title}&lt;\/h2&gt;\n              &lt;p className=&quot;description&quot;&gt;{item.desc}&lt;\/p&gt;\n              &lt;button&gt;Read More&lt;\/button&gt;\n            &lt;\/div&gt;\n          &lt;\/li&gt;\n        ))}\n      &lt;\/ul&gt;\n      &lt;nav className=&quot;nav&quot;&gt;\n        &lt;ion-icon class=&quot;btn prev&quot; name=&quot;arrow-back-outline&quot; onClick={handlePrev}&gt;&lt;\/ion-icon&gt;\n        &lt;ion-icon class=&quot;btn next&quot; name=&quot;arrow-forward-outline&quot; onClick={handleNext}&gt;&lt;\/ion-icon&gt;\n      &lt;\/nav&gt;\n    &lt;\/main&gt;\n  )\n}\n<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;css&quot;,&quot;mime&quot;:&quot;text\/css&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;CSS&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;CSS&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;css&quot;}\">* {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n}\n\nbody {\n  height: 100vh;\n  display: grid;\n  place-items: center;\n  overflow: hidden;\n}\n\n#root {\n  width: 100%;\n  height: 100%;\n}\n\nmain {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  box-shadow: 0 3px 10px rgba(0,0,0,0.3);\n}\n\n.item {\n  width: 200px;\n  height: 300px;\n  list-style-type: none;\n  position: absolute;\n  top: 50%;\n  transform: translateY(-50%);\n  z-index: 1;\n  background-position: center;\n  background-size: cover;\n  border-radius: 20px;\n  box-shadow: 0 20px 30px rgba(255,255,255,0.3) inset;\n  transition: transform 0.1s, left 0.75s, top 0.75s, width 0.75s, height 0.75s;\n\n  &amp;:nth-child(1), &amp;:nth-child(2) {\n    left: 0;\n    top: 0;\n    width: 100%;\n    height: 100%;\n    transform: none;\n    border-radius: 0;\n    box-shadow: none;\n    opacity: 1;\n  }\n\n  &amp;:nth-child(3) { left: 50%; }\n  &amp;:nth-child(4) { left: calc(50% + 220px); }\n  &amp;:nth-child(5) { left: calc(50% + 440px); }\n  &amp;:nth-child(6) { left: calc(50% + 660px); opacity: 0; }\n}\n\n.content {\n  width: min(30vw,400px);\n  position: absolute;\n  top: 50%;\n  left: 3rem;\n  transform: translateY(-50%);\n  font: 400 0.85rem helvetica,sans-serif;\n  color: white;\n  text-shadow: 0 3px 8px rgba(0,0,0,0.5);\n  opacity: 0;\n  display: none;\n\n  &amp; .title {\n    font-family: 'arial-black';\n    text-transform: uppercase;\n  }\n\n  &amp; .description {\n    line-height: 1.7;\n    margin: 1rem 0 1.5rem;\n    font-size: 0.8rem;\n  }\n\n  &amp; button {\n    width: fit-content;\n    background-color: rgba(0,0,0,0.1);\n    color: white;\n    border: 2px solid white;\n    border-radius: 0.25rem;\n    padding: 0.75rem;\n    cursor: pointer;\n  }\n}\n\n.item:nth-of-type(2) .content {\n  display: block;\n  animation: show 0.75s ease-in-out 0.3s forwards;\n}\n\n@keyframes show {\n  0% {\n    filter: blur(5px);\n    transform: translateY(calc(-50% + 75px));\n  }\n  100% {\n    opacity: 1;\n    filter: blur(0);\n  }\n}\n\n.nav {\n  position: absolute;\n  bottom: 2rem;\n  left: 50%;\n  transform: translateX(-50%);\n  z-index: 5;\n  user-select: none;\n\n  &amp; .btn {\n    background-color: rgba(255,255,255,0.5);\n    color: rgba(0,0,0,0.7);\n    border: 2px solid rgba(0,0,0,0.6);\n    margin: 0 0.25rem;\n    padding: 0.75rem;\n    border-radius: 50%;\n    cursor: pointer;\n\n    &amp;:hover {\n      background-color: rgba(255,255,255,0.3);\n    }\n  }\n}\n\n@media (width &gt; 650px) and (width &lt; 900px) {\n  .content {\n    &amp; .title        { font-size: 1rem; }\n    &amp; .description  { font-size: 0.7rem; }\n    &amp; button        { font-size: 0.7rem; }\n  }\n  .item {\n    width: 160px;\n    height: 270px;\n\n    &amp;:nth-child(3) { left: 50%; }\n    &amp;:nth-child(4) { left: calc(50% + 170px); }\n    &amp;:nth-child(5) { left: calc(50% + 340px); }\n    &amp;:nth-child(6) { left: calc(50% + 510px); opacity: 0; }\n  }\n}\n\n@media (width &lt; 650px) {\n  .content {\n    &amp; .title        { font-size: 0.9rem; }\n    &amp; .description  { font-size: 0.65rem; }\n    &amp; button        { font-size: 0.7rem; }\n  }\n  .item {\n    width: 130px;\n    height: 220px;\n\n    &amp;:nth-child(3) { left: 50%; }\n    &amp;:nth-child(4) { left: calc(50% + 140px); }\n    &amp;:nth-child(5) { left: calc(50% + 280px); }\n    &amp;:nth-child(6) { left: calc(50% + 420px); opacity: 0; }\n  }\n}\n<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;markdown&quot;,&quot;mime&quot;:&quot;text\/x-markdown&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;Markdown&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;Markdown&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;markdown&quot;}\"># 01 \u2014 Carousel\n\nFullscreen image carousel with stacked thumbnails on the right. Prev\/Next navigation rotates slides.\n\n## Files\n- `App.jsx` \u2014 component\n- `App.css` \u2014 styles\n\n## Usage\n1. Copy `App.jsx` and `App.css` into your project\n2. Import CSS in your entry file: `import '.\/App.css'`\n3. Add ionicons to your `index.html` before `&lt;\/body&gt;`:\n\n```html\n&lt;script type=&quot;module&quot; src=&quot;https:\/\/unpkg.com\/ionicons@7.1.0\/dist\/ionicons\/ionicons.esm.js&quot;&gt;&lt;\/script&gt;\n&lt;script nomodule src=&quot;https:\/\/unpkg.com\/ionicons@7.1.0\/dist\/ionicons\/ionicons.js&quot;&gt;&lt;\/script&gt;\n```\n\n## Notes\n- CSS nesting syntax (`&amp;`) \u2014 requires modern browser (Chrome 112+, Firefox 117+, Safari 17.2+)\n- Slide rotation uses `useState` array rotation \u2014 no DOM manipulation needed\n- Add `#root { width: 100%; height: 100%; }` to CSS if the component doesn't fill the screen\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":4516,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66,140],"tags":[],"class_list":["post-4517","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-reactjs","category-sliders_reactjs"],"_links":{"self":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/4517","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/comments?post=4517"}],"version-history":[{"count":5,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/4517\/revisions"}],"predecessor-version":[{"id":4529,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/4517\/revisions\/4529"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media\/4516"}],"wp:attachment":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media?parent=4517"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/categories?post=4517"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/tags?post=4517"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}