带有透明背景和渐变边框的圆角矩形

时间:2017-08-01 11:58:25

标签: css svg

我需要制作一个矩形,并考虑以下事项:

  1. 透明的白色背景(80%)
  2. 渐变边框(来自后端的不同颜色,1px宽)
  3. 可以根据文字长度进行缩放
  4. Like this

    我尝试过使用SVG并让它工作,除了第3点。

    我现在的尝试是使用3个svgs(一个用于左/右半圈,一个用于中间部分并且绝对定位它们但是我还不能让它工作。

    enter image description here

    中间部分不应缩放到100%高度,但我对svg缩放选项不够熟悉。

    我使用React和Glamour,但这不重要。 (片段因依赖而无效,但你应该得到问题)

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { css, style, after } from 'glamor';
    
    const SectionTag = ({ className, name, url, height, borderWidth, fontSize, theme, fillColor }) => {
      const styles = {
        main: {
          padding: 0,
          display: 'block',
        },
        inline: style({
          display: 'inline-block',
          verticalAlign: 'top',
        }),
        textWrapper: style({
          position: 'relative'
        }),
        background: style({
          position: 'absolute',
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          width: '100%',
        }),
        text: css({
          zIndex: 1,
          position: 'relative',
          color: theme.accentColor,
          fontSize: fontSize,
          lineHeight: 1,
          textTransform: 'uppercase',
          padding: '8px 1px',
          height,
          margin: 0,
        }),
      };
      return (
        <div className={css(className, styles.main)}>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width={height / 2}
            height={height}
            viewBox={`0 0 ${height / 2} ${height}`}
            className={styles.inline}
          >
            <rect rx={height / 2} ry={height / 2} x={borderWidth / 2} y={borderWidth / 2}
                  width={(height * 2) - (borderWidth)}
                  height={height - (borderWidth)}
                  style={{
                    fill: fillColor,
                    stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
                    strokeWidth: borderWidth
                  }} />
          </svg>
          <div className={css(styles.textWrapper, styles.inline)}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              height={height}
              viewBox={`0 0 ${height - 4} ${height}`}
              className={css(styles.background)}
              preserveAspectRatio="xMidYMin slice"
            >
              <linearGradient id={`gradient-${name.replace(/ /g, '-').toLowerCase()}`}>
                <stop offset="0" style={{ stopColor: theme.leftColor }} />
                <stop offset="1" style={{ stopColor: theme.rightColor }} />
              </linearGradient>
              <rect
                x={-borderWidth}
                y={0}
                width={height - (borderWidth * 2)}
                height={height - (borderWidth * 2)}
                style={{
                  fill: fillColor,
                  stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
                  strokeWidth: borderWidth,
                  vectorEffect: 'non-scaling-stroke',
                  height: height,
                  top: 0,
                  padding: 0,
                  margin: 0,
                }} />
            </svg>
            <p
              height={height}
              className={css(styles.text, styles.inline)}
            >
              {name}
            </p>
          </div>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width={height / 2}
            height={height}
            viewBox={`0 0 ${height / 2} ${height}`}
            className={styles.inline}
          >
            <rect rx={height / 2} ry={height / 2} x={-(height * 1.5)} y={borderWidth / 2}
                  width={(height * 2) - (borderWidth)}
                  height={height - (borderWidth)}
                  style={{
                    fill: fillColor,
                    stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
                    strokeWidth: borderWidth
                  }} />
          </svg>
        </div>
      );
    };
    
    SectionTag.propTypes = {};
    SectionTag.defaultProps = {
      name: 'default',
      height: 29,
      borderWidth: 1,
      fontSize: 10,
      fillColor: 'rgba(255, 255, 255, .8)',
      theme: {
        leftColor: 'rgba(255, 188, 0, 0.31)',
        rightColor: '#ff0000',
        accentColor: '#f9811b'
      }
    };
    
    const mountNode = document.querySelector('.el');
    ReactDOM.render(<SectionTag name="Jane" />, mountNode);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="el"></div>

3 个答案:

答案 0 :(得分:1)

知道了!渐变的中间部分的位置有点棘手,但这是我的代码: enter image description here

import React from 'react';
import { css, style } from 'glamor';

const SectionTag = ({ className, name, url, height, borderWidth, fontSize, theme, fillColor }) => {
  const styles = {
    main: {
      padding: 0,
      display: 'block',
    },
    inline: style({
      display: 'inline-block',
      verticalAlign: 'top',
    }),
    textWrapper: style({
      position: 'relative',
      height,
    }),
    background: style({
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      zIndex: 0,
    }),
    text: css({
      zIndex: 2,
      position: 'relative',
      color: theme.accentColor,
      fontSize: fontSize,
      lineHeight: 1,
      textTransform: 'uppercase',
      padding: `${(height - fontSize)/2}px 1px`,
      margin: 0,
    }),
  };
  return (
    <div className={css(className, styles.main)}>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width={height / 2}
        height={height}
        viewBox={`0 0 ${height / 2} ${height}`}
        className={styles.inline}
      >
        <rect rx={height / 2} ry={height / 2} x={borderWidth / 2} y={borderWidth / 2}
              width={(height * 2) - (borderWidth)}
              height={height - (borderWidth)}
              style={{
                fill: fillColor,
                stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
                strokeWidth: borderWidth,
                vectorEffect: 'non-scaling-stroke',
              }} />
      </svg>
      <div className={css(styles.textWrapper, styles.inline)}>
        <p
          height={height}
          className={css(styles.text, styles.inline)}
        >
          {name}
        </p>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          height={height}
          width="100%"
          className={css(styles.background)}
        >
          <linearGradient id={`gradient-${name.replace(/ /g, '-').toLowerCase()}`}>
            <stop offset="0" style={{ stopColor: theme.leftColor }} />
            <stop offset="1" style={{ stopColor: theme.rightColor }} />
          </linearGradient>
          <rect
            x={-height}
            y={borderWidth/2}
            height={height- (borderWidth)}
            style={{
              width: `calc(100% + ${height * 2}px)`,
              fill: fillColor,
              stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
              strokeWidth: borderWidth,
              vectorEffect: 'non-scaling-stroke',
            }} />
        </svg>
      </div>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width={height / 2}
        height={height}
        viewBox={`0 0 ${height / 2} ${height}`}
        className={styles.inline}
      >
        <rect rx={height / 2} ry={height / 2} x={-(height * 1.5)} y={borderWidth / 2}
              width={(height * 2) - (borderWidth)}
              height={height - (borderWidth)}
              style={{
                fill: fillColor,
                stroke: `url(#gradient-${name.replace(/ /g, '-').toLowerCase()})`,
                strokeWidth: borderWidth
              }} />
      </svg>
    </div>
  );
};

SectionTag.propTypes = {};
SectionTag.defaultProps = {
  name: 'default',
  height: 29,
  borderWidth: 1,
  fontSize: 10,
  fillColor: 'rgba(255, 255, 255, .8)',
  theme: {
    leftColor: '#73abff',
    rightColor: '#ff8c2b',
    accentColor: '#0000FF'
  }
};

export default SectionTag;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

答案 1 :(得分:0)

div {
    position: relative;
    border-left: 3px solid red;
    border-right: 3px solid blue;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.8);
    font-size:24px;
    padding: 5px 20px;
    overflow: hidden;
}

div:before {
    content: '';
    background: linear-gradient(to right, red, blue);
    position: absolute;
    top: 0;
    left: 1px;
    height: 2px;
   right:1px;
    display:block;
}

div:after {
    content: '';
    background: linear-gradient(to right, red, blue);
    position: absolute;
    bottom: 0;
    left: 1px;
    right: 1px;
    height: 2px;
    display:block;
}
<div>Submit</div>

答案 2 :(得分:0)

您可以像这样添加SVG。

/* just styles for demo */
body {
  margin: 0;
  height: 100vh;
}
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 105 105" preserveAspectRatio="none">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" style="stop-color:#0070d8" />
      <stop offset="0.5" style="stop-color:#2cdbf1" />
      <stop offset="1" style="stop-color:#83eb8a" />
    </linearGradient>
  </defs>
  <g transform="ref(svg, 0, 0)">
    <rect x="2" y="2" width="100" height="100" rx="20" ry="20" fill="none" stroke="url(#gradient)" stroke-width="0.5" />
  </g>
</svg>

使用此SVG的示例。注意:示例仅适用于Chrome,在所有浏览器中使用外部SVG(推荐方式)或转义SVG标记:

div {
  display: inline-block;
  padding: 20px 5%;
  background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 105 105" preserveAspectRatio="none"><defs><linearGradient id="gradient"><stop offset="0" style="stop-color:#0070d8" /><stop offset="0.5" style="stop-color:#2cdbf1" /><stop offset="1" style="stop-color:#83eb8a" /></linearGradient></defs><g transform="ref(svg, 0, 0)"><rect x="2" y="2" width="100" height="100" rx="20" ry="50" fill="none" stroke="url(#gradient)" stroke-width="0.5" /></g></svg>');
}
<div>
  This is div
</div>

<div>
  This is also div with very long text.
</div>

<div>
  This is also div with very long text. This is also div with very long text. This is also div with very long text.
</div>

<div>
  This is also div with very long text. This is also div with very long text.<br /> This is also div with very long text.
</div>