Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

256
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda