An article about an in-progess web-extension called scrapping. It collect and archive elements of a webpage (e.g a searchbar) and store it on another web page to curate collections (e.g a collection of scrollbars). Like the practice of scrapbooking, it allows us to select, "cut" and "glue" elements we see on the web.
Members of OSP and Luuse gathered to develop a web-extension which resulted from several work sessions of Declarations.
Declarations is an ongoing artistic research into the poetic materiality of the CSS web-standard.
CSS is a coding language used to apply styling (colors, fonts, animations, layout...) to a website when coding it. During the last year, some researchers, artists, developers, designers, gathered and reflected about this web language.
First, what is a web-extension?
A web-extension is a small software one can download on a web browser to add features when browsing the web. For example a popular web-extension called "Add blocker" is used to block adds on websites and videos. It's helpful to customize one's web experience. They are tactical to have a personalized web experienced and reshape the web how we want to. We call them companion tools and it's possible to create your own!
What is the project?
We imagined a web-extension called scrapping which could be used to collect and archive elements of a webpage (e.g a searchbar) and store it on another web page to curate collections (e.g a collection of scrollbars). Like the practice of scrapbooking, it would allow us to select, "cut" and "glue" elements we see on the web.
Scrapping?
The track of research around this extension started with those questions:
How can we document CSS usages, like a bag to collect objects during a walk?
Can we cut CSS from websites like a scrapbook?
Can we collect and curate a library of designed elements where the styles (CSS) are the content (what we read)?
How can we study cultural uses of CSS, as well as the writting itself? What does it mean to collect web elements?
This led to an extension to collect and a public collection to curate indivual objects from all websites: buttons, searchbar, typography...
This extension could serve a professional purpose as well as more artistic one.
The extension is currently in development stage. At this point, a first version of the web-extension is already working but needs improvements.
Here is a short summary of the technicality of the web extension.
So far the browser extension is made to function only on the browser Firefox.
The extention is written in JavaScript.
The actions one can execute would be described as:
While on a page, think of an element to scrap.
Press SHIFT and all the elements (also called DIVS) of the page will now have a cyan border to be well distinguished.
With the mouse select the desired element to save.
A pop up window appears to confirm the selection.
Here add your name and confirm your selection.
Now change tab and visit the public collection website.
You'll find your collected scraps and the ones from others.
The extension consists mostly on two seperate things :
The browser extension you need to install on your own machine, to scrap elements.
The public collection web page that receives the scraps and gathers the collections.
The browser extension
As explained just before, the user will press SHIFT when desiring to select an element to scrap.
At this moment, all the elements of the page will appear with a cyan border.
After selecting the desired element, a pop-up window will appear.
The pop-up window will include:
date / time
user name (to fill when scrapping)
what was scrapped (img, div, button...)
the domain name of the website
a note field (to fill when scrapping)
a cancel button
a glue button (to confirm the scrap)
an error message that appears when the element is not scrappable "scissors not sharp enough :("
The public collection
The public collection is the website that will gather all the collected scraps, from everyone using the browser extention.
Regarding the collection's interface, we wondered how all the scraps should be displayed.
By default the scraps should be shown chronologically (most recent at the top, oldest at the bottom at the page). We would need a pagination system to avoid the webiste needing to load too heavy content (imagine having to load 1000 scraps on one page).
A filtering system would be a helpful tool to browse through the craps, they will be:
by tags : image, div, buttons, link...
by CSS property : "scraps with borders", "scraps with dropshadows", "scraps that are round" (border, dropshadow, border-radius)
by user : who did the scrapping
by domain name : getting all the scraps from one same domain for example all the scraps scrapped from Wikipedia
We thought of three modes of viewing the scraps in the grid:
3 different ways of visually translating the scraps:
Real mode (html+css rendering the scrap)
is the real living element: it's organic and responsive
therefor it has an ever changing instable materiality
may have lost some CSS styling when scrapped
shows the exact true scale and render of the scrap, meaning they will be archived in their "real" size
View mode (screenshot of the scrap)
is how your browser saw the scrap at one precise moment
it's an image, with pixels
if the scrap has adds or external JavaScript linked to it it will be visible on the image on the view mode but not in the real mode since the latter is scrapping only the HTML and CSS
all the screenshots of the scraps will be ordered and rescaled to fit in a grid
Reading mode (html+css in plain text)
Actual access to the code behind the scrap
The technical obstacles
Since we're scrapping bits of HTML and CSS, the materiality of each scrap and all the information they contain (the meta-data) seem vast and ambigious.
In order to apprach that, we decided to list everything we could gather around on element, and then see what would be the process of actually getting it.
Inspired by the book scrapping analogies we tried to think of each materiality as a different physical tool that would collect something.
pipette -> take all the CSS linked to a single element
syringe -> take all the CSS linked to an element and all of its children, with a succion mouvement it's sucking everything inside
spyglass -> take all the inherited CSS linked to a single element, since element inherit styles defined on their parent, we need to zoom in/out until we reach the farthest :root to make sure we inspected everything
note -> custom comment on that scrap
glue -> glues it in a database
The main action that the Javascript does is grabbing information from the scrap's website.
Accessing the CSS of one scrap
While gathering the URL, or the HTML (bookmark and scissors) can be straight forward, getting the CSS applied to a specific element is a lot order than it seems.
When you right click on a web page, you can "inspect" the current code of that page. It allows you to see the HTML structure and the CSS properties applied to each element of the page. At first glance, the inspector is very easy to use and is a very practical and fast tool. In a way getting the style applied to an element is a bit like re-coding our own inspector. Unfortunately for us, the inspector tool is actually a very complex one, so we need to reproduce its functionality but in an easier way. Reproducing the "inspector" made us understand the CSS ambiguous materiality.
Firstly we had to reflect on the different possibilities of accessing the CSS information of an element using JavaScript.
There are different JS ways to access the CSS of an element
The first one is through ´.style´.
Using the JS ´.style´ to get the inline style of an element, for example:
element.style.background = "red";
will result in
<p style="background:red;">hello</p>
Limitations: it actually works backwards : we can easily apply a style to an element but we can't actually get a style from an element.
The second one is ´.getComputedStyle()´.
We get all possible properties that exists of one element, but it doesn't specify which ones where and wheren't declared.
Also, it only gives the resolved value. The resolved value is the value calculated but it's frozen.
Think of it as a frozen version of your CSS, no visible intentions through what has been declared, no responsivity, it's like a screenshot but through a huge list of variables. for example if you said in CSS ´width: 50%;´, ´.getComputedStyle´ will give you the actual rendered width, wich depend of your own screen, and can be like 324px.
let compStyles = window.getComputedStyle(element);
compStyles.getPropertyValue("width");
Limitations: we don't get the "real living" value of an element, but instead its calculated final static result. It's not considering an element as a responsive element.
The third one is through the CSSStyleSheet JS API.
This native JS API has a different approach, it lists the declarations used on the page per stylesheet, more like the way they were initially declared.
It allow to list all stylesheets used in a document (let's say main.css, font.css, color-palettes.css, etc)
We can iterate on each one of those, and then iterate on every declarations block!
for (let sheet of document.styleSheets) {
for (let rule of sheet.cssRules) {
if (rule instanceof CSSStyleRule) {
console.log(rule.selectorText);
for (let propName of rule.style) {
let value = rule.style[propName];
console.log(propName, value);
}
}
}
}
Conclusion:
This last option is the more promising for what we wanted to achieve, but also the most intensive, as when scrapping an element, it would require to go through all the CSS stylesheets, and all the declarations block on every stylesheet, to see which ones we need to pick (because they're applied to the element we're scrapping) and which ones we don't.
CSS selectors are contextual
By grabbing one single element and its children, from a webpage and gluing it back to the collection, we remove it from its context. We remove it away from its parent.
This can create confusion in the declarations applied to that element.
Or simple if we wrote in CSS
main > blockquote {
border: 1px dotted chocolate;
}
If we scrap one of those blockquote to upload it to our collection, it is not inside of a main tag anymore, therefore that rule is not applied anymore...
Think of the same problem for selector last ´:nth-of-type(2)´, it's not the second element anymore while cutted from its context.
To deal with that we decided to come up with a system of assigning a new class to every selector, keeping their properties but each have a unique classcontaining thoses properties. They can now be decontextualised with no fear of losing properties.
Inherited styles
Sometimes elements have styles attributed by their parent element (their container, or lets say their surrounding) and they "inherit" that style automatically.
Certain properties are inherited, others are not.
This might sound weird because we don't think about it while writing CSS, we use it as an instinctive language.
But when we say ´div{ color: darkorange; }´ what we want is all the text inside of that div being written in dark orange, even childs of childs of childs, color is an inherited property.
When we say ´div{ maring: 10px; }´ what we mean is that that div specifically should have margin, we absolutely don't want every of it's children to have the same margins.
The spyglass would be an additionnal tool that zooms out of the pipette, and smartly grab inheritance pattern.
We need to work towards listing inherited properties.
Nested transparency
How to select a see-through element and select the color in its background as well?
The simpliest way we found to explain that obstacle is the following.
<body>
<p>you can see through me</p>
</body>
body {
background: red;
color: grey;
}
What we will see is clear: a grey paragraph inside of a red body.
But the subtlety is that the paragraph background is actually transparent, it's the default, only the body has a colored solid red background.
We see the red body through the paragraph as if it was another layer floating above.
The color is an inherited property though, meaning even though it is defined on the body, it will transfer to the paragraph.
So if we scrap that paragraph it will not look with red background once removed from its context and put inside of the collection.
Faking that red background by emulating is a very fragile solution, as you never know if a design can include 12 paragraphs absolutly positioned above each others with games of transparency.
But it can also be interesting to show that ambiguity once the material is collected instead of emulating visually something too complex.
We thought allowing the user to change the background color of the whole public collection could render some scrap visible and invisible from time to time. The intial background color of the element would anyways still be screenshoted and visible on the "view mode".
It's important to mention that all those faced difficulties make the scrap extension a bit slow and it can take up to 1 minute to scrap an element at this point.
The references
We looked at collected references, mostly different existing collection, on the web or elsewhere.
HotGlue.me a platform to craft your website without coding knowledge using the metaphor of glueing
Collection of websites made using CSS : a collaborative gallery that could show what CSS could accomplish https://www.csszengarden.com/pages/alldesigns
A publication called "My Edmonton Journal" that shows part of the actual newspaper announcing the death of Elvis Presley in 1977, but all textual information has been removed. It becomes a collection of containers, borders, drawing and images. Where has the text gone? Maybe in another collection container? :)
[insert here scans]
A publication called "POSTER N°524", a visual research on posters dissecting 523 posters picked in Amsterdam. They are analysed through the lense of their content : image, typography, colors and compositions.
[insert here the POSTER N524 reference scans]
Current reflexions
When using the extension, should the cursor become scissors?
How should the scrap behave when being scraped? Should its surroundings behave a certain way too?
Should we keep the wording scrapping?
Could we create a generative prompt on the collection website to induce a collection direction :
Scrap every [generated HTML element] with [generated CSS property]
Scrap every [generated HTML element] with [generated adjective]
Could we make a tab in the collection webiste to make compositions with the scraps and allow overlaying and manual placement, and add mousewritten notes?
Have the possibility to currate personal collection?
Could those collections be "contaminated" by the CSS style from the last added scraps?
Building this extension led us to discover more about the materiality of CSS and its ambiguity, and wonder about collections, web archeology and its cultural meaning. Like mentioned at the top of this article, the scrap extension is still in development mode, but it's already mostly working. It needs improvements but we are working towards a proper version to share.