Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

255
Views
Diseño de libro CSS (acordeón horizontal)

Estoy tratando de crear una página con un diseño de libro, por lo que una página con algunas pestañas que se pueden expandir una a la vez.

Aquí un ejemplo de trabajo: https://codesandbox.io/s/book-layout-l28gh?file=/src/App.js:0-1419

 import { useState } from "react"; const dataset = [ { name: "A section", description: "page A" }, { name: "B section", description: "page B" }, { name: "C section with long title", description: "page C" }, { name: "D section", description: "page D" } ]; export default function App() { return <Page />; } function Page({}) { const [openSection, setOpenSection] = useState(0); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, padding: 10, flex: 1, flexGrow: isOpen ? 1 : 0, transition: "all 2s ease" }} > <div style={{ cursor: "pointer", writingMode: isOpen ? "horizontal-tb" : "vertical-rl", transition: "all 2s ease" }} onClick={() => setOpenSection(i)} > {name} </div> </div> ); })} </div> ); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Si lo pruebas, puedes notar algunos problemas:

  1. cuando expande una sección, el título no hace una transición suave al pasar de vertical a horizontal. Debe ser una rotación suave.
  2. a veces, no entendía exactamente cuándo, al hacer clic en un título, todas las tarjetas parecen acercarse unas a otras.
  3. otra solicitud es hacer que se pueda hacer clic en el área gris, pero es un problema obvio cuando está abierto

¿Por qué? ¿Cuál es el problema? ¿Hay un mejor enfoque para hacer un diseño como este?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Resolví todos tus problemas como dijiste.

Problema n. ° 1 -> resuelto: debe usar white-space:nowrap . si su texto es grande, al final de su cuadro se dividirá en la siguiente línea. white-space:nowrap , no permitas eso. (No lo recomiendo porque esto no es bueno para un texto de título demasiado largo).

Problema #2 -> resuelto: sucede cuando haces clic en algún elemento y en medio de la acción (cuadro de apertura) haces clic en otro. esto se debe a display: flex y flexGrow: 1 .

usó el cuadro flexible y justifyContent: "center" . así que cuando hace clic y hace clic en otro, su envoltorio se vuelve más pequeño y todas las tarjetas parecen estar más cerca unas de otras. flexGrow: 1 los romperá. entonces flexGrow: 5 es la solución.

Problema n. ° 3 -> resuelto: lugar incorrecto para configurar onClick . debe configurar el evento onClick en su cuadro, no en su texto. y una condición para el cursor es lo que quieres. (El elemento está seleccionado, por lo que el cursor debe ser default ; de lo contrario, debe ser un poiner ).

Bonificación :) si establece un ancho pequeño en su envoltorio para que su cuadro de rotación sea más bonito. gira al comienzo del texto y bingo.

 import { useState } from "react"; const dataset = [ { name: "A section" }, { name: "B section" }, { name: "C section with long title" }, { name: "D section" }, { name: "E section" }, ]; function Page() { const [openSection, setOpenSection] = useState(1); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh", }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} onClick={() => setOpenSection(i)} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, padding: "20px 30px", flex: 1, flexGrow: isOpen ? 5 : 0, transition: "all 1s linear", boxSizing: "border-box", cursor: openSection !== i ? 'pointer' : 'default', "&:first-child": { left: 0, }, "&:last-child": { right: 0, }, }} > <div style={{ transform: `rotate(${isOpen ? "0" : "90"}deg)`, transition: "all 1s linear", width: 1, whiteSpace: "nowrap", }} > {name} </div> </div> ); })} </div> ); } export default Page;
about 4 years ago · Juan Pablo Isaza Report

0

  1. Transición suave : agregue white-space:nowrap ahora para que el texto no se encoja cuando se reduzca el tamaño. Haga que la posición de title div sea absoluta para que su ancho no interfiera con el diseño y la transición.
  2. error de clic : no se pudo reproducir. A veces, codesandbox no se actualiza correctamente. Debe actualizar la página de salida y probar nuevamente. Verifique con mi código actualizado si sucede allí también.
  3. hacer que se pueda hacer clic en el área gris : mueva el puntero del mouse y el controlador de clic al padre con la condición isOpen.

Codesandbox modificado :

 import { useState } from "react"; const dataset = [ { name: "A section" }, { name: "B section" }, { name: "C section with long title" }, { name: "D section" }, { name: "E section" } ]; export default function App() { return <Page />; } function Page({}) { const [openSection, setOpenSection] = useState(0); return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }} > {dataset.map((datum, i) => { const { name } = datum; const isOpen = i === openSection; return ( <div key={name} style={{ height: "100%", backgroundColor: isOpen ? "white" : "lightgray", border: `1px solid ${isOpen ? "white" : "black"}`, flex: 1, flexGrow: isOpen ? 1 : 0, transition: "all 2s ease", //my changes padding: 0, flexBasis: "1.2rem", cursor: !isOpen ? "pointer" : "auto", position: "relative" }} onClick={!isOpen ? () => setOpenSection(i) : null} > <div style={{ transition: "all 2s ease", //my changes transform: `rotate(${isOpen ? "0" : "90"}deg) translateX(${isOpen ? "0" : "50"}%)`, whiteSpace: "nowrap", width: isOpen ? "100%" : "1rem", position: "absolute", top: isOpen ? "1rem" : "0", left: isOpen ? "1rem" : "0", fontWeight: "bold" }} > {name} </div> </div> ); })} </div> ); }
about 4 years ago · Juan Pablo Isaza Report

0

Seguiré el mismo orden en que presentaste tus problemas.

  1. el modo de escritura que está utilizando en los títulos no se puede animar. Podría intentar rotar el texto en lugar de usar la propiedad de transformación
  2. Si desea que se pueda hacer clic en toda el área gris, debe mover tanto la función onClick como el cursor: propiedad "puntero" al div principal de ese elemento exacto que es el título.
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!