CSS-Pseudoelemente in React

74

Ich baue React- Komponenten. Ich habe CSS inline in die Komponenten eingefügt, wie in dieser brillanten Präsentation von einem der Leute hinter React vorgeschlagen. Ich habe die ganze Nacht versucht, einen Weg zu finden, um CSS-Pseudoklassen inline hinzuzufügen, wie auf der Folie mit dem Titel ":: after" in der Präsentation. Leider muss ich nicht nur die content:"";Eigenschaft hinzufügen , sondern auch position:absolute; -webkit-filter: blur(10px) saturate(2);. Die Folien zeigen, wie Sie Inhalte hinzufügen {/* … */}, aber wie würden Sie andere Eigenschaften hinzufügen?

Michael Johansen
quelle

Antworten:

74

Ich habe eine Antwort von @Vjeux vom React- Team erhalten:

Normales HTML / CSS:

<div class="something"><span>Something</span></div>
<style>
    .something::after {
    content: '';
    position: absolute;
    -webkit-filter: blur(10px) saturate(2);
}
</style>

Reagieren Sie mit Inline-Stil:

render: function() {
    return (
        <div>
          <span>Something</span>
          <div style={{position: 'absolute', WebkitFilter: 'blur(10px) saturate(2)'}} />
        </div>
    );
},

Der Trick besteht darin, dass Sie anstelle von ::afterCSS zum Erstellen eines neuen Elements ein neues Element über React erstellen sollten. Wenn Sie dieses Element nicht überall hinzufügen müssen, erstellen Sie eine Komponente, die dies für Sie erledigt.

Für spezielle Attribute wie -webkit-filterkönnen Sie sie codieren, indem Sie Bindestriche entfernen und den nächsten Buchstaben groß schreiben . So wird es in WebkitFilter. Beachten Sie, dass dies {'-webkit-filter': ...}auch funktionieren sollte.

Michael Johansen
quelle
Obligatorische Entschuldigung für die Beantwortung meiner eigenen Frage. Und danke an @Vjeux für seine Antwort. Es hat wirklich gut funktioniert!
Michael Johansen
14
Wenn React JS jedoch an Suchagenten ausgegeben wird, indizieren sie den Pseudoinhalt, was nicht gut ist. Wenn Sie beispielsweise eine Überschrift in ein ::after-Element kopieren , um einen benutzerdefinierten Schatten zu erstellen, wäre ich nur zu Stylingzwecken nicht im DOM, wenn Google es sieht, aber mit diesem Ansatz wird Google es sehen ... Bedeutung Sie werden zwei Überschriften haben.
curly_brackets
4
Schade, dass dies oben angezeigt wird, wenn Sie nach Pseudoelementen suchen, die reagieren. @vjeux könnte sich ziemlich darüber ärgern, dass CSS schlecht war, ohne tatsächlich eine saubere / vollständige Alternative zu seinen Reaktionsfolgern bereitzustellen. Diese Lösung sollte nicht akzeptiert werden, es ist ein Schritt zurück - übrigens sicher, dass es wirklich gut funktioniert hat ahah
Ben
3
Dies ist meiner Meinung nach keine richtige Lösung. Ich verwende Pseudoelemente wie vorher und nachher, um unnötige DOMs zu vermeiden.
micky2be
5
Dies beantwortet nicht die Frage, ein neues Element zu erstellen, anstatt Pseudoelemente zu verwenden, ist keine ausreichende Lösung
Luke Flournoy
32

Inline-Stile können nicht für Pseudoklassen oder Pseudoelemente verwendet werden. Sie müssen ein Stylesheet verwenden.

Wenn Sie CSS dynamisch generieren möchten, ist es am einfachsten, ein DOM-Element zu erstellen <style>.

<style dangerouslySetInnerHTML={{
  __html: [
     '.my-special-div:after {',
     '  content: "Hello";',
     '  position: absolute',
     '}'
    ].join('\n')
  }}>
</style>
<div className='my-special-div'></div>
Wiktor Kozlik
quelle
12

Inline-Styling unterstützt keine Pseudos oder At-Rules (z. B. @media). Die Empfehlungen reichen von der Neuimplementierung von CSS-Funktionen in JavaScript für CSS-Zustände wie :hovervia onMouseEnterund onMouseLeaveder Verwendung weiterer Elemente zur Reproduktion von Pseudoelementen wie :afterund :beforeder Verwendung eines externen Stylesheets.

Ich persönlich mag all diese Lösungen nicht. Die Neuimplementierung von CSS-Funktionen über JavaScript lässt sich nicht gut skalieren, ebenso wenig wie das Hinzufügen überflüssiger Markups.

Stellen Sie sich ein großes Team vor, in dem jeder Entwickler CSS-Funktionen wie neu erstellt :hover. Jeder Entwickler wird es anders machen, wenn die Größe der Teams zunimmt. Wenn es möglich ist, wird es getan. Tatsache ist, dass es mit JavaScript ungefähr n Möglichkeiten gibt, CSS-Funktionen neu zu implementieren, und im Laufe der Zeit können Sie darauf wetten, dass jede dieser Möglichkeiten implementiert wird, wobei das Endergebnis Spaghetti-Code ist.

Was tun? Verwenden Sie CSS. Zugegeben, Sie haben nach Inline-Styling gefragt, vorausgesetzt, Sie befinden sich wahrscheinlich im CSS-in-JS-Camp (ich auch!). Ich habe festgestellt, dass das Colocieren von HTML und CSS genauso wertvoll ist wie das Colocieren von JS und HTML. Viele Leute wissen es einfach noch nicht (JS-HTML-Colocation hatte anfangs auch viel Widerstand).

In diesem Bereich wurde eine Lösung namens Style It erstellt , mit der Sie einfach Klartext-CSS in Ihre React-Komponenten schreiben können. Es ist nicht erforderlich, Zyklen zu verschwenden, in denen CSS in JS neu erfunden wird. Das richtige Werkzeug für den richtigen Job. Hier ein Beispiel mit :after:

npm install style-it --save

Funktionssyntax ( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      #heart {
        position: relative;
        width: 100px;
        height: 90px;
      }
      #heart:before,
      #heart:after {
        position: absolute;
        content: "";
        left: 50px;
        top: 0;
        width: 50px;
        height: 80px;
        background: red;
        -moz-border-radius: 50px 50px 0 0;
        border-radius: 50px 50px 0 0;
        -webkit-transform: rotate(-45deg);
        -moz-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
        -o-transform: rotate(-45deg);
        transform: rotate(-45deg);
        -webkit-transform-origin: 0 100%;
        -moz-transform-origin: 0 100%;
        -ms-transform-origin: 0 100%;
        -o-transform-origin: 0 100%;
        transform-origin: 0 100%;
      }
      #heart:after {
        left: 0;
        -webkit-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        -webkit-transform-origin: 100% 100%;
        -moz-transform-origin: 100% 100%;
        -ms-transform-origin: 100% 100%;
        -o-transform-origin: 100% 100%;
        transform-origin :100% 100%;
      }
    `,
      <div id="heart" />
    );
  }
}

export default Intro;

JSX-Syntax ( JSFIDDLE )

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        #heart {
          position: relative;
          width: 100px;
          height: 90px;
        }
        #heart:before,
        #heart:after {
          position: absolute;
          content: "";
          left: 50px;
          top: 0;
          width: 50px;
          height: 80px;
          background: red;
          -moz-border-radius: 50px 50px 0 0;
          border-radius: 50px 50px 0 0;
          -webkit-transform: rotate(-45deg);
          -moz-transform: rotate(-45deg);
          -ms-transform: rotate(-45deg);
          -o-transform: rotate(-45deg);
          transform: rotate(-45deg);
          -webkit-transform-origin: 0 100%;
          -moz-transform-origin: 0 100%;
          -ms-transform-origin: 0 100%;
          -o-transform-origin: 0 100%;
          transform-origin: 0 100%;
        }
        #heart:after {
          left: 0;
          -webkit-transform: rotate(45deg);
          -moz-transform: rotate(45deg);
          -ms-transform: rotate(45deg);
          -o-transform: rotate(45deg);
          transform: rotate(45deg);
          -webkit-transform-origin: 100% 100%;
          -moz-transform-origin: 100% 100%;
          -ms-transform-origin: 100% 100%;
          -o-transform-origin: 100% 100%;
          transform-origin :100% 100%;
        }
     `}

      <div id="heart" />
    </Style>
  }
}

export default Intro;

Herzbeispiel aus CSS-Tricks

Joshua Robinson
quelle
8

Sie können gestaltete Komponenten verwenden.

Installieren Sie es mit npm i styled-components

import React from 'react';
import styled from 'styled-components';

const YourEffect = styled.div`
  height: 50px;
  position: relative;
  &:after {
    // whatever you want with normal CSS syntax. Here, a custom orange line as example
    content: '';
    width: 60px;
    height: 4px;
    background: orange
    position: absolute;
    bottom: 0;
    left: 0;
  },

const YourComponent = props => {
  return (
    <YourEffect>...</YourEffect>
  )
}

export default YourComponent
Raphael Pinel
quelle
3

Abhängig davon, ob Sie nur einige Attribute benötigen, um sie inline zu gestalten, können Sie so etwas wie diese Lösung ausführen (und ersparen sich die Installation eines speziellen Pakets oder das Erstellen eines zusätzlichen Elements):

https://stackoverflow.com/a/42000085

<span class="something" datacustomattribute="👋">
  Hello
</span>
.something::before {
  content: attr(datascustomattribute);
  position: absolute;
}

Beachten Sie, dass das datacustomattributemit dataKleinbuchstaben beginnen und vollständig sein muss , um React zu erfüllen.

Peter W.
quelle
0

Keine direkte Antwort auf die Frage, aber dies kann denjenigen helfen, die Probleme beim Erstellen von styleInformationen mit Typescript haben.

Ich habe eine Fehlermeldung erhalten, dass Folgendes falsch war:

let iconStyle = {
    position: 'relative',
    maxHeight: '90px',
    top: '25%',
}

Der Fehler sagte mir, dass "Arten von Eigenschaften 'Position' nicht kompatibel sind". Ich habe keine Idee warum.

Ich habe dies behoben, indem ich eine strenge Typescript-Deklaration hinzugefügt habe, wie folgt:

let iconStyle: CSSProperties = {
    position: 'relative',
    maxHeight: '90px',
    top: '25%',
}

Das funktioniert.

Stuart Aitken
quelle
3
Frage hat buchstäblich nichts mit TypeScript zu tun.
Phillyslick
1
@phillyslick Ja, das tut es. Die angegebene Antwort gibt einen Fehler aus, wenn sie in Typescript geschrieben wird. Ich habe eine Lösung für diesen Fehler bereitgestellt.
Stuart Aitken
In Ihrer Antwort geht es darum, wie Sie CSS-Eigenschaften eingeben, insbesondere einen Positionseigenschaftstyp, und warum Sie keine Zeichenfolge verwenden können. Hierfür gibt es einige Lösungen (und Sie schlagen eine gute vor), aber auch bei dieser Frage geht es nicht um TypeScript. Es geht um JavaScript und React und CSS. Niemand, der hierher kommt, sollte denken, dass TypeScript etwas mit dieser Frage oder der gegebenen Lösung zu tun hat.
Phillyslick
1
@phillyslick Sicher wissen Sie, wie viel Überlappung Javascript und Typescript haben? Es gibt unzählige Male, in denen ich (und sicherlich auch andere) nach Lösungen für Probleme bei der Arbeit mit React gesucht und eine in Javascript geschriebene Lösung gefunden habe, die in Typescript genauso gut funktioniert. Manchmal, wie oben, ist dies jedoch nicht der Fall. Für mich ist es kaum ein Sprung in die Willkür, eine Notiz mit einer kleinen Änderung hinzuzufügen, damit die oben genannte Lösung für diejenigen funktioniert, die mit React CSS-Problemen in Typescript hierher gekommen sind. Ich sehe überhaupt nicht, was Ihr großes Problem ist, um ehrlich zu sein.
Stuart Aitken
1
Mein "großes Problem" ist, dass Ihre Antwort für jemanden, der TypeScript nicht verwendet, nicht hilfreich ist. Derzeit befindet sich Ihre Antwort über der akzeptierten Antwort. Die Frage wird jedoch nicht beantwortet - Sie sagen es selbst. Es beantwortet ein mögliches Problem, das einige Benutzer möglicherweise haben und das die Frage tangiert. Was passiert, wenn jemand SASS in seiner Pipeline verwendet? Sollten wir das auch beantworten? Was ist mit React Native? Man könnte argumentieren, dass Reagieren genauso tangential ist wie TypeScript. Sehen Sie meinen Punkt?
Phillyslick