I need to select a row to add a hover
effect on it. I'm trying to wrap all cells in a row with a div
, but all markup is destroyed. Does anyone have any idea how to do it? Is this even possible?
Check here for full code: 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;
`;
The :hover selector is used to select elements when you mouse over them. Tip: The :hover selector can be used on all elements, not only on links. Tip: Use the :link selector to style links to unvisited pages, the :visited selector to style links to visited pages, and the :active selector to style the active link.
If you want to give a hover style to cells, things are simple. Just add some CSS based on the '. wj-cell' class and ':hover' pseudo-selector. If you want to give a hover style to entire rows, apply the hover pseudo-style to the '.
The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).
The grid-row CSS shorthand property specifies a grid item's size and location within the grid row by contributing a line, a span, or nothing (automatic) to its grid placement, thereby specifying the inline-start and inline-end edge of its grid area.
display: contents;
to the rescue!
Kinda.
Depending on your browser support and/or accessibility requirements, we can achieve the effect you want, using the general structure you have, with the relatively new display: contents
property.
Describing display: contents
is somewhat difficult, so I'll point to this excellent CSS Tricks article.
To use it, we'll wrap each group of <span>
elements in a row into a <div>
with display: contents
. This allows us to target the div:hover > span
elements and apply a background color.
There were a few others small changes required to your styling, like making the <span>
elements fill the available width. Here's a working example:
.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>
With React and Styled Components
Now that we have the CSS working, we can put this back into a styled-components. The main change I've made to your code is to use the <LineUI />
component to wrap each row, along with the new CSS from above.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With