Is there a way for me to recreate the appearance of the outline and labeling found in Material-UI's outlined textfield?

Can anyone help me figure out how to hide the border behind the title text in an outlined textfield from Material-UI that I am trying to imitate?

In the image below, you can see "Due Date/Time" taken from Material-UI library where the title hides the border behind it. However, my custom component is struggling to achieve this effect.

Is there a more effective way to implement this outline design rather than just using CSS?

This is how my current component is structured:

<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>

https://i.sstatic.net/LZuUP.jpg

Answer №1

UPDATE

A different approach may be more suitable in many cases with my subsequent answer, which eliminates the use of TextField and therefore does not affect the FormControl context: How can I set a static outlined div similar to Material-UI's outlined textfield?


There are many possibilities with TextField. It allows for various types of inputs (such as Select, input, custom pickers) through the inputComponent property. You can utilize this feature by creating a custom component like OutlinedDiv:

import React from "react";

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

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

The CSS needed for everything to function properly is handled by the className passed to the inputComponent. Here's how you can use it:

import React from "react";
import ReactDOM from "react-dom";

import OutlinedDiv from "./OutlinedDiv";
import Avatar from "@material-ui/core/Avatar";
import deepOrange from "@material-ui/core/colors/deepOrange";
import deepPurple from "@material-ui/core/colors/deepPurple";
import red from "@material-ui/core/colors/red";
import green from "@material-ui/core/colors/green";
import blue from "@material-ui/core/colors/blue";
import Grid from "@material-ui/core/Grid";

function App() {
  return (
    <div className="App">
      <OutlinedDiv label="Color Picker">
        <Grid container justify="center" alignItems="center">
          <Avatar style={{ backgroundColor: deepOrange[500] }} />
          <Avatar style={{ backgroundColor: deepPurple[500] }} />
          <Avatar style={{ backgroundColor: red[500] }} />
          <Avatar style={{ backgroundColor: green[500] }} />
          <Avatar style={{ backgroundColor: blue[500] }} />
        </Grid>
      </OutlinedDiv>
      <br />
      <br />
      <OutlinedDiv label="Custom Outlined Thing">
         You have complete freedom to add anything inside here.
      </OutlinedDiv>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

https://codesandbox.io/s/jlmp5kw30w?fontsize=14

Answer №2

Avoid the need to write an Outlined div component and use FormControl, FormLabel, and FormGroup instead to achieve the same result. Following the logic of the outlined div will cause your input fields to lose focus.

Simply wrap your code with the following solution for an easy and quick implementation:

<FormControl component="fieldset" className="fieldset">
  <FormLabel component="Legend">Title</FormLabel>
  <FormGroup row>
    {/*Your Input fields e.g TextField or Select e.t.c*/}
  </FormGroup>
</FormControl>

Then, use useStyles to apply some CSS:

fieldset: {
  width: '100%',
  marginBottom: 10,
  padding: 10,
  border: '1px solid #ddd',
  borderRadius: 5
}

Answer №3

The process of implementing the outlined textfield was quite challenging. In order to incorporate this feature, we had to evaluate various options, each presenting its own set of difficulties.

  1. Utilizing an SVG Element

While building and animating with SVG is relatively straightforward, scaling it with surrounding elements posed a challenge. This approach would require us to listen for resize events, either through a window event (which lacks robustness) or utilizing modern but less supported features like ResizeObserver/MutationObserver. Implementing polyfills for compatibility would have increased the bundle size significantly for a seemingly small feature.

Despite these hurdles, the SVG route appears to be the most viable option moving forward. It's worth mentioning that Google's Material Components Web also adopts this solution to tackle similar issues.

  1. Traditional border styling with a label background

This method is the simplest but comes with limitations in terms of flexibility. For instance, Google's new sign-in flow employs this technique by setting a white background color. While suitable for many users, it may not work well with gradient backgrounds or specific scenarios. On the plus side, resizing is not a concern as it only involves modifying the border.

  1. Fieldset and legend integration

In the end, we opted for this approach due to its versatility for end users. Fieldset and its associated legend are pre-built components that offer the desired functionality. However, challenges include inconsistent styling across browsers and performance issues with properties like legend width. Despite being less semantically correct, using aria-hidden helps screen readers ignore unnecessary elements.

Depending on your objectives, any of these solutions could suit your needs best. It's important to note that finding a flawless solution addressing all concerns may prove to be a complex task!

Answer №4

To ensure that the color div has the same background color as its parent element, you can simply apply the style background-color: inherit like so:

<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' **(adding this line will achieve the desired effect)**
        }}
        >
          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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to automatically close navigation dropdowns when the screen size changes?

I am using a bootstrap 4 navbar with dropdowns that open with CSS animation/fade-in on desktop, and a separate toggle button for mobile. Everything works fine, but when I open the dropdowns on mobile and then resize the window screen, they remain open whic ...

unable to modify background color when mouse hovers in CSS

Recently, I implemented this code to style the navigation bar on my website. However, I encountered an issue where the color does not change when hovering over the links. .nav { list-style-type:none; margin:0; padding:0; overflow:hidden; } ...

Modify additional fields when there is a change in a MobX React form

I have been experimenting with the nestedField demo example from Mobx-react-form, making some tweaks to the field list. My goal is to create a function that will run every time any field in the form is updated or changed, allowing me to update dependent fi ...

Encountering syntax errors with CommonJS Rollup plugin when attempting to import third-party libraries, particularly those involving the 'process' module

I have been developing a personalized rollup configuration that involves React projects and inlines the JS and CSS in index.html. When attempting to import third-party React libraries (such as material-ui-color), I encountered an issue with CommonJS repo ...

How is it possible that I am able to retrieve an image from the public folder but unable to access a

I recently started learning Reactjs and came across this issue. In the images folder of my React project created with create-react-app, I have placed both a json file and a jpg image. However, I am able to use the jpg image but not the json file. let pho ...

Modify the background color of checkboxes without including any text labels

I am looking to customize my checkbox. The common method I usually see for customization is as follows: input[type=checkbox] { display: none; } .my_label { display: inline-block; cursor: pointer; font-size: 13px; margin-right: 15px; ...

Is there a way to eliminate the return?

Struggling to eliminate the unwanted return in my Wordpress loop. The layout is ruined by trying to display a thumbnail next to the entry: https://i.sstatic.net/j3Ozz.png Even using padding for the entry made it worse! Here's the code snippet that ...

How to align text in the center of a card using Angular Bootstrap

I have a column div that I need to center the text in Here is my code: <div class="card mb-4"> <div class="card-header"> <div class="card-title-wrap bar-info"> ...

Synchronizing CSS3 Animation Events and Event Listeners in jQuery: A Complete Guide

I've been exploring different ways to utilize CSS3 Animation Events and Event Listeners across browsers for more precise control over CSS3 animations. While I know it's possible, I'm struggling to implement it due to my current limitations d ...

Having issues with floats in Bootstrap?

I'm facing an issue trying to float two elements within a Bootstrap navigation bar, but for some reason it's not working. .cls1 { float: left !important; } .cls2 { float: right !important; } <link href="https://maxcdn.bootstra ...

Overlap and cover additional elements within a DIV

I am looking to create a versatile function that can effortlessly overlay various elements such as selects, textfields, inputs, divs, tables, and more with a partially transparent div matching their exact height and width. I have managed to obtain the pos ...

What is the process of programmatically sorting a column in a Material UI DataGrid?

Hey there! I'm currently working on a DataGrid that has a column with a custom header, specifically a Select option. My goal is to have the column sorted in descending order every time a user selects an option from the dropdown menu. renderHeader: (pa ...

The continuous re-rendering is being triggered by the Async/Await Function

I am facing an issue with fetching data from the backend using axios. The function is returning a Promise and each time I call it, my component keeps rendering continuously. Below is the code snippet: import { useState } from "react"; import Ax ...

Creating adaptive paper with Material-UI

I'm in the process of developing an application and currently focusing on creating a responsive login page. I want the login elements to be centered both horizontally and vertically, but 'justify-content: center' doesn't seem to work as ...

What is the best way to control and manipulate this parallax effect?

Having trouble getting the icon dog to appear correctly in this parallax effect. I want the full body of the dog icon to be displayed over the section, but I'm having no luck so far. Please see my code below and let me know if there are any correction ...

Having trouble with individuals gaining access to my gh-pages on Github

After creating a gh-pages repository on Github to showcase my portfolio, I encountered an issue where visitors were being prompted to log into Github in order to view the page. Gh-pages are intended to be public, so I am unsure why this is occurring. My ...

Using Material-UI's <Autocomplete/> component and the getOptionLabel prop to handle an empty string value

Currently, I am working with material-ui autocomplete and passing an array of states to its options property. However, I have encountered an issue with the getOptionLabel method: Material-UI: The `getOptionLabel` method of Autocomplete returned undefined ...

Creating an artistic blend by layering p5.js drawings over images in an HTML canvas

I'm having a tough time solving this issue. My goal is to overlay circles on top of an image, ideally using HTML for the image. However, I just can't seem to make it work. let img; function setup() { createCanvas(800,800); img = loadImage(&qu ...

Setting !important to every property's value at once

One interesting approach I am using is applying !important to all of the css properties' values like this: .someclass{ color: #f00 !important; background-color: #ff0 !important; margin: 0 !important; padding: 0 !important; width: 100% ! ...

Tips for ensuring Marketo forms are responsive when integrated into a WordPress website

We are currently using Wordpress for our responsive website. Within the site, we have integrated Marketo forms (a marketing automation system) with custom CSS for styling. The issue we are facing is that while the forms appear fine on desktops, they cause ...