CSS Grid如何选择行以添加悬停效果?

17

我需要选中一行并添加 hover 效果。我试图用一个 div 包含行中的所有单元格,但是所有标记都被破坏了。有人有任何想法如何做到这一点吗?这是否可能?

查看完整代码: https://codesandbox.io/s/goofy-easley-w5rrg

const TableWrapperUI = styled.div `
  display: grid;
  box-sizing: border-box;
  width: 100%;
  border: 1px solid #dbeaf4;
  grid-template-columns: repeat(
    ${props => props.columns && props.columns},
    fit-content(400px)
  );
  justify-items: center;
  padding: 5px 0;
  justify-content: space-between;
  > span {
    padding: 5px;
    justify-self: left;
    :hover {
      background: #dbeaf4;
    }
  }`;

const LineUI = styled.div `
  border-bottom: 1px solid #dbeaf4;
  width: 100%;
  grid-column: 1 / -1;
`;

重复的问题:https://dev59.com/-VYN5IYBdhLWcg3wAT9Y - Temani Afif
如何在CSS Grid布局中定位特定的列或行? - Michael Benjamin
以下的解决方案是否有解决您的问题? - Brett DeWoody
5个回答

23

display: contents;来拯救!

有点。

根据您的浏览器支持和/或可访问性要求,我们可以使用相对较新的display: contents属性,以您已有的一般结构实现所需的效果。

描述display: contents有些困难,因此我将指向这篇优秀的CSS Tricks文章

为了使用它,我们将把每个包含<span>元素组的行用具有display: contents<div>包装起来。这使我们能够针对元素并应用背景颜色。

需要进行其他一些小的样式更改,例如使<span>元素填充可用宽度。以下是一个工作示例:

.parent {
  display: grid;
  box-sizing: border-box;
  width: 100%;
  border: 1px solid #dbeaf4;
  grid-template-columns: repeat(4, minmax(15%, max-content));
  padding: 5px 0;
}

.parent span {
  padding: 5px;
  border-bottom: 1px solid #dbeaf4;
}

.row {
  display: contents;
}

.row:hover span {
  background-color: #dbeaf4;
  cursor: pointer;
}
<div class="parent">
  <div class="row">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>Knowledge process outsourcing land the plane yet to be inspired is to become creative, innovative and energized we want this</span>
  </div>
  <div class="row">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>
  <div class="row">
    <span>We need to socialize the comms with the wider stakeholder community</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>
  <div class="row">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>
  <div class="row">
    <span>1</span>
    <span>2</span>
    <span>3</span>
    <span>4</span>
  </div>
</div>

使用React和Styled Components

现在我们已经让CSS起作用了,我们可以把它放回到styled-components中。我对你的代码进行的主要更改是使用<LineUI />组件来包装每一行,并使用上面的新CSS。

const titles = [
  "Id",
  "Type",
  "Name",
  "Category",
  "Client",
  "Date",
  "Watched",
  "Amount",
  "State",
  "Delete"
];

const data = [
  {
    id: 23,
    type: "test",
    name: "joaaaahnny cageasdasdasd cageasdasdasd cageasdasdasd cageasdasdasd",
    category: "selasdasler",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 211,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custsdsom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 2222,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 2222,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 2222,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 2222,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  },
  {
    id: 2222,
    type: "test",
    name: "johnny cage",
    category: "seller",
    client: "custom",
    date: "01-01-2019",
    watched: "yes",
    amount: 1231,
    state: "pending",
    delete: "button"
  }
];

const TableWrapperUI = styled.div`
  display: grid;
  box-sizing: border-box;
  width: 100%;
  border: 1px solid #dbeaf4;
  grid-template-columns: repeat(
    ${props => props.columns && props.columns},
    minmax(auto, max-content)
  );
  padding: 5px;

  > * {
    padding: 5px;
  }
`;

const LineUI = styled.div`
  display: contents;
  
  > * {
    padding: 5px;
    border-bottom: 1px solid #dbeaf4;
  }

  :hover > * {
    background-color: #dbeaf4;
    cursor: pointer;
    overflow: visible;
  }
`;

const Table = ({ children, titles, data }) => {
  const [amountColumns, setAmountColumns] = React.useState(0);
  React.useEffect(() => {
    setAmountColumns(titles.length);
  }, []);

  const displayData = data => {
    return data.map((x, idx) => {
      return (
        <React.Fragment key={idx}>
          <LineUI>
            {Object.keys(x).map((value, ids) => (
              <span key={ids}>{x[value]}</span>
            ))}
          </LineUI>
        </React.Fragment>
      );
    });
  };

  const displayTitles = titles => {
    return titles.map((title, idx) => {
      return <span key={idx}>{title}</span>;
    });
  };

  return (
    amountColumns > 0 && (
      <TableWrapperUI columns={amountColumns}>
        {displayTitles(titles)}
        {displayData(data)}
      </TableWrapperUI>
    )
  );
};

function App() {
  return (
    <div className="App">
      <Table columns={10} titles={titles} data={data} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/4.3.2/styled-components.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>


<div id="root"></div>


我强烈建议任何人在制作面向一般用户的任何类型的内容时,暂时不要使用display: content,因为IE缺乏支持和Safari中存在的错误。 - Simen L
这种方法的一个缺点是,column-gap会在span之间产生间隙。 - SethWhite

4

您无法从子网格中选择整行,但如果涉及突出显示背景,则可以模拟它。

const TableWrapperUI = styled.div`
  display: grid;
  box-sizing: border-box;
  width: 80%;/* demo, to show overflow cut off */
  overflow:hidden;
  border: 1px solid #dbeaf4;
  grid-template-columns: repeat(
    ${props => props.columns && props.columns},
    fit-content(400px)
  );
  justify-items: center;
  padding: 5px 0;
  justify-content: space-between;
  > span {
    padding: 5px;
    justify-self: left;
    position: relative;  
    :hover {
      background: #dbeaf4;
    }
    :hover::before, ::before {
      content: "";
      position: absolute;
      background: inherit;
      top: 0;
      bottom: 0;
      left: -100vw;
      right: -100vw;
    }
    :hover::before {
      z-index:-1
    }
  }
`;

https://codesandbox.io/s/affectionate-colden-m34od


谢谢您的答案,但还有一些bug。它只在我指向span时悬停。是否可以让整行都悬停?并且悬停会超出我的表格边界。 - Yerlan Yeszhanov
将 overflow: hidden 添加到父元素(请参见 CSS 注释),使伪元素随时存在,并仅在悬停时更改颜色。 - G-Cyrillus
从我的评论中@YerlanYeszhanov https://codesandbox.io/s/affectionate-colden-m34od - G-Cyrillus

0

这里是基于网格的解决方案,使用两个不同的行与网格。

1)带有网格的标题行

2)带有网格的表格主体

参考代码链接:https://codesandbox.io/embed/hopeful-pascal-hfdzx

更新的 CSS:

const TableRowUI = styled.div`
  display: grid;
  box-sizing: border-box;
  width: 100%;
  border-top: 1px solid #dbeaf4;
  grid-template-columns: repeat(
    ${props => props.columns && props.columns},
    1fr
  );
  justify-items: center;
  justify-content: space-between;
  > span {
    padding: 5px;
    justify-self: left;
  }
`;

const TableHeadUI = styled.div`
  display: grid;
  box-sizing: border-box;
  width: 100%;
  border-bottom: 1px solid #dbeaf4;
  grid-template-columns: repeat(
    ${props => props.columns && props.columns},
    1fr
  );
  justify-items: center;
  justify-content: space-between;
  > span {
    padding: 5px;
    justify-self: left;
  }
`;

最终代码片段:

https://codesandbox.io/embed/hopeful-pascal-hfdzx


-2
让使用`table`变得简单,而不是`span`。

CodeSandbox示例 - 链接

table {
  border: 1px solid #dbeaf4;
}

table tbody tr:hover {
  background: #dbeaf4;
}

table tbody td {
  border-top: 1px solid #dbeaf4;
}

th,
td {
  text-align: left;
  padding: 5px;
}
<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Type</th>
      <th>Name</th>
      <th>Category</th>
      <th>Client</th>
      <th>Date</th>
      <th>Watched</th>
      <th>Amount</th>
      <th>State</th>
      <th>Delete</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>23</td>
      <td>test</td>
      <td>joaaaahnny cageasdasdasd cageasdasdasd cageasdasdasd cageasdasdasd</td>
      <td>selasdasler</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>211</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custsdsom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>2222</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>2222</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>2222</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>2222</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
    <tr>
      <td>2222</td>
      <td>test</td>
      <td>johnny cage</td>
      <td>seller</td>
      <td>custom</td>
      <td>01-01-2019</td>
      <td>yes</td>
      <td>1231</td>
      <td>pending</td>
      <td>button</td>
    </tr>
  </tbody>
</table>


-2

该组件将在不同的地方使用,其中会有动态数据,我需要可适应的列大小。 - Yerlan Yeszhanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接