user3258926
user3258926

Reputation:

CSS cross through an element

How can I put a big cross over an entire (div) element?

I have a page with a person's details on it - name, dob, address, etc. - and if the person is deceased I still want to display the contact details (address, phone number, etc.) but want to put a big cross through it all to show that it shouldn't be used.

I could only really think of using an image, but as the element could be varying in length and width I'm not sure how that would work anyway.

Upvotes: 17

Views: 32429

Answers (6)

KajMagnus
KajMagnus

Reputation: 11666

You can use CSS and SVG inside that CSS:

  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M100 0 L0 100 ' stroke='black' stroke-width='1'/><path d='M0 0 L100 100 ' stroke='black' stroke-width='1'/></svg>");
  background-repeat:no-repeat;
  background-position:center center;
  background-size: 100% 100%, auto;

Demo: http://jsfiddle.net/02ffvyeo/

All this, including the demo, is based on https://stackoverflow.com/a/20231370/694469. That answer draws a colored triangle, this question was about a cross

Code snippet:

.background {
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M100 0 L0 100 ' stroke='black' stroke-width='1'/><path d='M0 0 L100 100 ' stroke='black' stroke-width='1'/></svg>");
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 100% 100%, auto;
  border: solid red 2px;
  width: 300px;
}
<div class="background">

  hello world
  <br/><br/><br/><br/><br/><br/><br/>
</div>

Upvotes: 29

brouxhaha
brouxhaha

Reputation: 4093

You could use :before and :after in combination with transforms to put an X over the entire div: DEMO

.container {
  position: relative;
  background: gray;
  padding: 30px;
  overflow: hidden; /* hide overflow of pseudo elements */
}

.container:before,
.container:after {
  position: absolute;
  content: '';
  background: red;
  display: block;
  width: 100%;
  height: 30px;
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg); /* center the X vertically and horizontally: */
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}

.container:after {
  -webkit-transform: rotate(45deg);
  transform: rotate(45deg);
}
<div class="container">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse in massa at leo pretium ultricies. Nam cursus ultricies nisl sit amet aliquet. Vestibulum tristique, lectus sed tempor feugiat, augue purus tempor erat, viverra ullamcorper turpis nulla
  ut nunc. Praesent a ante at dui ultrices eleifend id tempus erat. Pellentesque vitae eleifend felis. Donec tellus tellus, aliquet at adipiscing et, adipiscing et lacus. Morbi vitae commodo metus.

</div>

Upvotes: 16

Alex Derbov
Alex Derbov

Reputation: 11

Without any SVG, pure CSS + JS Only thing that needed is to setProperty:

--width = width of div

--height = width of div

--cross-thickness = desired thickness of lines inside cross

var el = document.querySelector('.crossed');
el.style.setProperty('--width', parseFloat( el.clientWidth));
el.style.setProperty('--height', parseFloat( el.clientHeight));
.crossed {
    width: 300px;
    overflow: hidden;
    box-sizing: border-box;
    position:relative;
    --cross-thickness: 10px;
}
.crossed:before, .crossed:after {
    content: "";
    display: block;
    width: 300%;
    height: var( --cross-thickness);
    position: absolute;
    top: 0;
    z-index: 2;
    background: red;
    margin-top: calc( -1 * var( --cross-thickness) / 2);
    
}
.crossed:before {
    left: 0;
    transform-origin: top left;
    rotate: atan2(var(--height), var(--width));
}
.crossed:after {
    right: 0;
    rotate: calc(-1 * atan2(var(--height), var(--width)));
    transform-origin: top right;
}
    <div class="crossed">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</div>

Upvotes: 1

user1205406
user1205406

Reputation: 701

CSS isn't really designed for this sort of thing - the purpose of a div element is to divide the html into sections so you can apply formatting (CSS) to elements within the div tags. What you could try is formatting the text to have a line through it.

<p style="text-decoration: line-through">Name</p>

Its still readable but obviously defunct.

Upvotes: -2

Asons
Asons

Reputation: 87191

Add an absolute positioned div (100% height/width) containing a font with em size, fill it with an "X"

<div class="deceased">X</div>

Will expand properly (and save an image callback as well :) )

If you don't like the X to be clipped by setting its size very big you will need javascript to resize it when div size changes.

Even better, you can add it with :after pseudo class and save both the extra div and the "X"

.deceased:after
{ 
    content:"X";
    position:absolute;
    left:0px;
    top:0px;
    width:100%;
    height:100%;
    font-size: 1000px;      // adjust this a little though it will be clipped by the div
    text-align: center;
    line-height: 100%;
    overflow: hidden;
}

Or :before .. will put it "underneath" the existing content

.deceased:before
{ 
    content:"X";
    position:absolute;
    left:0px;
    top:0px;
    width:100%;
    height:100%;
    font-size: 1000px;      // adjust this a little though it will be clipped by the div
    text-align: center;
    line-height: 100%;
    overflow: hidden;
}

UPDATE

I did find a way to use CSS only ...

@media all and (min-width: 50px)  {  .deceased:before  {   font-size:0.1em;  } }
@media all and (min-width: 100px) {  .deceased:before  {   font-size:0.2em;  } }
@media all and (min-width: 200px) {  .deceased:before  {   font-size:0.4em;  } }
@media all and (min-width: 300px) {  .deceased:before  {   font-size:0.6em;  } }
@media all and (min-width: 400px) {  .deceased:before  {   font-size:0.8em;  } }
and so on ....

UPDATE 2

And an inline svg containing a text will scale the text to the size of the div...

.deceased:before
{ 
    content: url('data:image/svg+xml;utf8,<svg>....</svg>');
    position:absolute;
    left:0px;
    top:0px;
    width:100%;
    height:100%;
    overflow: hidden;
}

Upvotes: 1

G-Cyrillus
G-Cyrillus

Reputation: 105863

you could use a class on your box element. Then, through that class, add your cross as a background or a pseudo-element over it , using background-size or width/height for pseudo-element and absolute positionning over it.

Anyhow, the use of a class will help you to make a specific style to that box, it could even be display:none or opacity:0.5; pointer-events:none; , or whatever you thinks is right and coherent with meaning and website design.

Upvotes: 0

Related Questions