简体   繁体   中英

How to Make Square Icon Buttons with Rectangular SVG Icons Inside Them

I am attempting to make my own icon button using React, styled-components, and SVG. My icons are generally rectangular, however I want the buttons to be squares and to have the icons centered inside of them. This is where I am getting stuck. I tried tweaking the viewBox dimensions on the SVGs but (1) there is a lot of guesswork in this process, and (2) it screws up the position of the icons inside the buttons. Please can anyone offer some suggestions for how to achieve the square buttons with rectangular icons inside them?

Here is a CodePen with the below code: https://codepen.io/DanielPBank/pen/rPJgPW

const styled = styled.default; //normailly import from npm mmodules

const StyledButton = styled.button`
  appearance: none;
  opacity: 1;
  cursor: pointer;
  display: flex;
  height: ${props => props.size};
  width: ${props => props.size};
  max-height: ${props => props.maxSize}
  max-width: ${props => props.maxSize}
  margin: 1rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 0.88rem;
  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  border-radius: 8px;
  border: 3px solid ${props => props.active ? '#C23631' : '#222'};
  background-color: ${props => props.active ? '#C09AA1' : '#fcfcfc'};
  color: #222;

  &:hover {
    opacity: 0.70;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  }

  &:disabled {
    opacity: 0.5;
    pointer-events: none;
  }

  &:active {
    border: 3px solid #ccc;
    background-color: #444;
  }
`;

const StyledIcon = styled.svg`
  display: inline-block;
  fill: ${props => props.color || "white"};
  height ${props => props.size};
  width: ${props => props.size};
  user-select: none;
  flex-shrink: 0;
`;

class Icon extends React.Component {
  render() {
    const { size, viewBox, color } = this.props;
    return (
      <StyledIcon
        width={size || '1rem'}
        height={size || '1rem'}
        viewBox={viewBox}
        color={color}
        >
        {this.props.children}
      </StyledIcon>
    );
  }
}

class Undo extends React.Component {
  render() {
    return (
      <Icon
        {...this.props}
        x="0px"
        y="0px"
        viewBox="50 50 950 950"
        fill="#222"
        >
        <path
          d="M588.5,913.8c44.4,0,88.9,0,133.3,0c18,0,36.1,0,54.1,0c11.6,0,23.1-1.9,34.6-3.5     c10.3-1.5,20.3-4.1,29.9-8.1c14.8-6,29.1-12,41.9-21.5c12.4-9.2,24.7-18.5,34.6-30.4c20-24.2,36.5-51.4,42.8-82.6     c3.1-15.2,4.8-30.8,4.8-46.3c0-20.5,0-40.9,0-61.4c0-47.9,0-95.8,0-143.7c0-50.2-19.5-99.2-55.2-134.8     c-35.2-35.2-83.9-55.1-133.6-55.2c-23.7,0-47.3,0-71,0c-50,0-100,0-150,0c-59.9,0-119.8,0-179.7,0c-52.3,0-104.6,0-156.9,0     c-28.3,0-56.7,0-85,0c-1.3,0-2.6,0-3.9,0c-18,0-36.8,7.8-49.5,20.5c-6.8,6.3-11.7,13.8-14.5,22.5c-4.4,8.3-6.4,17.3-6,27     c0.8,18.1,6.8,36.9,20.5,49.5c13.7,12.6,30.5,20.5,49.5,20.5c22,0,43.9,0,65.9,0c52.6,0,105.1,0,157.7,0c62.8,0,125.7,0,188.5,0     c53.8,0,107.6,0,161.4,0c24.5,0,48.9-0.1,73.4,0c5.2,0,10.4,0.3,15.6,1c-6.2-0.8-12.4-1.7-18.6-2.5c10.3,1.4,20.3,4.1,29.9,8.1     c-5.6-2.4-11.1-4.7-16.7-7.1c9.4,4,18.2,9.1,26.3,15.2c-4.7-3.6-9.4-7.3-14.2-10.9c8.4,6.5,15.8,13.9,22.3,22.3     c-3.6-4.7-7.3-9.4-10.9-14.2c6.1,8.1,11.2,16.9,15.2,26.3c-2.4-5.6-4.7-11.1-7.1-16.7c4,9.6,6.7,19.6,8.1,29.9     c-0.8-6.2-1.7-12.4-2.5-18.6c1.3,10.7,1,21.6,1,32.3c0,17.5,0,34.9,0,52.4c0,39.9,0,79.8,0,119.7c0,12.5,0.6,25.1-1,37.5     c0.8-6.2,1.7-12.4,2.5-18.6c-1.4,10.3-4.1,20.3-8.1,29.9c2.4-5.6,4.7-11.1,7.1-16.7c-4,9.4-9.1,18.2-15.2,26.3     c3.6-4.7,7.3-9.4,10.9-14.2c-6.5,8.4-13.9,15.8-22.3,22.3c4.7-3.6,9.4-7.3,14.2-10.9c-8.1,6.1-16.9,11.2-26.3,15.2     c5.6-2.4,11.1-4.7,16.7-7.1c-9.6,4-19.6,6.7-29.9,8.1c6.2-0.8,12.4-1.7,18.6-2.5c-9.6,1.2-19.2,1-28.8,1c-14.5,0-29,0-43.5,0     c-35.4,0-70.8,0-106.1,0c-8.3,0-16.6,0-24.9,0c-17.9,0-36.8,7.8-49.5,20.5c-6.8,6.3-11.7,13.8-14.5,22.5c-4.4,8.3-6.4,17.3-6,27     c0.8,18.1,6.8,36.9,20.5,49.5C552.7,905.8,569.6,913.8,588.5,913.8L588.5,913.8z"
          />
        <path
          d="M296.1,130.8c-24.3,24.3-48.7,48.7-73,73c-38.8,38.8-77.6,77.6-116.4,116.4c-8.9,8.9-17.9,17.9-26.8,26.8     c-26.7,26.7-26.8,72.2,0,99c24.3,24.4,48.7,48.7,73,73.1c38.8,38.9,77.6,77.7,116.4,116.6c8.9,8.9,17.9,17.9,26.8,26.8     c12.7,12.7,31.6,20.5,49.5,20.5c17.2,0,37.7-7.6,49.5-20.5c12.2-13.3,21.3-30.9,20.5-49.5c-0.8-18.6-7.1-36.1-20.5-49.5     c-24.3-24.4-48.7-48.7-73-73.1c-38.8-38.9-77.6-77.7-116.4-116.6c-8.9-8.9-17.9-17.9-26.8-26.8c0,33,0,66,0,99     c24.3-24.3,48.7-48.7,73-73c38.8-38.8,77.6-77.6,116.4-116.4c8.9-8.9,17.9-17.9,26.8-26.8c12.7-12.7,20.5-31.5,20.5-49.5     c0-17.2-7.6-37.7-20.5-49.5c-13.3-12.2-30.9-21.3-49.5-20.5C327,111.1,309.5,117.4,296.1,130.8L296.1,130.8z"
          />
      </Icon>
    );
  }
}

class Button extends React.Component {
  render() {
    const { icon, size, maxSize, active, disabled } = this.props;
    return (
      <StyledButton
        type="button"
        ref={this.buttonRef}
        size={size}
        maxSize={maxSize}
        active={active}
        disabled={disabled}
        >
        {icon}
      </StyledButton>
    );
  }
}

class Application extends React.Component {
  render() {
    return (
      <div>
        <Button
          icon={<Undo color="black" size="100%"/>}
          size="25%"
          maxSize="5rem"
          />
      </div>
    )
  }
}

ReactDOM.render(<Application />, document.getElementById('content'));

Your icon is square alright. The button is rectangle because of button's default padding. In StyledButton , add padding: 0; and your button should be squared.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM