diff --git a/changelog_unreleased/css/16907.md b/changelog_unreleased/css/16907.md new file mode 100644 index 000000000..a8c0a79bf --- /dev/null +++ b/changelog_unreleased/css/16907.md @@ -0,0 +1,28 @@ +#### Break before breaking comma separated values (#16907 by @seiyab) + + +```css +/* Input */ +a { + background-image: + linear-gradient(to bottom, rgb(255 255 0 / 50%), rgb(0 0 255 / 50%)), + url("catfront.png"); +} + +/* Prettier stable */ +a { + background-image: linear-gradient( + to bottom, + rgb(255 255 0 / 50%), + rgb(0 0 255 / 50%) + ), + url("catfront.png"); +} + +/* Prettier main */ +a { + background-image: + linear-gradient(to bottom, rgb(255 255 0 / 50%), rgb(0 0 255 / 50%)), + url("catfront.png"); +} +``` diff --git a/src/language-css/print/parenthesized-value-group.js b/src/language-css/print/parenthesized-value-group.js index 58bec9ed2..197b55fb3 100644 --- a/src/language-css/print/parenthesized-value-group.js +++ b/src/language-css/print/parenthesized-value-group.js @@ -88,7 +88,11 @@ function printParenthesizedValueGroup(path, options, print) { assertDocArray(groupDocs); const withComma = chunk(join(",", groupDocs), 2); const parts = join(forceHardLine ? hardline : line, withComma); - return indent(forceHardLine ? [hardline, parts] : group(fill(parts))); + return indent( + forceHardLine + ? [hardline, parts] + : group([shouldPrecededBySoftline(path) ? softline : "", fill(parts)]), + ); } const parts = path.map(({ node: child, isLast, index }) => { @@ -165,6 +169,15 @@ function shouldBreakList(path) { ); } +function shouldPrecededBySoftline(path) { + return path.match( + (node) => node.type === "value-paren_group" && !node.open, + (node, key) => key === "group" && node.type === "value-value", + (node, key) => key === "group" && node.type === "value-root", + (node, key) => key === "value" && node.type === "css-decl", + ); +} + /** * @template {*} T * @param {T[]} array diff --git a/tests/format/markdown/code/__snapshots__/format.test.js.snap b/tests/format/markdown/code/__snapshots__/format.test.js.snap index a9af95113..b3ac1d86f 100644 --- a/tests/format/markdown/code/__snapshots__/format.test.js.snap +++ b/tests/format/markdown/code/__snapshots__/format.test.js.snap @@ -412,11 +412,8 @@ background-image: linear-gradient( =====================================output===================================== \`\`\`css -background-image: linear-gradient( - to bottom, - rgb(255 255 0 / 50%), - rgb(0 0 255 / 50%) - ), +background-image: + linear-gradient(to bottom, rgb(255 255 0 / 50%), rgb(0 0 255 / 50%)), url("catfront.png"); \`\`\` @@ -452,7 +449,8 @@ width: 400px; .box { margin: 10px 0; color: #fff; - background: linear-gradient( + background: + linear-gradient( 90deg, rgb(131 58 180 / 100%) 0%, rgb(253 29 29 / 60%) 60%, @@ -498,7 +496,8 @@ background-position: .multi-bg-example { width: 100%; height: 400px; - background-image: url(firefox.png), url(bubbles.png), + background-image: + url(firefox.png), url(bubbles.png), linear-gradient(to right, rgb(30 75 115 / 100%), rgb(255 255 255 / 0%)); background-repeat: no-repeat, no-repeat, no-repeat; background-position: @@ -535,11 +534,8 @@ proseWrap: "always" =====================================output===================================== \`\`\`css .stacked-linear { - background: linear-gradient( - 217deg, - rgb(255 0 0 / 80%), - rgb(255 0 0 / 0%) 70.71% - ), + background: + linear-gradient(217deg, rgb(255 0 0 / 80%), rgb(255 0 0 / 0%) 70.71%), linear-gradient(127deg, rgb(0 255 0 / 80%), rgb(0 255 0 / 0%) 70.71%), linear-gradient(336deg, rgb(0 0 255 / 80%), rgb(0 0 255 / 0%) 70.71%); } @@ -648,7 +644,8 @@ rgb(255 255 0 / 50%) 120px, =====================================output===================================== \`\`\`css .multi-repeating-linear { - background: repeating-linear-gradient( + background: + repeating-linear-gradient( 190deg, rgb(255 0 0 / 50%) 40px, rgb(255 153 0 / 50%) 80px, @@ -765,7 +762,8 @@ transparent 69px, =====================================output===================================== \`\`\`css .plaid-gradient { - background: repeating-linear-gradient( + background: + repeating-linear-gradient( 90deg, transparent, transparent 50px, @@ -810,7 +808,8 @@ transparent 69px, rgb(143 77 63 / 25%) 10px ); - background: repeating-linear-gradient( + background: + repeating-linear-gradient( 90deg, transparent 0 50px, rgb(255 127 0 / 25%) 50px 56px, @@ -1110,8 +1109,8 @@ mask-image: image(url(mask.png), skyblue), linear-gradi =====================================output===================================== \`\`\`css /* Multiple values */ -mask-image: image(url(mask.png), skyblue), - linear-gradient(rgb(0 0 0 / 100%), transparent); +mask-image: + image(url(mask.png), skyblue), linear-gradient(rgb(0 0 0 / 100%), transparent); \`\`\` ================================================================================ @@ -1269,9 +1268,10 @@ U+0152-0153, U+02BB-02BC, U+02C6, local("Montserrat Regular"), local("Montserrat-Regular"), url("fonts/montserrat-regular.woff2") format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, - U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, - U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, + U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, + U+FEFF, U+FFFD; } } \`\`\`