or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# PostCSS Selector Not

1

2

PostCSS Selector Not is a PostCSS plugin that transforms CSS level 4 `:not()` pseudo-class selectors with multiple arguments into CSS level 3 compatible selectors. It converts modern `:not(.a, .b)` syntax to `:not(.a):not(.b)` to ensure compatibility with older browsers while allowing developers to use the more concise modern syntax.

3

4

## Package Information

5

6

- **Package Name**: postcss-selector-not

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install postcss-selector-not --save-dev`

10

- **Node Version**: >=18

11

- **PostCSS Version**: ^8.4 (peer dependency)

12

13

## Core Imports

14

15

```typescript

16

import postcssSelectorNot from "postcss-selector-not";

17

// Named export also available

18

import type { pluginOptions } from "postcss-selector-not";

19

```

20

21

For CommonJS:

22

23

```javascript

24

const postcssSelectorNot = require("postcss-selector-not");

25

```

26

27

## Basic Usage

28

29

```typescript

30

import postcss from "postcss";

31

import postcssSelectorNot from "postcss-selector-not";

32

33

// Basic PostCSS usage

34

const result = await postcss([

35

postcssSelectorNot()

36

]).process(css, { from: undefined });

37

38

console.log(result.css);

39

```

40

41

Example transformation:

42

43

```css

44

/* Input CSS */

45

p:not(:first-child, .special) {

46

color: red;

47

}

48

49

/* Output CSS */

50

p:not(:first-child):not(.special) {

51

color: red;

52

}

53

```

54

55

## Architecture

56

57

PostCSS Selector Not follows the standard PostCSS plugin architecture:

58

59

- **Plugin Creator**: Factory function that returns a PostCSS plugin instance

60

- **Rule Processing**: Processes CSS rules containing `:not()` selectors

61

- **Selector Parsing**: Uses `postcss-selector-parser` for reliable CSS selector manipulation

62

- **Error Handling**: Provides warnings for invalid selectors without breaking the build

63

- **Transformation Logic**: Expands multi-argument `:not()` selectors into separate single-argument `:not()` functions

64

65

## Capabilities

66

67

### Plugin Creator Function

68

69

Creates a PostCSS plugin instance for transforming `:not()` selectors.

70

71

```typescript { .api }

72

/**

73

* Creates a PostCSS plugin for transforming CSS level 4 :not() selectors

74

* @param options - Plugin configuration options (currently none supported)

75

* @returns PostCSS plugin instance

76

*/

77

declare function postcssSelectorNot(options?: pluginOptions): Plugin;

78

79

/** Plugin options type - currently no options are supported */

80

type pluginOptions = Record<string, never>;

81

```

82

83

The plugin creator function returns a PostCSS plugin object with:

84

- `postcssPlugin`: String identifier "postcss-selector-not"

85

- `Rule`: Function that processes CSS rules containing `:not()` selectors

86

87

### Plugin Properties

88

89

```typescript { .api }

90

/** PostCSS plugin flag indicating this is a valid PostCSS plugin */

91

postcssSelectorNot.postcss: true;

92

```

93

94

### Transformation Behavior

95

96

The plugin specifically targets `:not()` pseudo-class selectors that contain multiple simple selectors separated by commas. It performs the following transformations:

97

98

- **Input**: `:not(.a, .b)`**Output**: `:not(.a):not(.b)`

99

- **Input**: `:not(tag1, tag2, tag3)`**Output**: `:not(tag1):not(tag2):not(tag3)`

100

- **Input**: `:not(:hover, :focus)`**Output**: `:not(:hover):not(:focus)`

101

102

**Supported selectors**:

103

- Class selectors: `.class`

104

- Type selectors: `tag`

105

- ID selectors: `#id`

106

- Pseudo-class selectors: `:hover`, `:focus`, etc.

107

- Attribute selectors: `[attr="value"]`

108

109

**Limitations**:

110

- Only simple selectors are supported within `:not()`

111

- Complex selectors like `:not(.a > .b, .c ~ .d)` cannot be downgraded and will be left unchanged

112

- The plugin only processes selectors that contain `:not(` (case-insensitive)

113

114

### Error Handling

115

116

The plugin includes comprehensive error handling:

117

118

- **Selector Parsing Errors**: If a selector cannot be parsed by `postcss-selector-parser`, the plugin will issue a PostCSS warning with the selector string and error message

119

- **Invalid Selectors**: Malformed selectors are reported but don't break the build process

120

- **Graceful Degradation**: When transformation fails, the original selector is preserved

121

122

**Warning Format**:

123

```

124

Failed to parse selector : "invalid-selector" with message: "error details"

125

```

126

127

## Types

128

129

```typescript { .api }

130

/** Plugin options type - currently no configuration options are supported */

131

type pluginOptions = Record<string, never>;

132

133

/** PostCSS Plugin interface */

134

interface PostCSSPlugin {

135

postcssPlugin: string;

136

Rule(rule: PostCSSRule, helpers: { result: PostCSSResult }): void;

137

}

138

139

/** PostCSS Rule interface (from postcss library) */

140

interface PostCSSRule {

141

selector: string;

142

warn(result: PostCSSResult, message: string): void;

143

clone(overrides: { selector: string }): PostCSSRule;

144

replaceWith(newRule: PostCSSRule): void;

145

}

146

147

/** PostCSS Result interface (from postcss library) */

148

interface PostCSSResult {

149

// PostCSS processing result object

150

}

151

```

152

153

## Usage Examples

154

155

### Basic Webpack Configuration

156

157

```javascript

158

const postcssSelectorNot = require("postcss-selector-not");

159

160

module.exports = {

161

module: {

162

rules: [

163

{

164

test: /\.css$/,

165

use: [

166

"style-loader",

167

"css-loader",

168

{

169

loader: "postcss-loader",

170

options: {

171

postcssOptions: {

172

plugins: [

173

postcssSelectorNot()

174

]

175

}

176

}

177

}

178

]

179

}

180

]

181

}

182

};

183

```

184

185

### PostCSS Configuration File

186

187

```javascript

188

// postcss.config.js

189

module.exports = {

190

plugins: [

191

require("postcss-selector-not")()

192

]

193

};

194

```

195

196

### Complex Selector Examples

197

198

```css

199

/* Multiple pseudo-classes */

200

.button:not(:hover, :focus, :active) {

201

opacity: 0.8;

202

}

203

/* Becomes: */

204

.button:not(:hover):not(:focus):not(:active) {

205

opacity: 0.8;

206

}

207

208

/* Mixed selector types */

209

article:not(.featured, #special, [data-premium]) {

210

margin: 1rem;

211

}

212

/* Becomes: */

213

article:not(.featured):not(#special):not([data-premium]) {

214

margin: 1rem;

215

}

216

217

/* Nested :not() selectors */

218

.container :not(h1, h2) :not(.icon, .badge) {

219

font-size: 0.9rem;

220

}

221

/* Becomes: */

222

.container :not(h1):not(h2) :not(.icon):not(.badge) {

223

font-size: 0.9rem;

224

}

225

```