如何通过 CSS 创建一个一侧有角度且圆角的盒子?

Exi*_*ito 18 html css frontend

我目前发现自己需要做这样的事情。

在此输入图像描述

我的第一个想法是使用 Clip-Path,但圆角很难实现,而且当按钮因其内容而改变宽度时,很难保持 22.5 度。

因此,我最终将每个按钮制作为两个div,其中一个 div 倾斜 22.5 度并与常规矩形 div 重叠。然后我给两者都添加了边框半径。

body {
  line-height: 0;
  font-size: 16px;
  background-color: black;
}

.cta-button-group {
  display: flex;
  gap: 2rem;
  align-items: center;
}

.button-angular-wrapper-left {
  display: flex;
  isolation: isolate;
  position: relative;
  height: 40px;
  width: fit-content;
}

.button-angular-wrapper-left .button-angular-main {
  border-radius: 7px 0 0 7px;
  height: 100%;
  display: inline-grid;
  place-items: center;
  padding-inline: 8px 16px;
  margin-right: 13px;
  transition: background-color 50ms;
}

.button-angular-wrapper-left .button-angular-slant {
  border-radius: 0 7px 7px 0;
  height: 100%;
  width: 24px;
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
  transition: background-color 50ms;
}

.button-angular-wrapper-left .button-angular-slant.back-slash {
  transform: skewX(22.5deg);
}

.button-angular-wrapper-left .button-angular-slant.forward-slash {
  transform: skewX(-22.5deg);
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main,
.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant {
  background: white;
  border: 3px solid white;
  color: blue;
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main {
  border-right: none;
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant {
  border-left: none;
}

.button-angular-wrapper-right {
  display: flex;
  isolation: isolate;
  position: relative;
  height: 40px;
  width: fit-content;
}

.button-angular-wrapper-right .button-angular-main {
  border-radius: 0 7px 7px 0;
  height: 100%;
  display: inline-grid;
  place-items: center;
  padding-inline: 8px 16px;
  margin-left: 13px;
}

.button-angular-wrapper-right .button-angular-slant {
  border-radius: 7px 0 0 7px;
  height: 100%;
  width: 24px;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
}

.button-angular-wrapper-right .button-angular-slant.back-slash {
  transform: skewX(22.5deg);
}

.button-angular-wrapper-right .button-angular-slant.forward-slash {
  transform: skewX(-22.5deg);
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main,
.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant {
  border: 3px solid white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main {
  border-left: none;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .icon-call {
  color: white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .cta-text {
  color: white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant {
  border-right: none;
}
Run Code Online (Sandbox Code Playgroud)
<div class="cta-button-group">
  <div class="button-angular-wrapper-left button-angular-color-solid-white" href="">
    <div class="button-angular-main">
      <span class="cta-text">
        Learn More Today
      </span>
    </div>
    <div class="button-angular-slant back-slash">
    </div>
  </div>
  <div class="button-angular-wrapper-right button-angular-color-outline-white" href="">
    <div class="button-angular-main">
      <span class="cta-text tel-link-no">
        1800-1-5555
      </span>
    </div>
    <div class="button-angular-slant back-slash">
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

代码笔: https: //codepen.io/katylar/pen/yLRjKaO

它有效,但并不完美。我注意到某些浏览器在某些分辨率下会出现明显的伪影和奇怪的角/边缘。

有好的解决办法吗?这不涉及面具(我总是很难戴上面具,尺寸方面)?

Apo*_*mus 14

我已经用伪元素尝试过这种方法。该形状的左侧是一个::before元素,为了实现悬停效果,我将按钮和伪元素上的特定边转为不可见,并更改了特定角的边框半径。

.button {
  color: white;
  background-color: black;
  text-align: center;
  text-transform: uppercase;
  padding: 5px 10px;
  margin: 11px;
  display: inline-block;
  border-radius: 4px;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  border: 2px solid black;
  -ms-transform: skewX(-20deg);
  -webkit-transform: skewX(-20deg);
  transform: skewX(-20deg);
}

.button-left::before {
  content: " ";
  display: block;
  position: absolute;
  top: -2px;
  left: -12px;
  z-index: -10;
  background-color: black;
  width: 20px;
  height: 100%;
  -ms-transform: skewX(20deg);
  -webkit-transform: skewX(20deg);
  transform: skewX(20deg);
  border-radius: 4px;
  border: 2px solid black;
}

.button-left:hover {
  background: rgba(0,0,0,0);
  box-sizing: border-box;
  border: 2px solid black;
  border-left: 2px solid rgba(0,0,0,0);
  color: black;
  border-top-left-radius: 0;
}

.button-left:hover::before {
  border-right: 2px solid rgba(0,0,0,0);
  background: rgba(0,0,0,0);
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.button-content {
  -ms-transform: skewX(20deg);
  -webkit-transform: skewX(20deg);
  transform: skewX(20deg);  
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<div class="button button-left">
  <span class="button-content">Slanted Button</span>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 从技术上讲,伪元素是 `::before`,而不是 `:before`。规范说 `:` 是伪类,`::` 是伪元素。不幸的是,规范最初并没有做出这种区分,因此大多数浏览器都接受“:”和“::”——作为原始伪元素。但是为了与后来的伪元素(通常必须是 `::`)保持一致,我们可能应该坚持规范,除非您特别需要旧版浏览器支持(我不知道 IE 曾经支持过 `:: `)。 (4认同)
  • 好的!需要明确的是,我已经投了赞成票,但我很欣赏这次更新。 (2认同)

Ada*_*dam 9

如果您完全反对遮罩,一个建议是在 3D 中使用perspective并旋转一个 div 以提供有角度的元素。

使用一个容器并使其display: inline-block倾斜的 div 始终位于右侧。这使得当您在 X 轴上旋转它时,它会向右“向后”倾斜。我们在容器中创建一个新的堆叠上下文来隐藏父级下面的最后一个 div。使用 css 自定义属性来确保最终的 div 与父级的宽度匹配。就我个人而言,我会使用蒙版,但可以使用它来代替,当然对于具有纯色背景的元素来说。我不知道你会如何使用边框来做到这一点,因为边框宽度也会随着transform: rotateX()属性而改变。对于不同的高度和宽度来说,它也有点脆弱,但它可能是一个有用的起点。

无论如何,看看你的想法。

body {
  background: black;
  color: black;
}

.container {
  --height: 4rem;
  perspective: 100px;
  isolation: isolate;
  display: inline-flex;
}

.main,
.angle {
  display: inline-flex;
  align-items: center;
  padding-left: 1rem;
  background-color: white;
  border-radius: 0.5rem;
}

.main {
  height: var(--height);
  width: 200px;
}

.angle {
  position: relative;
  right: 30px;
  width: 30px;
  transform-origin: top center;
  transform: rotateX(20deg);
  height: calc(var(--height) * 0.96);
  z-index: -1;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class='main'>Learn more today!</div><div class="angle"></div>
</div>
Run Code Online (Sandbox Code Playgroud)


KRy*_*yan 5

该版本不需要任何额外的 HTML 标记;它使用伪元素自动应用适当的倾斜效果。它还适用于任意数量的按钮,并仅在元素之间自动添加倾斜,使第一个元素没有左倾斜,最后一个元素没有右倾斜。

\n

它还使用多个 CSS 变量来允许根据给定的用例对其进行自定义。

\n

\r\n
\r\n
.slant-between:not(:first-child) {\n  margin-top: 2rem;\n}\n\n.slant-between {\n  white-space: nowrap;\n  --border-width: 0.25rem;\n  --border-radius: 0.5rem;\n  --bg-color: black;\n  --fg-color: white;\n  --skew-angle: 25deg;\n  --height: 2rem;\n}\n\n.slant-between>* {\n  box-sizing: border-box;\n  position: relative;\n  z-index: 0;\n  border: transparent;\n  background: transparent;\n  color: var(--fg-color);\n  padding: 0 1rem;\n  height: var(--height);\n  line-height: var(--height);\n  font-weight: bold;\n  cursor: pointer;\n}\n.slant-between>:hover {\n  color: var(--bg-color);\n}\n.slant-between>::before {\n  content: \' \';\n  position: absolute;\n  z-index: -1;\n  background: var(--bg-color);\n  border: var(--border-width) solid var(--bg-color);\n  border-radius: var(--border-radius);\n  transform: skew(var(--skew-angle));\n  top: 0;\n  bottom: 0;\n}\n.slant-between>:not(:first-child)::before {\n  left: 0;\n}\n.slant-between>:not(:last-child)::before {\n  right: 0;\n}\n.slant-between>:hover::before {\n  background: var(--fg-color);\n}\n\n.slant-between>:first-child::before,\n.slant-between>:first-child::after,\n.slant-between>:last-child::before,\n.slant-between>:last-child::after {\n  --skew-tangent: tan(var(--skew-angle));\n  --abs-skew-tangent: max(var(--skew-tangent), -1 * var(--skew-tangent));\n  --safe-overlap-width: calc(var(--height)/2 * var(--abs-skew-tangent) + var(--border-radius))\n}\n.slant-between>:first-child::before {\n  left: var(--safe-overlap-width);\n}\n.slant-between>:last-child::before {\n  right: var(--safe-overlap-width);\n}\n.slant-between>:first-child::before {\n  border-left: 0;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.slant-between>:last-child::before {\n  border-right: 0;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.slant-between>:first-child::after, .slant-between>:last-child::after {\n  content: \' \';\n  position: absolute;\n  z-index: -2;\n  top: 0;\n  bottom: 0;\n  background: var(--bg-color);\n  border: var(--border-width) solid var(--bg-color);\n}\n.slant-between>:first-child:hover::after, .slant-between>:last-child:hover::after {\n  background: var(--fg-color);\n}\n.slant-between>:first-child::after {\n  left: 0;\n  right: var(--safe-overlap-width);\n  border-right: 0;\n  border-top-left-radius: var(--border-radius);\n  border-bottom-left-radius: var(--border-radius);\n}\n.slant-between>:last-child::after {\n  right: 0;\n  left: var(--safe-overlap-width);\n  border-left: 0;\n  border-top-right-radius: var(--border-radius);\n  border-bottom-right-radius: var(--border-radius);\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="slant-between">\n  <button>Foo</button>\n  <button>Bar</button>\n  <button>Baz</button>\n</div>\n\n<div class="slant-between" style="--skew-angle: 15deg; --bg-color: green; --fg-color: blue; padding: 0.5rem; background: blue">\n  <button></button>\n  <button></button>\n  <button></button>\n  <button></button>\n  <button>\xe2\x99\xa5</button>\n</div>\n\n<div class="slant-between" style="--skew-angle: -45deg">\n  <button style="--bg-color: pink">Hearts</button>\n  <button style="--bg-color: yellow; --fg-color: black">Stars</button>\n  <button style="--bg-color: purple">Horseshoes</button>\n  <button style="--bg-color: green">Clovers</button>\n  <button style="--bg-color: blue">Blue Moons</button>\n  <button style="--bg-color: gold">Pots of Gold</button>\n  <button style="--bg-color: linear-gradient(\n        90deg,\n        rgba(255, 0, 0, 1) 0%,\n        rgba(255, 154, 0, 1) 10%,\n        rgba(208, 222, 33, 1) 20%,\n        rgba(79, 220, 74, 1) 30%,\n        rgba(63, 218, 216, 1) 40%,\n        rgba(47, 201, 226, 1) 50%,\n        rgba(28, 127, 238, 1) 60%,\n        rgba(95, 21, 242, 1) 70%,\n        rgba(186, 12, 248, 1) 80%,\n        rgba(251, 7, 217, 1) 90%,\n        rgba(255, 0, 0, 1) 100%\n    )">Rainbows</button>\n  <button style="--bg-color: red">A Red Balloon</button>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

它可以处理各种倾斜角度、配色方案、边框宽度和半径等。

\n

此处代码的主要限制是您需要使用变量在 CSS 中定义按钮的高度--height。在很多情况下,周围的所有三角函数都--height可以用估计值\xe2\x80\x94进行硬编码,其中\xe2\x80\x99有很大的回旋空间。

\n

它也不适用于纯色以外的背景,正如您在 \xe2\x80\x9cRainbows\xe2\x80\x9d 示例中看到的那样,因为您可以\xe2\x80\x99t 使用渐变或图像或任何文本或边框颜色。我还是很高兴尝试一下。我从@Bartek\xe2\x80\x99s 答案中得到了彩虹渐变。

\n