如何从Material-UI的大纲文本字段中模仿大纲和标签的外观?

时间:2019-03-06 22:09:47

标签: css reactjs material-ui

我正在尝试从Material-UI模仿轮廓文本框,但是我不知道如何在标题文本后面隐藏边框。

在下图中,请注意如何从Material-UI库中获取“到期日期/时间”,标题隐藏了它的边框,但是当我尝试用自定义组件模仿它时,我只是无法隐藏边界。

或者,有没有更好的方法来使用此轮廓设计,而不是仅使用CSS来实现?

我当前的组件看起来像这样:

<div style={inputContainerStyle}>
        <div style={{
          ...titleStyle,
          transform: 'translate(-43px, -11px) scale(0.75)',
          fontSize: '17px',
          color: 'rgba(0, 0, 0, 0.54)',
          position: 'absolute',
        }}
        >
          Color
        </div>
        <div
          className="flex-row"
          style={{
            border: '1px solid rgba(0, 0, 0, 0.23)',
            padding: '18.5px 14px',
            borderRadius: '4px',
          }}
        >
          {
            availableColors.map(color => <div style={colorCircleStyle(color)} />)
          }
        </div>
      </div>

3 个答案:

答案 0 :(得分:1)

使用TextField可以做的事情有很大的灵活性。 TextField支持通过Select属性插入不同类型的输入(例如inputinputComponent,自定义选择器)。您可以通过创建类似OutlinedDiv的自定义组件来利用此功能将任何内容放入其标记的轮廓内:

import React from "react";

import TextField from "@material-ui/core/TextField";

const OutlinedDiv = ({ children, label }) => {
  return (
    <TextField
      variant="outlined"
      label={label}
      InputLabelProps={{ shrink: true }}
      InputProps={{
        inputComponent: ({ className }) => (
          <div className={className}>{children}</div>
        )
      }}
    />
  );
};
export default OutlinedDiv;

传递给className的{​​{1}}负责使所有这些工作的CSS。然后,您可以像下面这样使用它:

inputComponent

Edit Custom Outlined Component

答案 1 :(得分:0)

只需将背景色应用于 div 作为父级的背景颜色,您可以通过 background-颜色:继承

<div style={inputContainerStyle}>
        <div style={{
          ...titleStyle,
          transform: 'translate(-43px, -11px) scale(0.75)',
          fontSize: '17px',
          color: 'rgba(0, 0, 0, 0.54)',
          position: 'absolute',
          background-color:'inherit' **(just add this line)**
        }}
        >
          Color
        </div>
        <div
          className="flex-row"
          style={{
            border: '1px solid rgba(0, 0, 0, 0.23)',
            padding: '18.5px 14px',
            borderRadius: '4px',
          }}
        >
          {
            availableColors.map(color => <div style={colorCircleStyle(color)} />)
          }
        </div>
      </div>

答案 2 :(得分:0)

概述的文本字段实在很难实现。推广该功能时,我们必须考虑多个选项,每个选项都有其自身的缺点

  1. SVG元素

易于构建和设置动画,但很难与周围的元素进行缩放。如果走了这条路线,我们将需要侦听某种类型的resize事件,这意味着要么使用不可靠的window resize事件,要么使用诸如ResizeObserver / MutationObserver之类的较新且受较少支持的功能。有polyfill,但是对于相对较小的功能,捆绑包的大小将增加约2K。

SVG路由可能会在将来使用。还值得注意的是Google Material Components Web就是通过这种方式解决问题的。

  1. 在标签上带有背景的纯旧边框

这是迄今为止最简单的方法,但是它也有些不灵活。您可以在Google的新登录流程中看到一个示例。他们在那里实际上将背景色设置为白色。对于许多用户来说,这可能是一个不错的方法,但是如果您的背景是渐变色或类似的边缘情况,则当然不起作用。就是说,不必担心调整大小,因为它只是一个边界。

  1. 字段集和图例

这就是我们最终要做的,主要是因为它对最终用户具有灵活性。 Fieldset及其图例组件都是获得此确切功能的内置方法。这样做的最大缺点是,跨浏览器的样式设置很困难,而且我们要为其设置动画的属性也无法实现,例如图例宽度。此外,当然最好还是使用语义HTML,但实际上并非如此,这意味着我们需要使用aria-hidden来指示屏幕阅读器忽略该元素。

根据您的目标,这些解决方案中的任何一种都可能最适合您。请注意,获得能够解决所有这些问题的完美解决方案可能非常棘手!